Apply cmake-format

This commit is contained in:
Martchus 2019-02-06 17:30:52 +01:00
parent 42dd86a16e
commit 86f3bf8b3b
12 changed files with 1409 additions and 1399 deletions

View File

@ -36,8 +36,7 @@ set(HEADER_FILES
misc/levenshtein.h
tests/testutils.h
tests/cppunit.h
tests/outputcheck.h
)
tests/outputcheck.h)
set(SRC_FILES
application/argumentparserprivate.h
application/argumentparser.cpp
@ -61,12 +60,9 @@ set(SRC_FILES
math/math.cpp
misc/random.cpp
misc/levenshtein.cpp
tests/testutils.cpp
)
tests/testutils.cpp)
set(TEST_HEADER_FILES
)
set(TEST_HEADER_FILES)
set(TEST_SRC_FILES
tests/cppunit.cpp
tests/conversiontests.cpp
@ -75,8 +71,7 @@ set(TEST_SRC_FILES
tests/argumentparsertests.cpp
tests/traitstests.cpp
tests/mathtests.cpp
tests/misctests.cpp
)
tests/misctests.cpp)
set(CMAKE_MODULE_FILES
cmake/modules/BasicConfig.cmake
@ -89,8 +84,7 @@ set(CMAKE_MODULE_FILES
cmake/modules/Doxygen.cmake
cmake/modules/ListToString.cmake
cmake/modules/ShellCompletion.cmake
cmake/modules/3rdParty.cmake
)
cmake/modules/3rdParty.cmake)
set(CMAKE_TEMPLATE_FILES
cmake/templates/bash-completion.sh.in
cmake/templates/Config.cmake.in
@ -101,28 +95,15 @@ set(CMAKE_TEMPLATE_FILES
cmake/templates/appdata.xml.in
cmake/templates/doxygen.in
cmake/templates/global.h.in
cmake/templates/template.pc.in
)
set(SCRIPT_FILES
)
if(MINGW)
list(APPEND CMAKE_TEMPLATE_FILES
cmake/templates/windows.rc.in
)
list(APPEND SCRIPT_FILES
scripts/wine.sh
)
endif()
cmake/templates/template.pc.in)
set(SCRIPT_FILES)
if (MINGW)
list(APPEND CMAKE_TEMPLATE_FILES cmake/templates/windows.rc.in)
list(APPEND SCRIPT_FILES scripts/wine.sh)
endif ()
set(DOC_FILES
README.md
doc/buildvariables.md
doc/testapplication.md
)
set(EXTRA_FILES
tests/calculateoverallcoverage.awk
coding-style.clang-format
)
set(DOC_FILES README.md doc/buildvariables.md doc/testapplication.md)
set(EXTRA_FILES tests/calculateoverallcoverage.awk coding-style.clang-format)
# required to include CMake modules from own project directory
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" "${CMAKE_MODULE_PATH}")
@ -146,62 +127,57 @@ use_iconv(AUTO_LINKAGE REQUIRED)
# configure use of native file buffer and its backend implementation if enabled
option(USE_NATIVE_FILE_BUFFER "enables use of native file buffer, affects ABI" OFF)
option(FORCE_BOOST_IOSTREAMS_FOR_NATIVE_FILE_BUFFER "forces use of Boost.Iostreams for native file buffer" OFF)
if(USE_NATIVE_FILE_BUFFER)
if (USE_NATIVE_FILE_BUFFER)
list(APPEND META_PUBLIC_COMPILE_DEFINITIONS ${META_PROJECT_VARNAME}_USE_NATIVE_FILE_BUFFER)
# check whether __gnu_cxx::stdio_filebuf is available
try_compile(GNU_CXX_STDIO_FILEBUF_AVAILABLE ${CMAKE_CURRENT_BINARY_DIR}
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/feature_detection/stdio_filebuf.cpp
OUTPUT_VARIABLE GNU_CXX_STDIO_FILEBUF_CHECK_LOG
)
try_compile(GNU_CXX_STDIO_FILEBUF_AVAILABLE
${CMAKE_CURRENT_BINARY_DIR}
SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/feature_detection/stdio_filebuf.cpp
OUTPUT_VARIABLE GNU_CXX_STDIO_FILEBUF_CHECK_LOG)
# use __gnu_cxx::stdio_filebuf if available or fallback to boost::iostreams::stream_buffer
if(GNU_CXX_STDIO_FILEBUF_AVAILABLE AND NOT FORCE_BOOST_IOSTREAMS_FOR_NATIVE_FILE_BUFFER)
if (GNU_CXX_STDIO_FILEBUF_AVAILABLE AND NOT FORCE_BOOST_IOSTREAMS_FOR_NATIVE_FILE_BUFFER)
message(STATUS "Using __gnu_cxx::stdio_filebuf for NativeFileStream")
set_property(
SOURCE io/nativefilestream.cpp
APPEND PROPERTY COMPILE_DEFINITIONS ${META_PROJECT_VARNAME}_USE_GNU_CXX_STDIO_FILEBUF
)
else()
set_property(SOURCE io/nativefilestream.cpp
APPEND
PROPERTY COMPILE_DEFINITIONS ${META_PROJECT_VARNAME}_USE_GNU_CXX_STDIO_FILEBUF)
else ()
message(STATUS "Using boost::iostreams::stream_buffer<boost::iostreams::file_descriptor_sink> for NativeFileStream")
set(boost_iostreams_DYNAMIC_COMPILE_DEFINITIONS BOOST_IOSTREAMS_DYN_LINK)
use_external_library(boost_iostreams AUTO_LINKAGE REQUIRED)
set_property(
SOURCE io/nativefilestream.cpp
APPEND PROPERTY COMPILE_DEFINITIONS ${META_PROJECT_VARNAME}_USE_BOOST_IOSTREAMS
)
endif()
else()
set_property(SOURCE io/nativefilestream.cpp
APPEND
PROPERTY COMPILE_DEFINITIONS ${META_PROJECT_VARNAME}_USE_BOOST_IOSTREAMS)
endif ()
else ()
message(STATUS "Using std::fstream for NativeFileStream")
endif()
endif ()
# configure forcing UTF-8 code page under Windows
option(FORCE_UTF8_CODEPAGE "forces use of UTF-8 code page under Windows via ApplicationUtilities::startConsole()" OFF)
if(FORCE_UTF8_CODEPAGE)
if (FORCE_UTF8_CODEPAGE)
list(APPEND META_PRIVATE_COMPILE_DEFINITIONS ${META_PROJECT_VARNAME}_FORCE_UTF8_CODEPAGE)
endif()
endif ()
# configure whether escape codes should be enabled by default
option(ENABLE_ESCAPE_CODES_BY_DEAULT "enables usage of escape codes by default" ON)
if(ENABLE_ESCAPE_CODES_BY_DEAULT)
set_property(
SOURCE application/argumentparser.cpp
io/ansiescapecodes.cpp
tests/argumentparsertests.cpp
APPEND PROPERTY COMPILE_DEFINITIONS ${META_PROJECT_VARNAME}_ESCAPE_CODES_ENABLED_BY_DEFAULT
)
else()
if (ENABLE_ESCAPE_CODES_BY_DEAULT)
set_property(SOURCE application/argumentparser.cpp io/ansiescapecodes.cpp tests/argumentparsertests.cpp
APPEND
PROPERTY COMPILE_DEFINITIONS ${META_PROJECT_VARNAME}_ESCAPE_CODES_ENABLED_BY_DEFAULT)
else ()
message(STATUS "Disabling use of escape codes by default.")
endif()
endif ()
# configure use of thread_local
option(ENABLE_THREAD_LOCAL "enables use of Thread-Local Storage" ON)
if(NOT ENABLE_THREAD_LOCAL)
set_property(
SOURCE conversion/stringconversion.cpp
APPEND PROPERTY COMPILE_DEFINITIONS ${META_PROJECT_VARNAME}_NO_THREAD_LOCAL
)
endif()
if (NOT ENABLE_THREAD_LOCAL)
set_property(SOURCE conversion/stringconversion.cpp
APPEND
PROPERTY COMPILE_DEFINITIONS ${META_PROJECT_VARNAME}_NO_THREAD_LOCAL)
endif ()
# include modules to apply configuration
include(BasicConfig)

View File

@ -1,195 +1,258 @@
cmake_minimum_required(VERSION 3.3.0 FATAL_ERROR)
# prevent multiple inclusion
if(DEFINED THIRD_PARTY_MODULE_LOADED)
if (DEFINED THIRD_PARTY_MODULE_LOADED)
return()
endif()
endif ()
set(THIRD_PARTY_MODULE_LOADED YES)
macro(save_default_library_suffixes)
macro (save_default_library_suffixes)
set(DEFAULT_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
endmacro()
endmacro ()
macro(restore_default_library_suffixes)
macro (restore_default_library_suffixes)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${DEFAULT_CMAKE_FIND_LIBRARY_SUFFIXES})
unset(DEFAULT_CMAKE_FIND_LIBRARY_SUFFIXES)
endmacro()
endmacro ()
macro(configure_static_library_suffixes)
macro (configure_static_library_suffixes)
# allows to look for static libraries in particular
if(WIN32)
if (WIN32)
set(CMAKE_FIND_LIBRARY_SUFFIXES .a .lib)
else()
else ()
set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
endif()
endmacro()
endif ()
endmacro ()
macro(configure_dynamic_library_suffixes)
macro (configure_dynamic_library_suffixes)
# allows to look for dynamic libraries in particular
if(WIN32)
if (WIN32)
set(CMAKE_FIND_LIBRARY_SUFFIXES .dll .dll.a)
elseif(APPLE)
elseif (APPLE)
set(CMAKE_FIND_LIBRARY_SUFFIXES .dylib .so)
else()
else ()
set(CMAKE_FIND_LIBRARY_SUFFIXES .so)
endif()
endmacro()
endif ()
endmacro ()
macro(link_against_library_varnames NAME LINKAGE REQUIRED PRIVATE_LIBRARIES_VARNAME PUBLIC_LIBRARIES_VARNAME PRIVATE_STATIC_LIBRARIES_VARNAME PUBLIC_STATIC_LIBRARIES_VARNAME)
# determine whether the library is required or optional
# FIXME: improve passing required argument
if("${REQUIRED}" STREQUAL "OPTIONAL")
macro (link_against_library_varnames
NAME
LINKAGE
REQUIRED
PRIVATE_LIBRARIES_VARNAME
PUBLIC_LIBRARIES_VARNAME
PRIVATE_STATIC_LIBRARIES_VARNAME
PUBLIC_STATIC_LIBRARIES_VARNAME)
# determine whether the library is required or optional FIXME: improve passing required argument
if ("${REQUIRED}" STREQUAL "OPTIONAL")
set(${NAME}_REQUIRED "NO")
elseif("${REQUIRED}" STREQUAL "REQUIRED")
elseif ("${REQUIRED}" STREQUAL "REQUIRED")
set(${NAME}_REQUIRED "REQUIRED")
else()
else ()
message(FATAL_ERROR "Invalid use of link_against_library; must specify either REQUIRED or OPTIONAL.")
endif()
endif ()
# add library to list of libraries to link against when building dynamic libraries or applications
# - prefer dynamic lib if linkage not explicitely specified
if(${NAME}_STATIC_LIB AND (("${LINKAGE}" STREQUAL "AUTO_LINKAGE" AND ((NOT (${NAME}_DYNAMIC_LIB OR ${NAME}_SHARED_LIB)) OR (STATIC_LINKAGE AND "${META_PROJECT_TYPE}" STREQUAL "application") OR (STATIC_LIBRARY_LINKAGE AND ("${META_PROJECT_TYPE}" STREQUAL "" OR "${META_PROJECT_TYPE}" STREQUAL "library")))) OR ("${LINKAGE}" STREQUAL "STATIC")))
# add library to list of libraries to link against when building dynamic libraries or applications - prefer dynamic lib
# if linkage not explicitely specified
if (${NAME}_STATIC_LIB
AND (("${LINKAGE}" STREQUAL "AUTO_LINKAGE"
AND ((NOT (${NAME}_DYNAMIC_LIB OR ${NAME}_SHARED_LIB))
OR (STATIC_LINKAGE AND "${META_PROJECT_TYPE}" STREQUAL "application")
OR (STATIC_LIBRARY_LINKAGE
AND ("${META_PROJECT_TYPE}" STREQUAL "" OR "${META_PROJECT_TYPE}" STREQUAL "library"))))
OR ("${LINKAGE}" STREQUAL "STATIC")))
set(USE_${NAME} ON)
set(USE_STATIC_${NAME} ON)
list(APPEND LIBRARIES ${${NAME}_STATIC_LIB})
message(STATUS "Linking ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} statically against external library ${NAME} (${${NAME}_STATIC_LIB}).")
if(${NAME}_STATIC_INCLUDE_DIR)
message(
STATUS
"Linking ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} statically against external library ${NAME} (${${NAME}_STATIC_LIB})."
)
if (${NAME}_STATIC_INCLUDE_DIR)
list(APPEND ADDITIONAL_STATIC_INCLUDE_DIRS ${${NAME}_STATIC_INCLUDE_DIR})
message(STATUS "Adding include path for ${NAME} to ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}: ${${NAME}_STATIC_INCLUDE_DIR}")
endif()
if(${NAME}_STATIC_COMPILE_DEFINITIONS)
message(
STATUS
"Adding include path for ${NAME} to ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}: ${${NAME}_STATIC_INCLUDE_DIR}"
)
endif ()
if (${NAME}_STATIC_COMPILE_DEFINITIONS)
list(APPEND META_PRIVATE_STATIC_LIB_COMPILE_DEFINITIONS ${${NAME}_STATIC_COMPILE_DEFINITIONS})
endif()
endif ()
if(${${NAME}_STATIC_LIB} IN_LIST META_PUBLIC_STATIC_LIB_DEPENDS OR ${NAME} IN_LIST META_PUBLIC_STATIC_LIB_DEPENDS)
if (${${NAME}_STATIC_LIB} IN_LIST META_PUBLIC_STATIC_LIB_DEPENDS OR ${NAME} IN_LIST META_PUBLIC_STATIC_LIB_DEPENDS)
list(APPEND ${PUBLIC_LIBRARIES_VARNAME} ${${NAME}_STATIC_LIB})
if(${NAME}_STATIC_INCLUDE_DIR)
if (${NAME}_STATIC_INCLUDE_DIR)
list(APPEND PUBLIC_SHARED_INCLUDE_DIRS ${${NAME}_STATIC_INCLUDE_DIR})
endif()
else()
endif ()
else ()
list(APPEND ${PRIVATE_LIBRARIES_VARNAME} ${${NAME}_STATIC_LIB})
if(${NAME}_STATIC_INCLUDE_DIR)
if (${NAME}_STATIC_INCLUDE_DIR)
list(APPEND PRIVATE_SHARED_INCLUDE_DIRS ${${NAME}_STATIC_INCLUDE_DIR})
endif()
endif()
endif ()
endif ()
# add Qt resources of static library to be enabled
if(${NAME}_QT_RESOURCES)
if (${NAME}_QT_RESOURCES)
message(STATUS "Adding ${${NAME}_QT_RESOURCES} to LIBRARIES_QT_RESOURCES for ${META_PROJECT_NAME}.")
list(APPEND LIBRARIES_QT_RESOURCES ${${NAME}_QT_RESOURCES})
endif()
endif ()
elseif((${NAME}_DYNAMIC_LIB OR ${NAME}_SHARED_LIB) AND (("${LINKAGE}" STREQUAL "AUTO_LINKAGE") OR ("${LINKAGE}" STREQUAL "SHARED")))
elseif ((${NAME}_DYNAMIC_LIB OR ${NAME}_SHARED_LIB)
AND (("${LINKAGE}" STREQUAL "AUTO_LINKAGE") OR ("${LINKAGE}" STREQUAL "SHARED")))
set(USE_${NAME} ON)
set(USE_SHARED_${NAME} ON)
if(NOT ${NAME}_DYNAMIC_LIB)
if (NOT ${NAME}_DYNAMIC_LIB)
set(${NAME}_DYNAMIC_LIB ${${NAME}_SHARED_LIB})
endif()
endif ()
list(APPEND LIBRARIES ${${NAME}_DYNAMIC_LIB})
message(STATUS "Linking ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} dynamically against external library ${NAME} (${${NAME}_DYNAMIC_LIB}).")
if(${NAME}_DYNAMIC_INCLUDE_DIR)
message(
STATUS
"Linking ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} dynamically against external library ${NAME} (${${NAME}_DYNAMIC_LIB})."
)
if (${NAME}_DYNAMIC_INCLUDE_DIR)
list(APPEND ADDITIONAL_SHARED_INCLUDE_DIRS ${${NAME}_DYNAMIC_INCLUDE_DIR})
message(STATUS "Adding include path for ${NAME} to ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}: ${${NAME}_DYNAMIC_INCLUDE_DIR}")
endif()
if(${NAME}_DYNAMIC_COMPILE_DEFINITIONS)
message(
STATUS
"Adding include path for ${NAME} to ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}: ${${NAME}_DYNAMIC_INCLUDE_DIR}"
)
endif ()
if (${NAME}_DYNAMIC_COMPILE_DEFINITIONS)
list(APPEND META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS ${${NAME}_DYNAMIC_COMPILE_DEFINITIONS})
endif()
endif ()
if(${${NAME}_DYNAMIC_LIB} IN_LIST META_PUBLIC_SHARED_LIB_DEPENDS OR ${NAME} IN_LIST META_PUBLIC_SHARED_LIB_DEPENDS)
if (${${NAME}_DYNAMIC_LIB} IN_LIST META_PUBLIC_SHARED_LIB_DEPENDS OR ${NAME} IN_LIST META_PUBLIC_SHARED_LIB_DEPENDS)
list(APPEND ${PUBLIC_LIBRARIES_VARNAME} ${${NAME}_DYNAMIC_LIB})
if(${NAME}_DYNAMIC_INCLUDE_DIR)
if (${NAME}_DYNAMIC_INCLUDE_DIR)
list(APPEND PUBLIC_SHARED_INCLUDE_DIRS ${${NAME}_DYNAMIC_INCLUDE_DIR})
endif()
else()
endif ()
else ()
list(APPEND ${PRIVATE_LIBRARIES_VARNAME} ${${NAME}_DYNAMIC_LIB})
if(${NAME}_DYNAMIC_INCLUDE_DIR)
if (${NAME}_DYNAMIC_INCLUDE_DIR)
list(APPEND PRIVATE_SHARED_INCLUDE_DIRS ${${NAME}_DYNAMIC_INCLUDE_DIR})
endif()
endif()
else()
if(${NAME}_REQUIRED)
message(FATAL_ERROR "External library ${NAME} required by ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} is not available for the specified linkage ${LINKAGE}.")
else()
message(WARNING "External library ${NAME} required by ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} is not available for the specified linkage ${LINKAGE}.")
endif()
endif()
endif ()
endif ()
else ()
if (${NAME}_REQUIRED)
message(
FATAL_ERROR
"External library ${NAME} required by ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} is not available for the specified linkage ${LINKAGE}."
)
else ()
message(
WARNING
"External library ${NAME} required by ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} is not available for the specified linkage ${LINKAGE}."
)
endif ()
endif ()
# add library to list of libraries to be provided as transitive dependencies when building static libraries
# - prefer static lib if linkage not explicitely specified
if(${NAME}_STATIC_LIB AND ("${LINKAGE}" STREQUAL "AUTO_LINKAGE") OR ("${LINKAGE}" STREQUAL "STATIC"))
# add library to list of libraries to be provided as transitive dependencies when building static libraries - prefer
# static lib if linkage not explicitely specified
if (${NAME}_STATIC_LIB AND ("${LINKAGE}" STREQUAL "AUTO_LINKAGE") OR ("${LINKAGE}" STREQUAL "STATIC"))
set(USE_${NAME} ON)
set(USE_STATIC_${NAME} ON)
list(APPEND STATIC_LIBRARIES ${${NAME}_STATIC_LIB})
message(STATUS "Adding static external library ${NAME} (${${NAME}_STATIC_LIB}) to dependencies of ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}.")
if(${NAME}_STATIC_INCLUDE_DIR)
message(
STATUS
"Adding static external library ${NAME} (${${NAME}_STATIC_LIB}) to dependencies of ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}."
)
if (${NAME}_STATIC_INCLUDE_DIR)
list(APPEND ADDITIONAL_STATIC_INCLUDE_DIRS ${${NAME}_STATIC_INCLUDE_DIR})
message(STATUS "Adding include path for ${NAME} to static ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}: ${${NAME}_STATIC_INCLUDE_DIR}")
endif()
message(
STATUS
"Adding include path for ${NAME} to static ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}: ${${NAME}_STATIC_INCLUDE_DIR}"
)
endif ()
if(${${NAME}_STATIC_LIB} IN_LIST META_PUBLIC_STATIC_LIB_DEPENDS OR ${NAME} IN_LIST META_PUBLIC_STATIC_LIB_DEPENDS)
if (${${NAME}_STATIC_LIB} IN_LIST META_PUBLIC_STATIC_LIB_DEPENDS OR ${NAME} IN_LIST META_PUBLIC_STATIC_LIB_DEPENDS)
list(APPEND ${PUBLIC_STATIC_LIBRARIES_VARNAME} ${${NAME}_STATIC_LIB})
if(${NAME}_STATIC_INCLUDE_DIR)
if (${NAME}_STATIC_INCLUDE_DIR)
list(APPEND PUBLIC_STATIC_INCLUDE_DIRS ${${NAME}_STATIC_INCLUDE_DIR})
endif()
else()
endif ()
else ()
list(APPEND ${PRIVATE_STATIC_LIBRARIES_VARNAME} ${${NAME}_STATIC_LIB})
if(${NAME}_STATIC_INCLUDE_DIR)
if (${NAME}_STATIC_INCLUDE_DIR)
list(APPEND PRIVATE_STATIC_INCLUDE_DIRS ${${NAME}_STATIC_INCLUDE_DIR})
endif()
endif()
endif ()
endif ()
# add Qt resources of static library for exporting it
if(${NAME}_QT_RESOURCES)
if (${NAME}_QT_RESOURCES)
message(STATUS "Adding ${${NAME}_QT_RESOURCES} to STATIC_LIBRARIES_QT_RESOURCES for ${META_PROJECT_NAME}.")
list(APPEND STATIC_LIBRARIES_QT_RESOURCES ${${NAME}_QT_RESOURCES})
endif()
endif ()
elseif((${NAME}_DYNAMIC_LIB OR ${NAME}_SHARED_LIB) AND (("${LINKAGE}" STREQUAL "AUTO_LINKAGE" AND (NOT ${NAME}_STATIC_LIB OR (NOT STATIC_LINKAGE AND "${META_PROJECT_TYPE}" STREQUAL "application") OR (NOT STATIC_LIBRARY_LINKAGE AND ("${META_PROJECT_TYPE}" STREQUAL "" OR "${META_PROJECT_TYPE}" STREQUAL "library")))) OR ("${LINKAGE}" STREQUAL "SHARED")))
elseif ((${NAME}_DYNAMIC_LIB OR ${NAME}_SHARED_LIB)
AND (("${LINKAGE}" STREQUAL "AUTO_LINKAGE"
AND (NOT ${NAME}_STATIC_LIB
OR (NOT STATIC_LINKAGE AND "${META_PROJECT_TYPE}" STREQUAL "application")
OR (NOT STATIC_LIBRARY_LINKAGE
AND ("${META_PROJECT_TYPE}" STREQUAL "" OR "${META_PROJECT_TYPE}" STREQUAL "library"))))
OR ("${LINKAGE}" STREQUAL "SHARED")))
set(USE_${NAME} ON)
set(USE_SHARED_${NAME} ON)
if(NOT ${NAME}_DYNAMIC_LIB)
if (NOT ${NAME}_DYNAMIC_LIB)
set(${NAME}_DYNAMIC_LIB ${${NAME}_SHARED_LIB})
endif()
endif ()
list(APPEND STATIC_LIBRARIES ${${NAME}_DYNAMIC_LIB})
message(STATUS "Adding dynamic external library ${NAME} (${${NAME}_DYNAMIC_LIB}) to dependencies of static ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}.")
if(${NAME}_DYNAMIC_INCLUDE_DIR)
message(
STATUS
"Adding dynamic external library ${NAME} (${${NAME}_DYNAMIC_LIB}) to dependencies of static ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}."
)
if (${NAME}_DYNAMIC_INCLUDE_DIR)
list(APPEND ADDITIONAL_SHARED_INCLUDE_DIRS ${${NAME}_DYNAMIC_INCLUDE_DIR})
message(STATUS "Adding include path for ${NAME} to static ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}: ${${NAME}_DYNAMIC_INCLUDE_DIR}")
endif()
message(
STATUS
"Adding include path for ${NAME} to static ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}: ${${NAME}_DYNAMIC_INCLUDE_DIR}"
)
endif ()
if(${${NAME}_DYNAMIC_LIB} IN_LIST META_PUBLIC_SHARED_LIB_DEPENDS OR ${NAME} IN_LIST META_PUBLIC_SHARED_LIB_DEPENDS)
if (${${NAME}_DYNAMIC_LIB} IN_LIST META_PUBLIC_SHARED_LIB_DEPENDS OR ${NAME} IN_LIST META_PUBLIC_SHARED_LIB_DEPENDS)
list(APPEND ${PUBLIC_STATIC_LIBRARIES_VARNAME} ${${NAME}_DYNAMIC_LIB})
if(${NAME}_DYNAMIC_INCLUDE_DIR)
if (${NAME}_DYNAMIC_INCLUDE_DIR)
list(APPEND PUBLIC_STATIC_INCLUDE_DIRS ${${NAME}_DYNAMIC_INCLUDE_DIR})
endif()
else()
endif ()
else ()
list(APPEND ${PRIVATE_STATIC_LIBRARIES_VARNAME} ${${NAME}_DYNAMIC_LIB})
if(${NAME}_DYNAMIC_INCLUDE_DIR)
if (${NAME}_DYNAMIC_INCLUDE_DIR)
list(APPEND PRIVATE_STATIC_INCLUDE_DIRS ${${NAME}_DYNAMIC_INCLUDE_DIR})
endif()
endif()
else()
if(${NAME}_REQUIRED)
message(FATAL_ERROR "External library ${NAME} required by ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} is not available for the specified linkage ${LINKAGE}.")
else()
message(WARNING "External library ${NAME} required by ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} is not available for the specified linkage ${LINKAGE}.")
endif()
endif()
endmacro()
endif ()
endif ()
else ()
if (${NAME}_REQUIRED)
message(
FATAL_ERROR
"External library ${NAME} required by ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} is not available for the specified linkage ${LINKAGE}."
)
else ()
message(
WARNING
"External library ${NAME} required by ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} is not available for the specified linkage ${LINKAGE}."
)
endif ()
endif ()
endmacro ()
macro(link_against_library NAME LINKAGE REQUIRED)
link_against_library_varnames("${NAME}" "${LINKAGE}" "${REQUIRED}"
PRIVATE_LIBRARIES PUBLIC_LIBRARIES PRIVATE_STATIC_LIBRARIES PUBLIC_STATIC_LIBRARIES
)
endmacro()
macro (link_against_library NAME LINKAGE REQUIRED)
link_against_library_varnames("${NAME}"
"${LINKAGE}"
"${REQUIRED}"
PRIVATE_LIBRARIES
PUBLIC_LIBRARIES
PRIVATE_STATIC_LIBRARIES
PUBLIC_STATIC_LIBRARIES)
endmacro ()
macro(link_tests_against_library NAME LINKAGE REQUIRED)
link_against_library_varnames("${NAME}" "${LINKAGE}" "${REQUIRED}"
TEST_LIBRARIES TEST_LIBRARIES STATIC_TEST_LIBRARIES STATIC_TEST_LIBRARIES
)
endmacro()
macro (link_tests_against_library NAME LINKAGE REQUIRED)
link_against_library_varnames("${NAME}"
"${LINKAGE}"
"${REQUIRED}"
TEST_LIBRARIES
TEST_LIBRARIES
STATIC_TEST_LIBRARIES
STATIC_TEST_LIBRARIES)
endmacro ()
macro(find_external_library NAME LINKAGE REQUIRED)
macro (find_external_library NAME LINKAGE REQUIRED)
set(${NAME}_DYNAMIC_INCLUDE_DIR NOTFOUND CACHE PATH "${NAME} include dir (dynamic)")
set(${NAME}_DYNAMIC_LIB NOTFOUND CACHE FILEPATH "${NAME} lib (dynamic)")
set(${NAME}_STATIC_INCLUDE_DIR NOTFOUND CACHE PATH "${NAME} include dir (static)")
@ -197,83 +260,97 @@ macro(find_external_library NAME LINKAGE REQUIRED)
save_default_library_suffixes()
if(NOT ${NAME}_DYNAMIC_LIB)
if (NOT ${NAME}_DYNAMIC_LIB)
configure_dynamic_library_suffixes()
find_library(DETECTED_${NAME}_DYNAMIC_LIB ${NAME})
set(${NAME}_DYNAMIC_LIB ${DETECTED_${NAME}_DYNAMIC_LIB} CACHE FILEPATH "${NAME} lib (dynamic)" FORCE)
endif()
endif ()
if(NOT ${NAME}_STATIC_LIB)
if (NOT ${NAME}_STATIC_LIB)
configure_static_library_suffixes()
find_library(DETECTED_${NAME}_STATIC_LIB ${NAME})
set(${NAME}_STATIC_LIB ${DETECTED_${NAME}_STATIC_LIB} CACHE FILEPATH "${NAME} lib (static)" FORCE)
endif()
endif ()
restore_default_library_suffixes()
endmacro()
endmacro ()
macro(use_external_library NAME LINKAGE REQUIRED)
macro (use_external_library NAME LINKAGE REQUIRED)
find_external_library("${NAME}" "${LINKAGE}" "${REQUIRED}")
link_against_library("${NAME}" "${LINKAGE}" "${REQUIRED}")
endmacro()
endmacro ()
function(use_external_library_from_package_dynamic NAME PKGNAME INCLUDE_VAR LIBRARY_VAR COMPAT_VERSION)
function (use_external_library_from_package_dynamic NAME PKGNAME INCLUDE_VAR LIBRARY_VAR COMPAT_VERSION)
# internally used by find_external_library_from_package to find dynamic libraries
configure_dynamic_library_suffixes()
find_package(${PKGNAME} ${COMPAT_VERSION})
set(${NAME}_DYNAMIC_INCLUDE_DIR ${${INCLUDE_VAR}} CACHE PATH "${NAME} include dir (dynamic)" FORCE)
set(${NAME}_DYNAMIC_LIB ${${LIBRARY_VAR}} CACHE FILEPATH "${NAME} lib (dynamic)" FORCE)
endfunction()
endfunction ()
function(use_external_library_from_package_static NAME PKGNAME INCLUDE_VAR LIBRARY_VAR COMPAT_VERSION)
function (use_external_library_from_package_static NAME PKGNAME INCLUDE_VAR LIBRARY_VAR COMPAT_VERSION)
# internally used by find_external_library_from_package to find static libraries
configure_static_library_suffixes()
find_package(${PKGNAME} ${COMPAT_VERSION})
set(${NAME}_STATIC_INCLUDE_DIR ${${INCLUDE_VAR}} CACHE PATH "${NAME} include dir (static)" FORCE)
set(${NAME}_STATIC_LIB ${${LIBRARY_VAR}} CACHE FILEPATH "${NAME} lib (static)" FORCE)
endfunction()
endfunction ()
macro(find_external_library_from_package NAME PKGNAME VERSION INCLUDE_VAR LIBRARY_VAR LINKAGE REQUIRED)
macro (find_external_library_from_package NAME PKGNAME VERSION INCLUDE_VAR LIBRARY_VAR LINKAGE REQUIRED)
# handle specified VERSION
if("${VERSION}" STREQUAL "ANY_VERSION")
if ("${VERSION}" STREQUAL "ANY_VERSION")
set(${NAME}_COMPATIBLE_VERSION "")
else()
else ()
set(${NAME}_COMPATIBLE_VERSION ${VERSION})
endif()
endif ()
# use the find_library approach first because it is less buggy when trying to detect static libraries
# caveat: this way include dirs are not detected - however those are mostly the default anyways and
# can also be set manually by the user in case the auto-detection is not sufficient
# use the find_library approach first because it is less buggy when trying to detect static libraries caveat: this way
# include dirs are not detected - however those are mostly the default anyways and can also be set manually by the user
# in case the auto-detection is not sufficient
find_external_library("${NAME}" "${LINKAGE}" OPTIONAL)
# fall back to actual use of find_package
# use separate functions to get a new scope
# fall back to actual use of find_package use separate functions to get a new scope
save_default_library_suffixes()
if(NOT ${NAME}_DYNAMIC_LIB)
use_external_library_from_package_dynamic(${NAME} ${PKGNAME} ${INCLUDE_VAR} "${LIBRARY_VAR}" "${${NAME}_COMPATIBLE_VERSION}")
endif()
if(NOT ${NAME}_STATIC_LIB)
use_external_library_from_package_static(${NAME} ${PKGNAME} ${INCLUDE_VAR} "${LIBRARY_VAR}" "${${NAME}_COMPATIBLE_VERSION}")
endif()
if (NOT ${NAME}_DYNAMIC_LIB)
use_external_library_from_package_dynamic(${NAME}
${PKGNAME}
${INCLUDE_VAR}
"${LIBRARY_VAR}"
"${${NAME}_COMPATIBLE_VERSION}")
endif ()
if (NOT ${NAME}_STATIC_LIB)
use_external_library_from_package_static(${NAME}
${PKGNAME}
${INCLUDE_VAR}
"${LIBRARY_VAR}"
"${${NAME}_COMPATIBLE_VERSION}")
endif ()
restore_default_library_suffixes()
endmacro()
endmacro ()
macro(use_external_library_from_package NAME PKGNAME VERSION INCLUDE_VAR LIBRARY_VAR LINKAGE REQUIRED)
find_external_library_from_package("${NAME}" "${PKGNAME}" "${VERSION}" "${INCLUDE_VAR}" "${LIBRARY_VAR}" "${LINKAGE}" "${REQUIRED}")
macro (use_external_library_from_package NAME PKGNAME VERSION INCLUDE_VAR LIBRARY_VAR LINKAGE REQUIRED)
find_external_library_from_package("${NAME}"
"${PKGNAME}"
"${VERSION}"
"${INCLUDE_VAR}"
"${LIBRARY_VAR}"
"${LINKAGE}"
"${REQUIRED}")
link_against_library("${NAME}" "${LINKAGE}" "${REQUIRED}")
endmacro()
endmacro ()
macro(use_iconv LINKAGE REQUIRED)
set(FORCE_EXTERNAL_ICONV OFF CACHE PATH "whether to force usage of external iconv (rather than the using the one bundled with glibc)")
if(NOT FORCE_EXTERNAL_ICONV)
macro (use_iconv LINKAGE REQUIRED)
set(FORCE_EXTERNAL_ICONV OFF
CACHE PATH "whether to force usage of external iconv (rather than the using the one bundled with glibc)")
if (NOT FORCE_EXTERNAL_ICONV)
# check whether iconv exists in standard lib
include(CheckFunctionExists)
check_function_exists(iconv HAS_ICONV)
endif()
if(NOT FORCE_EXTERNAL_ICONV AND HAS_ICONV)
endif ()
if (NOT FORCE_EXTERNAL_ICONV AND HAS_ICONV)
message(STATUS "Using iconv from the standard library for ${META_PROJECT_NAME}.")
else()
else ()
# find external iconv library
use_external_library(iconv ${LINKAGE} ${REQUIRED})
endif()
endmacro()
endif ()
endmacro ()

View File

@ -1,282 +1,264 @@
if(NOT BASIC_PROJECT_CONFIG_DONE)
if (NOT BASIC_PROJECT_CONFIG_DONE)
message(FATAL_ERROR "Before including the AppTarget module, the BasicConfig module must be included.")
endif()
if(TARGET_CONFIG_DONE)
endif ()
if (TARGET_CONFIG_DONE)
message(FATAL_ERROR "Can not include AppTarget module when targets are already configured.")
endif()
endif ()
# check whether project type is set correctly
if(NOT "${META_PROJECT_TYPE}" STREQUAL "application")
message(FATAL_ERROR "The AppTarget CMake module is intended to be used for building application projects only (and not for libraries).")
endif()
if (NOT "${META_PROJECT_TYPE}" STREQUAL "application")
message(
FATAL_ERROR
"The AppTarget CMake module is intended to be used for building application projects only (and not for libraries)."
)
endif ()
# set the windows extension to "exe", this is required by the Windows specific WindowsResources module
if(WIN32)
if (WIN32)
set(WINDOWS_EXT "exe")
endif(WIN32)
endif (WIN32)
# set compile definitions
if(NOT META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS)
set(META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS ${META_PUBLIC_COMPILE_DEFINITIONS} ${META_ADDITIONAL_PUBLIC_SHARED_COMPILE_DEFINITIONS})
endif()
if(NOT META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS)
set(META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS ${META_PRIVATE_COMPILE_DEFINITIONS} ${META_ADDITIONAL_PRIVATE_SHARED_COMPILE_DEFINITIONS})
if(STATIC_LINKAGE)
if (NOT META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS)
set(META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS ${META_PUBLIC_COMPILE_DEFINITIONS}
${META_ADDITIONAL_PUBLIC_SHARED_COMPILE_DEFINITIONS})
endif ()
if (NOT META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS)
set(META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS ${META_PRIVATE_COMPILE_DEFINITIONS}
${META_ADDITIONAL_PRIVATE_SHARED_COMPILE_DEFINITIONS})
if (STATIC_LINKAGE)
list(APPEND META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS APP_STATICALLY_LINKED)
endif()
endif()
endif ()
endif ()
# set linker flags
if(STATIC_LINKAGE)
if (STATIC_LINKAGE)
set(ACTUAL_ADDITIONAL_LINK_FLAGS ${META_ADDITIONAL_STATIC_LINK_FLAGS})
else()
else ()
set(ACTUAL_ADDITIONAL_LINK_FLAGS ${META_ADDITIONAL_LINK_FLAGS})
endif()
endif ()
# define relevant files
set(ALL_FILES ${HEADER_FILES} ${SRC_FILES} ${GENERATED_DBUS_FILES} ${WIDGETS_FILES} ${QML_FILES} ${RES_FILES} ${WINDOWS_ICON_PATH})
if(NOT BUILTIN_TRANSLATIONS)
set(ALL_FILES
${HEADER_FILES}
${SRC_FILES}
${GENERATED_DBUS_FILES}
${WIDGETS_FILES}
${QML_FILES}
${RES_FILES}
${WINDOWS_ICON_PATH})
if (NOT BUILTIN_TRANSLATIONS)
list(APPEND ALL_FILES ${QM_FILES})
endif()
endif ()
# add target for building the application
if (NOT ANDROID)
add_executable(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} ${GUI_TYPE} ${ALL_FILES})
else()
else ()
# create a library which can be loaded from the Java-side
add_library(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} SHARED ${GUI_TYPE} ${ALL_FILES})
endif()
endif ()
target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
PUBLIC ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}"
PRIVATE "${PRIVATE_LIBRARIES}"
)
PUBLIC ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}"
PRIVATE "${PRIVATE_LIBRARIES}")
target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}>
${PUBLIC_SHARED_INCLUDE_DIRS}
PRIVATE
"${PRIVATE_SHARED_INCLUDE_DIRS}"
)
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> ${PUBLIC_SHARED_INCLUDE_DIRS}
PRIVATE "${PRIVATE_SHARED_INCLUDE_DIRS}")
target_compile_definitions(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS}"
PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS}"
)
PUBLIC
"${META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS}"
PRIVATE
"${META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS}")
target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}"
PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}"
)
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} PROPERTIES
CXX_STANDARD "${META_CXX_STANDARD}"
LINK_SEARCH_START_STATIC ${STATIC_LINKAGE}
LINK_SEARCH_END_STATIC ${STATIC_LINKAGE}
AUTOGEN_TARGET_DEPENDS "${AUTOGEN_DEPS}"
)
PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}"
PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}")
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
PROPERTIES CXX_STANDARD
"${META_CXX_STANDARD}"
LINK_SEARCH_START_STATIC
${STATIC_LINKAGE}
LINK_SEARCH_END_STATIC
${STATIC_LINKAGE}
AUTOGEN_TARGET_DEPENDS
"${AUTOGEN_DEPS}")
if(NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS)
if (NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS)
# add install target for binary
if(APPLE)
if (APPLE)
set(BUNDLE_INSTALL_DESTINATION bin CACHE STRING "specifies the install destination for bundles")
install(TARGETS ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
RUNTIME DESTINATION bin
BUNDLE DESTINATION "${BUNDLE_INSTALL_DESTINATION}"
COMPONENT binary
)
elseif(ANDROID)
install(
TARGETS ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
RUNTIME DESTINATION bin
COMPONENT binary
LIBRARY DESTINATION lib${SELECTED_LIB_SUFFIX}
COMPONENT binary
ARCHIVE DESTINATION lib${SELECTED_LIB_SUFFIX}
COMPONENT binary
)
else()
RUNTIME DESTINATION bin
BUNDLE DESTINATION "${BUNDLE_INSTALL_DESTINATION}" COMPONENT binary)
elseif (ANDROID)
install(TARGETS ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
RUNTIME DESTINATION bin
COMPONENT binary
)
endif()
RUNTIME DESTINATION bin COMPONENT binary
LIBRARY DESTINATION lib${SELECTED_LIB_SUFFIX} COMPONENT binary
ARCHIVE DESTINATION lib${SELECTED_LIB_SUFFIX} COMPONENT binary)
else ()
install(TARGETS ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} RUNTIME DESTINATION bin COMPONENT binary)
endif ()
if(NOT TARGET install-binary)
if (NOT TARGET install-binary)
add_custom_target(install-binary
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=binary -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=binary -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif ()
add_dependencies(install-binary ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX})
# add mingw-w64 specific install target
if(NOT TARGET install-mingw-w64)
if (NOT TARGET install-mingw-w64)
add_custom_target(install-mingw-w64)
add_dependencies(install-mingw-w64 install-binary)
endif()
endif ()
add_dependencies(install-mingw-w64 ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX})
# add install target for desktop entries and icons
foreach(DESKTOP_FILE ${DESKTOP_FILES})
install(
FILES "${DESKTOP_FILE}"
DESTINATION "share/applications"
COMPONENT desktop
)
endforeach()
foreach (DESKTOP_FILE ${DESKTOP_FILES})
install(FILES "${DESKTOP_FILE}" DESTINATION "share/applications" COMPONENT desktop)
endforeach ()
foreach(ICON_FILE ${ICON_FILES})
install(
FILES "${ICON_FILE}"
DESTINATION "share/icons/hicolor/scalable/apps"
COMPONENT desktop
)
endforeach()
if(NOT TARGET install-desktop)
foreach (ICON_FILE ${ICON_FILES})
install(FILES "${ICON_FILE}" DESTINATION "share/icons/hicolor/scalable/apps" COMPONENT desktop)
endforeach ()
if (NOT TARGET install-desktop)
add_custom_target(install-desktop
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=desktop -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=desktop -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif ()
add_dependencies(install-desktop ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX})
if(NOT TARGET install-appimage)
if (NOT TARGET install-appimage)
add_custom_target(install-appimage
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=appimage -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=appimage -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif ()
add_dependencies(install-appimage ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX})
# add install target for stripped binaries
if(NOT TARGET install-binary-strip)
if (NOT TARGET install-binary-strip)
add_custom_target(install-binary-strip
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_DO_STRIP=1 -DCMAKE_INSTALL_COMPONENT=binary -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_DO_STRIP=1 -DCMAKE_INSTALL_COMPONENT=binary -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif ()
add_dependencies(install-binary-strip ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX})
# add mingw-w64 specific install targets
if(MINGW)
if(NOT TARGET install-mingw-w64)
if (MINGW)
if (NOT TARGET install-mingw-w64)
add_custom_target(install-mingw-w64)
add_dependencies(install-mingw-w64 install-binary)
endif()
if(NOT TARGET install-mingw-w64-strip)
endif ()
if (NOT TARGET install-mingw-w64-strip)
add_custom_target(install-mingw-w64-strip)
add_dependencies(install-mingw-w64-strip install-binary-strip)
endif()
if(LOCALIZATION_TARGET)
endif ()
if (LOCALIZATION_TARGET)
add_dependencies(install-mingw-w64 ${LOCALIZATION_TARGET})
add_dependencies(install-mingw-w64-strip ${LOCALIZATION_TARGET})
endif()
endif()
endif()
endif ()
endif ()
endif ()
# add target for launching application with wine ensuring the WINEPATH is set correctly so wine is able to find all required *.dll files
# requires script from c++utilities, hence the sources of c++utilities must be present
if(MINGW AND CMAKE_CROSSCOMPILING AND CPP_UTILITIES_SOURCE_DIR)
if(NOT TARGET ${META_PROJECT_NAME}_run)
if(CMAKE_FIND_ROOT_PATH)
# add target for launching application with wine ensuring the WINEPATH is set correctly so wine is able to find all required
# *.dll files requires script from c++utilities, hence the sources of c++utilities must be present
if (MINGW AND CMAKE_CROSSCOMPILING AND CPP_UTILITIES_SOURCE_DIR)
if (NOT TARGET ${META_PROJECT_NAME}_run)
if (CMAKE_FIND_ROOT_PATH)
list(APPEND RUNTIME_LIBRARY_PATH "${CMAKE_FIND_ROOT_PATH}/bin")
endif()
add_custom_target(${META_PROJECT_NAME}_run COMMAND "${CPP_UTILITIES_SOURCE_DIR}/scripts/wine.sh" "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}.${WINDOWS_EXT}" ${RUNTIME_LIBRARY_PATH})
endif ()
add_custom_target(${META_PROJECT_NAME}_run
COMMAND "${CPP_UTILITIES_SOURCE_DIR}/scripts/wine.sh"
"${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}.${WINDOWS_EXT}" ${RUNTIME_LIBRARY_PATH})
add_dependencies(${META_PROJECT_NAME}_run ${META_PROJECT_NAME})
endif()
endif()
endif ()
endif ()
# find template for *.desktop files
include(TemplateFinder)
find_template_file("desktop" CPP_UTILITIES APP_DESKTOP_TEMPLATE_FILE)
find_template_file("appdata.xml" CPP_UTILITIES APP_APPSTREAM_TEMPLATE_FILE)
# function to add *.desktop files with additional entries
# FIXME v5: use "include(CMakeParseArguments)" like in ReflectionGenerator.cmake
function(add_custom_desktop_file_with_additional_entries
FILE_NAME
DESKTOP_FILE_APP_NAME
DESKTOP_FILE_GENERIC_NAME
DESKTOP_FILE_DESCRIPTION
DESKTOP_FILE_CATEGORIES
DESKTOP_FILE_CMD
DESKTOP_FILE_ICON
DESKTOP_FILE_ADDITIONAL_ENTRIES)
# function to add *.desktop files with additional entries FIXME v5: use "include(CMakeParseArguments)" like in
# ReflectionGenerator.cmake
function (add_custom_desktop_file_with_additional_entries
FILE_NAME
DESKTOP_FILE_APP_NAME
DESKTOP_FILE_GENERIC_NAME
DESKTOP_FILE_DESCRIPTION
DESKTOP_FILE_CATEGORIES
DESKTOP_FILE_CMD
DESKTOP_FILE_ICON
DESKTOP_FILE_ADDITIONAL_ENTRIES)
# create desktop file from template
configure_file(
"${APP_DESKTOP_TEMPLATE_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/resources/${FILE_NAME}.desktop"
)
configure_file("${APP_DESKTOP_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/resources/${FILE_NAME}.desktop")
# add install for the desktop file
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/resources/${FILE_NAME}.desktop"
DESTINATION "share/applications"
COMPONENT desktop
)
endfunction()
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/resources/${FILE_NAME}.desktop"
DESTINATION "share/applications"
COMPONENT desktop)
endfunction ()
# function to add *.desktop files
function(add_custom_desktop_file
FILE_NAME
DESKTOP_FILE_APP_NAME
DESKTOP_FILE_GENERIC_NAME
DESKTOP_FILE_DESCRIPTION
DESKTOP_FILE_CATEGORIES
DESKTOP_FILE_CMD
DESKTOP_FILE_ICON)
add_custom_desktop_file_with_additional_entries(
"${FILE_NAME}"
"${DESKTOP_FILE_APP_NAME}"
"${DESKTOP_FILE_GENERIC_NAME}"
"${DESKTOP_FILE_DESCRIPTION}"
"${DESKTOP_FILE_CATEGORIES}"
"${DESKTOP_FILE_CMD}"
"${DESKTOP_FILE_ICON}"
""
)
endfunction()
function (add_custom_desktop_file
FILE_NAME
DESKTOP_FILE_APP_NAME
DESKTOP_FILE_GENERIC_NAME
DESKTOP_FILE_DESCRIPTION
DESKTOP_FILE_CATEGORIES
DESKTOP_FILE_CMD
DESKTOP_FILE_ICON)
add_custom_desktop_file_with_additional_entries("${FILE_NAME}"
"${DESKTOP_FILE_APP_NAME}"
"${DESKTOP_FILE_GENERIC_NAME}"
"${DESKTOP_FILE_DESCRIPTION}"
"${DESKTOP_FILE_CATEGORIES}"
"${DESKTOP_FILE_CMD}"
"${DESKTOP_FILE_ICON}"
"")
endfunction ()
# convenience function to add *.desktop file and meta info from project meta data
function(add_desktop_file)
function (add_desktop_file)
# compose actions
set(DESKTOP_FILE_ADDITIONAL_ENTRIES "")
foreach(ACTION_VAR ${META_APP_ACTIONS})
foreach (ACTION_VAR ${META_APP_ACTIONS})
list(GET META_APP_ACTION_${ACTION_VAR} 0 ACTION_ID)
list(GET META_APP_ACTION_${ACTION_VAR} 1 ACTION_NAME)
list(GET META_APP_ACTION_${ACTION_VAR} 2 ACTION_ARGS)
set(DESKTOP_FILE_ADDITIONAL_ENTRIES "${DESKTOP_FILE_ADDITIONAL_ENTRIES}\n[Desktop Action ${ACTION_ID}]\nName=${ACTION_NAME}\nExec=${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} ${ACTION_ARGS}")
endforeach()
set(
DESKTOP_FILE_ADDITIONAL_ENTRIES
"${DESKTOP_FILE_ADDITIONAL_ENTRIES}\n[Desktop Action ${ACTION_ID}]\nName=${ACTION_NAME}\nExec=${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} ${ACTION_ARGS}"
)
endforeach ()
# create desktop file
add_custom_desktop_file_with_additional_entries(
"${META_ID}"
"${META_APP_NAME}"
"${META_GENERIC_NAME}"
"${META_APP_DESCRIPTION}"
"${META_APP_CATEGORIES}"
"${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}"
"${META_PROJECT_NAME}"
"${DESKTOP_FILE_ADDITIONAL_ENTRIES}"
)
add_custom_desktop_file_with_additional_entries("${META_ID}"
"${META_APP_NAME}"
"${META_GENERIC_NAME}"
"${META_APP_DESCRIPTION}"
"${META_APP_CATEGORIES}"
"${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}"
"${META_PROJECT_NAME}"
"${DESKTOP_FILE_ADDITIONAL_ENTRIES}")
# read body for appstream desktop file from resources
set(META_APP_APPDATA_BODY_FILE "${CMAKE_CURRENT_SOURCE_DIR}/resources/body.appdata.xml")
set(META_APP_APPDATA_SUBSTITUTED_BODY_FILE "${CMAKE_CURRENT_BINARY_DIR}/resources/${META_ID}.body.appdata.xml")
if(EXISTS "${META_APP_APPDATA_BODY_FILE}")
configure_file(
"${META_APP_APPDATA_BODY_FILE}"
"${META_APP_APPDATA_SUBSTITUTED_BODY_FILE}"
@ONLY
)
if (EXISTS "${META_APP_APPDATA_BODY_FILE}")
configure_file("${META_APP_APPDATA_BODY_FILE}" "${META_APP_APPDATA_SUBSTITUTED_BODY_FILE}" @ONLY)
file(READ "${META_APP_APPDATA_SUBSTITUTED_BODY_FILE}" META_APP_APPDATA_BODY)
# add indentation of two additional spaces
string(REGEX REPLACE "\n([^$])" "\n \\1" META_APP_APPDATA_BODY "${META_APP_APPDATA_BODY}")
endif()
string(REGEX
REPLACE "\n([^$])"
"\n \\1"
META_APP_APPDATA_BODY
"${META_APP_APPDATA_BODY}")
endif ()
# create appstream desktop file from template
configure_file(
"${APP_APPSTREAM_TEMPLATE_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/resources/${META_ID}.appdata.xml"
@ONLY
)
configure_file("${APP_APPSTREAM_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/resources/${META_ID}.appdata.xml" @ONLY)
# add install for the appstream file
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/resources/${META_ID}.appdata.xml"
DESTINATION "share/metainfo"
COMPONENT appimage
)
endfunction()
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/resources/${META_ID}.appdata.xml"
DESTINATION "share/metainfo"
COMPONENT appimage)
endfunction ()
set(TARGET_CONFIG_DONE YES)

View File

@ -1,119 +1,130 @@
# before including this module, the project meta-data must be set
if(NOT META_PROJECT_NAME)
if (NOT META_PROJECT_NAME)
message(FATAL_ERROR "No project name (META_PROJECT_NAME) specified.")
endif()
if(NOT META_APP_NAME)
endif ()
if (NOT META_APP_NAME)
message(FATAL_ERROR "No project name (META_APP_NAME) specified.")
endif()
if(NOT META_APP_AUTHOR)
endif ()
if (NOT META_APP_AUTHOR)
message(FATAL_ERROR "No project name (META_APP_AUTHOR) specified.")
endif()
if(NOT META_APP_DESCRIPTION)
endif ()
if (NOT META_APP_DESCRIPTION)
message(FATAL_ERROR "No project name (META_APP_DESCRIPTION) specified.")
endif()
endif ()
# set project name (displayed in Qt Creator)
message(STATUS "Configuring project ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}")
project(${META_PROJECT_NAME})
# set META_PROJECT_VARNAME and META_PROJECT_VARNAME_UPPER if not specified explicitely
if(NOT META_PROJECT_VARNAME)
if (NOT META_PROJECT_VARNAME)
set(META_PROJECT_VARNAME "${META_PROJECT_NAME}")
endif()
if(NOT META_PROJECT_VARNAME_UPPER)
endif ()
if (NOT META_PROJECT_VARNAME_UPPER)
string(TOUPPER ${META_PROJECT_VARNAME} META_PROJECT_VARNAME_UPPER)
endif()
if(NOT META_PROJECT_VARNAME_LOWER)
string(REGEX REPLACE "_+" "" META_PROJECT_VARNAME_LOWER "${META_PROJECT_VARNAME}")
endif ()
if (NOT META_PROJECT_VARNAME_LOWER)
string(REGEX
REPLACE "_+"
""
META_PROJECT_VARNAME_LOWER
"${META_PROJECT_VARNAME}")
string(TOLOWER "${META_PROJECT_VARNAME_LOWER}" META_PROJECT_VARNAME_LOWER)
endif()
endif ()
# set META_GENERIC_NAME to META_APP_NAME if not specified explicitely
if(NOT META_GENERIC_NAME)
if (NOT META_GENERIC_NAME)
set(META_GENERIC_NAME "${META_APP_NAME}")
endif()
endif ()
# set default CXX_STANDARD for all library, application and test targets
if(NOT META_CXX_STANDARD)
if (NOT META_CXX_STANDARD)
set(META_CXX_STANDARD 14)
endif()
endif ()
# set version to 0.0.0 if not specified explicitely
if(NOT META_VERSION_MAJOR)
if (NOT META_VERSION_MAJOR)
set(META_VERSION_MAJOR 0)
endif()
if(NOT META_VERSION_MINOR)
endif ()
if (NOT META_VERSION_MINOR)
set(META_VERSION_MINOR 0)
endif()
if(NOT META_VERSION_PATCH)
endif ()
if (NOT META_VERSION_PATCH)
set(META_VERSION_PATCH 0)
endif()
endif ()
# set META_ID to META_PROJECT_NAME if not specified
if(NOT META_ID)
if (NOT META_ID)
set(META_ID "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}")
endif()
endif ()
# set bugtracker URL
if(NOT META_APP_BUGTRACKER_URL)
if(META_APP_URL MATCHES "https://(github.com|gitlab.com|.*/(gogs|gitea)|(gogs|gitea).*)/.*")
if (NOT META_APP_BUGTRACKER_URL)
if (META_APP_URL MATCHES "https://(github.com|gitlab.com|.*/(gogs|gitea)|(gogs|gitea).*)/.*")
set(META_APP_BUGTRACKER_URL "${META_APP_URL}/issues")
else()
else ()
set(META_APP_BUGTRACKER_URL "${META_APP_URL}")
endif()
endif()
endif ()
endif ()
# determine license automatically from LICENSE file
if(NOT META_PROJECT_LICENSE)
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
if (NOT META_PROJECT_LICENSE)
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE" META_PROJECT_LICENSE_FILE)
elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../LICENSE")
elseif (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../LICENSE")
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/../LICENSE" META_PROJECT_LICENSE_FILE)
endif()
if(META_PROJECT_LICENSE_FILE MATCHES "GNU GENERAL PUBLIC LICENSE.*Version ([1-9\\.]*)")
endif ()
if (META_PROJECT_LICENSE_FILE MATCHES "GNU GENERAL PUBLIC LICENSE.*Version ([1-9\\.]*)")
set(META_PROJECT_LICENSE "GPL-${CMAKE_MATCH_1}")
elseif(META_PROJECT_LICENSE_FILE MATCHES "GNU LESSER GENERAL PUBLIC LICENSE.*Version ([1-9\\.]*)")
elseif (META_PROJECT_LICENSE_FILE MATCHES "GNU LESSER GENERAL PUBLIC LICENSE.*Version ([1-9\\.]*)")
set(META_PROJECT_LICENSE "LGPL-${CMAKE_MATCH_1}")
elseif(META_PROJECT_LICENSE_FILE MATCHES "MIT License")
elseif (META_PROJECT_LICENSE_FILE MATCHES "MIT License")
set(META_PROJECT_LICENSE "MIT")
elseif(META_PROJECT_LICENSE_FILE MATCHES "Mozilla Public License Version ([1-9\\.]*)")
elseif (META_PROJECT_LICENSE_FILE MATCHES "Mozilla Public License Version ([1-9\\.]*)")
set(META_PROJECT_LICENSE "MPL-${CMAKE_MATCH_1}")
else()
message(WARNING "Unable to detect license of ${META_PROJECT_NAME}. Set META_PROJECT_LICENSE manually to silence this warning.")
endif()
endif()
else ()
message(
WARNING
"Unable to detect license of ${META_PROJECT_NAME}. Set META_PROJECT_LICENSE manually to silence this warning."
)
endif ()
endif ()
# provide variables for other projects built as part of the same subdirs project
# to access files from this project
# provide variables for other projects built as part of the same subdirs project to access files from this project
get_directory_property(HAS_PARENT PARENT_DIRECTORY)
if(HAS_PARENT)
if (HAS_PARENT)
set(${META_PROJECT_VARNAME_UPPER}_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PARENT_SCOPE)
set(${META_PROJECT_VARNAME_UPPER}_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" PARENT_SCOPE)
set(${META_PROJECT_NAME}_DIR "${CMAKE_CURRENT_BINARY_DIR}" PARENT_SCOPE)
set(RUNTIME_LIBRARY_PATH "${CMAKE_CURRENT_BINARY_DIR}" ${RUNTIME_LIBRARY_PATH} PARENT_SCOPE)
endif()
endif ()
# determine version
set(META_APP_VERSION ${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH})
option(APPEND_GIT_REVISION "whether the build script should attempt to append the git revision and latest commit to the version displayed via --help" ON)
if(APPEND_GIT_REVISION)
option(
APPEND_GIT_REVISION
"whether the build script should attempt to append the git revision and latest commit to the version displayed via --help"
ON)
if (APPEND_GIT_REVISION)
find_program(GIT_BIN git)
execute_process(
COMMAND ${GIT_BIN} rev-list --count HEAD
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE META_GIT_REV_COUNT
)
execute_process(
COMMAND ${GIT_BIN} rev-parse --short HEAD
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE META_GIT_LAST_COMMIT_ID
)
string(REPLACE "\n" "" META_GIT_REV_COUNT "${META_GIT_REV_COUNT}")
string(REPLACE "\n" "" META_GIT_LAST_COMMIT_ID "${META_GIT_LAST_COMMIT_ID}")
if(META_GIT_REV_COUNT AND META_GIT_LAST_COMMIT_ID)
execute_process(COMMAND ${GIT_BIN} rev-list --count HEAD
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE META_GIT_REV_COUNT)
execute_process(COMMAND ${GIT_BIN} rev-parse --short HEAD
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE META_GIT_LAST_COMMIT_ID)
string(REPLACE "\n"
""
META_GIT_REV_COUNT
"${META_GIT_REV_COUNT}")
string(REPLACE "\n"
""
META_GIT_LAST_COMMIT_ID
"${META_GIT_LAST_COMMIT_ID}")
if (META_GIT_REV_COUNT AND META_GIT_LAST_COMMIT_ID)
set(META_APP_VERSION ${META_APP_VERSION}-${META_GIT_REV_COUNT}.${META_GIT_LAST_COMMIT_ID})
endif()
endif()
endif ()
endif ()
# set TARGET_EXECUTABLE which is used to refer to the target executable at its installation location
set(TARGET_EXECUTABLE "${CMAKE_INSTALL_PREFIX}/bin/${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}")
@ -121,239 +132,245 @@ set(TARGET_EXECUTABLE "${CMAKE_INSTALL_PREFIX}/bin/${TARGET_PREFIX}${META_PROJEC
# create header for feature detection
if (META_FEATURES_FOR_COMPILER_DETECTION_HEADER)
include(WriteCompilerDetectionHeader)
write_compiler_detection_header(
FILE "${CMAKE_CURRENT_BINARY_DIR}/resources/features.h"
PREFIX "${META_PROJECT_VARNAME_UPPER}"
COMPILERS GNU Clang
FEATURES ${META_FEATURES_FOR_COMPILER_DETECTION_HEADER}
)
endif()
write_compiler_detection_header(FILE
"${CMAKE_CURRENT_BINARY_DIR}/resources/features.h"
PREFIX
"${META_PROJECT_VARNAME_UPPER}"
COMPILERS
GNU
Clang
FEATURES
${META_FEATURES_FOR_COMPILER_DETECTION_HEADER})
endif ()
# disable new ABI (can't catch ios_base::failure with new ABI)
option(FORCE_OLD_ABI "specifies whether usage of old ABI should be forced" OFF)
if(FORCE_OLD_ABI)
if (FORCE_OLD_ABI)
list(APPEND META_PRIVATE_COMPILE_DEFINITIONS _GLIBCXX_USE_CXX11_ABI=0)
message(STATUS "Forcing usage of old CXX11 ABI.")
else()
else ()
message(STATUS "Using default CXX11 ABI (not forcing old CX11 ABI).")
endif()
endif ()
# enable debug-only code when doing a debug build
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
list(APPEND META_PRIVATE_COMPILE_DEFINITIONS DEBUG_BUILD)
message(STATUS "Debug build enabled.")
endif()
endif ()
# enable logging when option is set
option(LOGGING_ENABLED "specifies whether logging is enabled" OFF)
if(LOGGING_ENABLED)
if (LOGGING_ENABLED)
list(APPEND META_PRIVATE_COMPILE_DEFINITIONS LOGGING_ENABLED)
message(STATUS "Logging is enabled.")
endif()
endif ()
# options for deciding whether to build static and/or shared libraries
if(("${META_PROJECT_TYPE}" STREQUAL "library") OR ("${META_PROJECT_TYPE}" STREQUAL "plugin") OR ("${META_PROJECT_TYPE}" STREQUAL "qtplugin") OR ("${META_PROJECT_TYPE}" STREQUAL ""))
if (("${META_PROJECT_TYPE}" STREQUAL "library")
OR ("${META_PROJECT_TYPE}" STREQUAL "plugin")
OR ("${META_PROJECT_TYPE}" STREQUAL "qtplugin")
OR ("${META_PROJECT_TYPE}" STREQUAL ""))
option(ENABLE_STATIC_LIBS "whether building static libraries is enabled (disabled by default)" OFF)
option(DISABLE_SHARED_LIBS "whether building dynamic libraries is disabled (enabled by default)" OFF)
if(DISABLE_SHARED_LIBS)
if (DISABLE_SHARED_LIBS)
set(BUILD_SHARED_LIBS OFF)
else()
else ()
set(BUILD_SHARED_LIBS ON)
endif()
if(ENABLE_STATIC_LIBS)
endif ()
if (ENABLE_STATIC_LIBS)
set(BUILD_STATIC_LIBS ON)
else()
else ()
set(BUILD_STATIC_LIBS OFF)
endif()
endif()
endif ()
endif ()
# options for forcing static linkage when building applications or dynamic libraries
if(("${META_PROJECT_TYPE}" STREQUAL "library") OR ("${META_PROJECT_TYPE}" STREQUAL "plugin") OR ("${META_PROJECT_TYPE}" STREQUAL "qtplugin") OR ("${META_PROJECT_TYPE}" STREQUAL ""))
if (("${META_PROJECT_TYPE}" STREQUAL "library")
OR ("${META_PROJECT_TYPE}" STREQUAL "plugin")
OR ("${META_PROJECT_TYPE}" STREQUAL "qtplugin")
OR ("${META_PROJECT_TYPE}" STREQUAL ""))
option(STATIC_LIBRARY_LINKAGE "forces static linkage when building dynamic libraries" OFF)
elseif("${META_PROJECT_TYPE}" STREQUAL "application")
elseif ("${META_PROJECT_TYPE}" STREQUAL "application")
option(STATIC_LINKAGE "forces static linkage when building applications" OFF)
endif()
endif ()
# additional linker flags used when static linkage is enabled
if(NOT APPLE)
if (NOT APPLE)
list(APPEND META_ADDITIONAL_STATIC_LINK_FLAGS -static)
endif()
endif ()
list(APPEND META_ADDITIONAL_STATIC_LINK_FLAGS -static-libstdc++ -static-libgcc)
# determine whether the project is a header-only library
if(SRC_FILES OR GUI_SRC_FILES OR WIDGETS_SRC_FILES OR WIDGETS_UI_FILES OR QML_SRC_FILES OR RES_FILES)
if (SRC_FILES OR GUI_SRC_FILES OR WIDGETS_SRC_FILES OR WIDGETS_UI_FILES OR QML_SRC_FILES OR RES_FILES)
set(META_HEADER_ONLY_LIB NO)
else()
else ()
set(META_HEADER_ONLY_LIB YES)
if("${META_PROJECT_TYPE}" STREQUAL "application")
if ("${META_PROJECT_TYPE}" STREQUAL "application")
message(FATAL_ERROR "Project ${META_PROJECT_NAME} is supposed to be an application but has only header files.")
endif()
endif ()
message(STATUS "Project ${META_PROJECT_NAME} is header-only library.")
endif()
endif ()
# options for enabling/disabling Qt GUI (if available)
if(WIDGETS_HEADER_FILES OR WIDGETS_SRC_FILES OR WIDGETS_UI_FILES OR META_HAS_WIDGETS_GUI)
if(META_GUI_OPTIONAL)
if (WIDGETS_HEADER_FILES OR WIDGETS_SRC_FILES OR WIDGETS_UI_FILES OR META_HAS_WIDGETS_GUI)
if (META_GUI_OPTIONAL)
option(WIDGETS_GUI "enables/disables building the Qt Widgets GUI: yes (default) or no" ON)
else()
else ()
set(WIDGETS_GUI ON)
endif()
else()
endif ()
else ()
set(WIDGETS_GUI OFF)
endif()
if(QML_HEADER_FILES OR QML_SRC_FILES OR META_HAS_QUICK_GUI)
if(META_GUI_OPTIONAL)
endif ()
if (QML_HEADER_FILES OR QML_SRC_FILES OR META_HAS_QUICK_GUI)
if (META_GUI_OPTIONAL)
option(QUICK_GUI "enables/disables building the Qt Quick GUI: yes (default) or no" ON)
else()
else ()
set(QUICK_GUI ON)
endif()
else()
endif ()
else ()
set(QUICK_GUI OFF)
endif()
endif ()
# find coding style (use style from c++utilities if none included in own project dir)
if(NOT META_NO_TIDY)
if (NOT META_NO_TIDY)
set(CLANG_FORMAT_RULES "${CMAKE_CURRENT_SOURCE_DIR}/coding-style.clang-format")
if(CPP_UTILITIES_SOURCE_DIR AND NOT EXISTS "${CLANG_FORMAT_RULES}")
if (CPP_UTILITIES_SOURCE_DIR AND NOT EXISTS "${CLANG_FORMAT_RULES}")
set(CLANG_FORMAT_RULES "${CPP_UTILITIES_SOURCE_DIR}/coding-style.clang-format")
endif()
if(NOT EXISTS "${CLANG_FORMAT_RULES}")
endif ()
if (NOT EXISTS "${CLANG_FORMAT_RULES}")
set(CLANG_FORMAT_RULES "${CPP_UTILITIES_CONFIG_DIRS}/codingstyle.clang-format")
endif()
endif()
endif ()
endif ()
# enable testing
enable_testing()
get_directory_property(HAS_PARENT PARENT_DIRECTORY)
if(HAS_PARENT)
if (HAS_PARENT)
message(STATUS "For the check target to work, it is required to call enable_testing() on the source directory root.")
endif()
endif ()
# make finding testfiles in out-of-source-tree build more convenient by adding a reference to the source directory
# (not only useful if there's a test target; this is for instance also used in mocked configuration of syncthingtray)
# -> add a file called "srcdirref" to the build directory; this file contains the path of the sources so tests can easily find test files contained in the source directory
# make finding testfiles in out-of-source-tree build more convenient by adding a reference to the source directory (not only
# useful if there's a test target; this is for instance also used in mocked configuration of syncthingtray) -> add a file
# called "srcdirref" to the build directory; this file contains the path of the sources so tests can easily find test files
# contained in the source directory
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/srcdirref" "${CMAKE_CURRENT_SOURCE_DIR}")
# -> ensure the directory "testfiles" exists in the build directory; tests of my projects use it by default to create working copies of testfiles
# -> ensure the directory "testfiles" exists in the build directory; tests of my projects use it by default to create working
# copies of testfiles
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/testfiles")
# determine source files which might be passed to clang-format or clang-tidy
set(FORMATABLE_FILES
${HEADER_FILES} ${SRC_FILES}
${TEST_HEADER_FILES} ${TEST_SRC_FILES}
${GUI_HEADER_FILES} ${GUI_SRC_FILES}
${WIDGETS_HEADER_FILES} ${WIDGETS_SRC_FILES}
${QML_HEADER_FILES} ${QML_SRC_FILES}
)
${HEADER_FILES}
${SRC_FILES}
${TEST_HEADER_FILES}
${TEST_SRC_FILES}
${GUI_HEADER_FILES}
${GUI_SRC_FILES}
${WIDGETS_HEADER_FILES}
${WIDGETS_SRC_FILES}
${QML_HEADER_FILES}
${QML_SRC_FILES})
# only format C/C++ files (and not eg. QML files)
if(FORMATABLE_FILES)
if (FORMATABLE_FILES)
list(FILTER FORMATABLE_FILES INCLUDE REGEX ".*\\.(c|cpp|h|hpp)")
endif()
endif ()
# determine source files which might be passed to cmake-format
set(FORMATABLE_FILES_CMAKE
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_MODULE_FILES}
)
set(FORMATABLE_FILES_CMAKE ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt ${CMAKE_MODULE_FILES})
# add command for symlinking clang-{format,tidy} rules so the tools can find it
if(EXISTS "${CLANG_FORMAT_RULES}")
add_custom_command(
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/.clang-format"
COMMAND "${CMAKE_COMMAND}" -E create_symlink "${CLANG_FORMAT_RULES}" "${CMAKE_CURRENT_SOURCE_DIR}/.clang-format"
COMMENT "Linking coding style from ${CLANG_FORMAT_RULES}"
)
else()
if (EXISTS "${CLANG_FORMAT_RULES}")
add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/.clang-format"
COMMAND "${CMAKE_COMMAND}" -E create_symlink "${CLANG_FORMAT_RULES}"
"${CMAKE_CURRENT_SOURCE_DIR}/.clang-format"
COMMENT "Linking coding style from ${CLANG_FORMAT_RULES}")
else ()
message(WARNING "Format rules for clang-format not found.")
endif()
endif ()
# allow user to configure creation of tidy targets unless the project disables this via META_NO_TIDY
if(NOT META_NO_TIDY)
if (NOT META_NO_TIDY)
option(CLANG_FORMAT_ENABLED "enables creation of tidy target using clang-format" OFF)
option(CMAKE_FORMAT_ENABLED "enables creation of tidy target using cmake-format" OFF)
endif()
endif ()
# add target for tidying with clang-format
if(NOT META_NO_TIDY AND CLANG_FORMAT_ENABLED AND FORMATABLE_FILES AND EXISTS "${CLANG_FORMAT_RULES}")
if (NOT META_NO_TIDY AND CLANG_FORMAT_ENABLED AND FORMATABLE_FILES AND EXISTS "${CLANG_FORMAT_RULES}")
find_program(CLANG_FORMAT_BIN clang-format)
if(NOT CLANG_FORMAT_BIN)
if (NOT CLANG_FORMAT_BIN)
message(FATAL_ERROR "Unable to add tidy target; clang-format not found")
endif()
endif ()
add_custom_target("${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tidy"
COMMAND "${CLANG_FORMAT_BIN}" -style=file -i ${FORMATABLE_FILES}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Tidying ${META_PROJECT_NAME} sources using clang-format"
DEPENDS "${FORMATABLE_FILES};${CMAKE_CURRENT_SOURCE_DIR}/.clang-format"
)
if(NOT TARGET tidy)
COMMAND "${CLANG_FORMAT_BIN}" -style=file -i ${FORMATABLE_FILES}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Tidying ${META_PROJECT_NAME} sources using clang-format"
DEPENDS "${FORMATABLE_FILES};${CMAKE_CURRENT_SOURCE_DIR}/.clang-format")
if (NOT TARGET tidy)
add_custom_target(tidy)
endif()
endif ()
add_dependencies(tidy "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tidy")
# also add a test to verify whether sources are tidy
add_test(NAME "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tidy_test"
COMMAND "${CLANG_FORMAT_BIN}" -output-replacements-xml -style=file ${FORMATABLE_FILES}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
)
COMMAND "${CLANG_FORMAT_BIN}" -output-replacements-xml -style=file ${FORMATABLE_FILES}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
list(APPEND CHECK_TARGET_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/.clang-format")
set_tests_properties("${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tidy_test" PROPERTIES
FAIL_REGULAR_EXPRESSION "<replacement.*>.*</replacement>"
REQUIRED_FILES "${CMAKE_CURRENT_SOURCE_DIR}/.clang-format"
)
endif()
set_tests_properties("${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tidy_test"
PROPERTIES FAIL_REGULAR_EXPRESSION
"<replacement.*>.*</replacement>"
REQUIRED_FILES
"${CMAKE_CURRENT_SOURCE_DIR}/.clang-format")
endif ()
# add target for tidying with cmake-format
if(NOT META_NO_TIDY AND CMAKE_FORMAT_ENABLED AND FORMATABLE_FILES_CMAKE)
if (NOT META_NO_TIDY AND CMAKE_FORMAT_ENABLED AND FORMATABLE_FILES_CMAKE)
find_program(CMAKE_FORMAT_BIN cmake-format)
if(NOT CMAKE_FORMAT_BIN)
if (NOT CMAKE_FORMAT_BIN)
message(FATAL_ERROR "Unable to add tidy target; cmake-format not found")
endif()
endif ()
if (NOT META_CMAKE_FORMAT_OPTIONS)
set(META_CMAKE_FORMAT_OPTIONS
--tab-size=4 --separate-ctrl-name-with-space=True --line-width=125
)
endif()
set(META_CMAKE_FORMAT_OPTIONS --tab-size=4 --separate-ctrl-name-with-space=True --line-width=125)
endif ()
add_custom_target("${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_cmake_tidy"
COMMAND "${CMAKE_FORMAT_BIN}" --in-place ${META_CMAKE_FORMAT_OPTIONS} ${FORMATABLE_FILES_CMAKE}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Tidying ${META_PROJECT_NAME} sources using cmake-format"
DEPENDS "${FORMATABLE_FILES_CMAKE}"
)
if(NOT TARGET tidy)
COMMAND "${CMAKE_FORMAT_BIN}" --in-place ${META_CMAKE_FORMAT_OPTIONS} ${FORMATABLE_FILES_CMAKE}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Tidying ${META_PROJECT_NAME} sources using cmake-format"
DEPENDS "${FORMATABLE_FILES_CMAKE}")
if (NOT TARGET tidy)
add_custom_target(tidy)
endif()
endif ()
add_dependencies(tidy "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_cmake_tidy")
endif()
endif ()
# add target for static code analysis using clang-tidy
if(NOT META_NO_STATIC_ANALYSIS AND FORMATABLE_FILES)
if (NOT META_NO_STATIC_ANALYSIS AND FORMATABLE_FILES)
option(CLANG_TIDY_ENABLED "enables creation of static-check target using clang-tidy" OFF)
set(CLANG_TIDY_CHECKS "" CACHE STRING "-*,clang-analyzer-*,cppcoreguidelines-*,modernize-*,performance-*,portability-*,readability-*,android-*")
if(CLANG_TIDY_ENABLED)
set(CLANG_TIDY_CHECKS ""
CACHE STRING
"-*,clang-analyzer-*,cppcoreguidelines-*,modernize-*,performance-*,portability-*,readability-*,android-*")
if (CLANG_TIDY_ENABLED)
find_program(CLANG_TIDY_BIN clang-tidy)
if(NOT CLANG_TIDY_BIN)
if (NOT CLANG_TIDY_BIN)
message(FATAL_ERROR "Unable to add tidy target; clang-tidy not found")
endif()
endif ()
set(CLANG_TIDY_DEPENDS ${FORMATABLE_FILES})
# compose options for clang-tidy
set(CLANG_TIDY_OPTIONS
-checks="${CLANG_TIDY_CHECKS}"
-header-filter="^${META_PROJECT_NAME}/"
)
if(EXISTS "${CLANG_FORMAT_RULES}")
set(CLANG_TIDY_OPTIONS -checks="${CLANG_TIDY_CHECKS}" -header-filter="^${META_PROJECT_NAME}/")
if (EXISTS "${CLANG_FORMAT_RULES}")
list(APPEND CLANG_TIDY_OPTIONS "-format-style=file")
list(APPEND CLANG_TIDY_DPENDS "${CMAKE_CURRENT_SOURCE_DIR}/.clang-format")
endif()
endif ()
# compose CXX flags for clang-tidy
set(CLANG_TIDY_CXX_FLAGS "")
if(NOT META_HEADER_ONLY_LIB)
if (NOT META_HEADER_ONLY_LIB)
# deduce flags from target
set(TARGET_NAME ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX})
if(NOT BUILD_SHARED_LIBS AND BUILD_STATIC_LIBS)
if (NOT BUILD_SHARED_LIBS AND BUILD_STATIC_LIBS)
set(TARGET_NAME "${TARGET_NAME}_static")
endif()
endif ()
# set c++ standard
list(APPEND CLANG_TIDY_CXX_FLAGS "-std=c++$<TARGET_PROPERTY:${TARGET_NAME},CXX_STANDARD>")
# add compile flags
@ -365,112 +382,105 @@ if(NOT META_NO_STATIC_ANALYSIS AND FORMATABLE_FILES)
# add include directories
set(PROP "$<TARGET_PROPERTY:${TARGET_NAME},INCLUDE_DIRECTORIES>")
list(APPEND CLANG_TIDY_CXX_FLAGS "$<$<BOOL:${PROP}>:-I$<JOIN:${PROP},$<SEMICOLON>-I>>")
else()
else ()
# set at least c++ standard for header-only libs
list(APPEND CLANG_TIDY_CXX_FLAGS "-std=c++${META_CXX_STANDARD}")
endif()
endif ()
# add a custom command for each source file
set(CLANG_TIDY_SYMBOLIC_OUTPUT_FILES "")
foreach(FILE ${FORMATABLE_FILES})
foreach (FILE ${FORMATABLE_FILES})
# skip header files
if(${FILE} MATCHES ".*\.h")
if (${FILE} MATCHES ".*\.h")
continue()
endif()
endif ()
# use symbolic output file since there's no actual output file (we're just interested in the log)
set(SYMBOLIC_OUTPUT_FILE "${FILE}.clang-tidy-output")
list(APPEND CLANG_TIDY_SYMBOLIC_OUTPUT_FILES "${SYMBOLIC_OUTPUT_FILE}")
add_custom_command(OUTPUT "${SYMBOLIC_OUTPUT_FILE}"
COMMAND "${CLANG_TIDY_BIN}" ${FILE} -- ${CLANG_TIDY_CXX_FLAGS}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Linting ${FILE} using clang-tidy"
DEPENDS "${FILE}"
COMMAND_EXPAND_LISTS
VERBATIM
)
endforeach()
COMMAND "${CLANG_TIDY_BIN}" ${FILE} -- ${CLANG_TIDY_CXX_FLAGS}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Linting ${FILE} using clang-tidy"
DEPENDS "${FILE}" COMMAND_EXPAND_LISTS
VERBATIM)
endforeach ()
# mark all symbolic output files actually as symbolic
set_source_files_properties(${CLANG_TIDY_SYMBOLIC_OUTPUT_FILES}
PROPERTIES SYMBOLIC YES
)
set_source_files_properties(${CLANG_TIDY_SYMBOLIC_OUTPUT_FILES} PROPERTIES SYMBOLIC YES)
# add targets
add_custom_target("${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static_check"
DEPENDS ${CLANG_TIDY_SYMBOLIC_OUTPUT_FILES}
COMMENT "Linting ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} sources using clang-tidy"
)
if(NOT TARGET static-check)
DEPENDS ${CLANG_TIDY_SYMBOLIC_OUTPUT_FILES}
COMMENT "Linting ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} sources using clang-tidy")
if (NOT TARGET static-check)
add_custom_target(static-check)
endif()
endif ()
add_dependencies(static-check "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static_check")
endif()
endif()
endif ()
endif ()
# add autotools-style check target
if(NOT TARGET check)
if (NOT TARGET check)
set(CMAKE_CTEST_COMMAND ${CMAKE_CTEST_COMMAND} -V)
add_custom_target(check
COMMAND ${CMAKE_CTEST_COMMAND}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
DEPENDS "${CHECK_TARGET_DEPENDS}"
)
endif()
COMMAND ${CMAKE_CTEST_COMMAND}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
DEPENDS "${CHECK_TARGET_DEPENDS}")
endif ()
# enable source code based coverage analysis using clang
option(CLANG_SOURCE_BASED_COVERAGE_ENABLED "enables creation of coverage targets for source-based coverage with clang" OFF)
if(CLANG_SOURCE_BASED_COVERAGE_ENABLED)
if(NOT CMAKE_HOST_UNIX OR NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
if (CLANG_SOURCE_BASED_COVERAGE_ENABLED)
if (NOT CMAKE_HOST_UNIX
OR NOT
"${CMAKE_CXX_COMPILER_ID}"
STREQUAL
"Clang")
message(FATAL_ERROR "Source-based coverage only available under UNIX with Clang")
endif()
if(NOT META_PROJECT_TYPE STREQUAL "application" AND DISABLE_SHARED_LIBS)
endif ()
if (NOT META_PROJECT_TYPE STREQUAL "application" AND DISABLE_SHARED_LIBS)
message(FATAL_ERROR "Source-based coverage not available when only building static libs")
endif()
endif ()
set(CLANG_SOURCE_BASED_COVERAGE_AVAILABLE YES)
set(CLANG_SOURCE_BASED_COVERAGE_FLAGS -fprofile-instr-generate -fcoverage-mapping)
list(APPEND META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS ${CLANG_SOURCE_BASED_COVERAGE_FLAGS})
list(APPEND META_PRIVATE_STATIC_LIB_COMPILE_OPTIONS ${CLANG_SOURCE_BASED_COVERAGE_FLAGS})
list(APPEND META_ADDITIONAL_SHARED_LINK_FLAGS ${CLANG_SOURCE_BASED_COVERAGE_FLAGS})
list(APPEND META_ADDITIONAL_STATIC_LINK_FLAGS ${CLANG_SOURCE_BASED_COVERAGE_FLAGS})
endif()
endif ()
# configure creation of install targets
if(NOT META_NO_INSTALL_TARGETS)
# install targets have not been disabled on project level
# check whether install targets are disabled by the user
# this might be useful since install targets seem to cause problems under MacOS
if (NOT META_NO_INSTALL_TARGETS)
# install targets have not been disabled on project level check whether install targets are disabled by the user this
# might be useful since install targets seem to cause problems under MacOS
option(ENABLE_INSTALL_TARGETS "enables creation of install targets" ON)
endif()
endif ()
# add install target for extra files
if(NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS)
foreach(EXTRA_FILE ${EXTRA_FILES})
if (NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS)
foreach (EXTRA_FILE ${EXTRA_FILES})
get_filename_component(EXTRA_DIR ${EXTRA_FILE} DIRECTORY)
install(
FILES ${EXTRA_FILE}
DESTINATION "share/${META_PROJECT_NAME}/${EXTRA_DIR}"
COMPONENT extra-files
)
endforeach()
if(NOT TARGET install-extra-files)
install(FILES ${EXTRA_FILE} DESTINATION "share/${META_PROJECT_NAME}/${EXTRA_DIR}" COMPONENT extra-files)
endforeach ()
if (NOT TARGET install-extra-files)
add_custom_target(install-extra-files
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=extra-files -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
endif()
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=extra-files -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif ()
endif ()
# determine library directory suffix
# note: Applications might be built as libraries under some platforms (eg. Android). Hence this is part of BasicConfig and not LibraryConfig.
# determine library directory suffix note: Applications might be built as libraries under some platforms (eg. Android). Hence
# this is part of BasicConfig and not LibraryConfig.
set(LIB_SUFFIX "" CACHE STRING "specifies the general suffix for the library directory")
set(SELECTED_LIB_SUFFIX "${LIB_SUFFIX}")
set(LIB_SUFFIX_32 "" CACHE STRING "specifies the suffix for the library directory to be used when building 32-bit library")
set(LIB_SUFFIX_64 "" CACHE STRING "specifies the suffix for the library directory to be used when building 64-bit library")
if(LIB_SUFFIX_64 AND CMAKE_SIZEOF_VOID_P MATCHES "8")
if (LIB_SUFFIX_64 AND CMAKE_SIZEOF_VOID_P MATCHES "8")
set(SELECTED_LIB_SUFFIX "${LIB_SUFFIX_64}")
elseif(LIB_SUFFIX_32 AND CMAKE_SIZEOF_VOID_P MATCHES "4")
elseif (LIB_SUFFIX_32 AND CMAKE_SIZEOF_VOID_P MATCHES "4")
set(SELECTED_LIB_SUFFIX "${LIB_SUFFIX_32}")
endif()
endif ()
set(BASIC_PROJECT_CONFIG_DONE YES)

View File

@ -1,64 +1,69 @@
# before including this module, all relevant variables must be set
# just include this module as last one since nothing should depend on it
# before including this module, all relevant variables must be set just include this module as last one since nothing should
# depend on it
if(NOT TARGET_CONFIG_DONE)
if (NOT TARGET_CONFIG_DONE)
message(FATAL_ERROR "Before including the ConfigHeader module, the AppTarget/LibraryTarget module must be included.")
endif()
endif ()
# find config.h template
include(TemplateFinder)
find_template_file("config.h" CPP_UTILITIES CONFIG_H_TEMPLATE_FILE)
# create list of dependency versions present at link time (one list for shared library and another for
# the static library since the lists might differ)
# create list of dependency versions present at link time (one list for shared library and another for the static library
# since the lists might differ)
include(ListToString)
foreach(LINKAGE IN ITEMS "" "STATIC_")
foreach (LINKAGE IN ITEMS "" "STATIC_")
unset(DEPENCENCY_VERSIONS)
unset(${LINKAGE}DEPENCENCY_VERSIONS_ARRAY)
# iterate through public and private libraries of shared/static library
foreach(DEPENDENCY IN LISTS PUBLIC_${LINKAGE}LIBRARIES PRIVATE_${LINKAGE}LIBRARIES)
if(TARGET ${DEPENDENCY})
foreach (DEPENDENCY IN LISTS PUBLIC_${LINKAGE}LIBRARIES PRIVATE_${LINKAGE}LIBRARIES)
if (TARGET ${DEPENDENCY})
unset(DEPENDENCY_DISPLAY_NAME)
unset(DEPENDENCY_VER)
# find version and display name for target
if(DEPENDENCY MATCHES "(Static)?Qt5::([A-Za-z0-9]+)")
if (DEPENDENCY MATCHES "(Static)?Qt5::([A-Za-z0-9]+)")
# read meta-data of Qt module
set(DEPENDENCY_MODULE_NAME "${CMAKE_MATCH_2}")
set(DEPENDENCY_DISPLAY_NAME "Qt ${DEPENDENCY_MODULE_NAME}")
set(DEPENDENCY_VER "${Qt5${DEPENDENCY_MODULE_NAME}_VERSION_STRING}")
elseif(${DEPENDENCY}_varname)
elseif (${DEPENDENCY}_varname)
# read meta-data of one of my own libraries
set(DEPENDENCY_VARNAME "${${DEPENDENCY}_varname}")
set(DEPENDENCY_DISPLAY_NAME "${DEPENDENCY}")
if(${DEPENDENCY_VARNAME}_DISPLAY_NAME)
if (${DEPENDENCY_VARNAME}_DISPLAY_NAME)
set(DEPENDENCY_DISPLAY_NAME "${${DEPENDENCY_VARNAME}_DISPLAY_NAME}")
endif()
endif ()
set(DEPENDENCY_VER "${${DEPENDENCY_VARNAME}_VERSION}")
endif()
endif ()
# FIXME: provide meta-data for other libs, too
if(DEPENDENCY_VER AND NOT "${DEPENDENCY_VER}" STREQUAL "DEPENDENCY_VER-NOTFOUND")
if (DEPENDENCY_VER
AND NOT
"${DEPENDENCY_VER}"
STREQUAL
"DEPENDENCY_VER-NOTFOUND")
list(APPEND DEPENCENCY_VERSIONS "${DEPENDENCY_DISPLAY_NAME}: ${DEPENDENCY_VER}")
endif()
endif()
endforeach()
if(DEPENCENCY_VERSIONS)
endif ()
endif ()
endforeach ()
if (DEPENCENCY_VERSIONS)
list_to_string("," " \\\n \"" "\"" "${DEPENCENCY_VERSIONS}" ${LINKAGE}DEPENCENCY_VERSIONS_ARRAY)
endif()
endforeach()
endif ()
endforeach ()
# add configuration header
configure_file(
"${CONFIG_H_TEMPLATE_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/resources/config.h"
)
configure_file("${CONFIG_H_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/resources/config.h")
# ensure generated include files can be included via #include "resources/config.h"
if(NOT META_HEADER_ONLY_LIB)
foreach(TARGET_NAME ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib)
if(TARGET ${TARGET_NAME})
if (NOT META_HEADER_ONLY_LIB)
foreach (TARGET_NAME
${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests
${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib)
if (TARGET ${TARGET_NAME})
target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
endif()
endforeach()
endif()
endif ()
endforeach ()
endif ()

View File

@ -1,11 +1,11 @@
if(NOT BASIC_PROJECT_CONFIG_DONE)
if (NOT BASIC_PROJECT_CONFIG_DONE)
message(FATAL_ERROR "Before including the Doxygen module, the BasicConfig module must be included.")
endif()
endif ()
option(NO_DOXYGEN "whether creation of Doxygen targets is disabled (enabled by default)" OFF)
if(NO_DOXYGEN)
if (NO_DOXYGEN)
return()
endif()
endif ()
# find doxygen.h template
include(TemplateFinder)
@ -15,31 +15,41 @@ find_template_file("doxygen" CPP_UTILITIES DOXYGEN_TEMPLATE_FILE)
find_program(DOXYGEN_BIN doxygen)
find_program(PERL_BIN perl)
find_program(DIA_BIN dia)
if(DIA_BIN)
if (DIA_BIN)
set(HAVE_DIA "YES")
else()
else ()
set(HAVE_DIA "NO")
endif()
endif ()
find_program(DOT_BIN dot)
if(DOT_BIN)
if (DOT_BIN)
set(HAVE_DOT "YES")
else()
else ()
set(HAVE_DOT "NO")
endif()
endif ()
if(NOT DOXYGEN_BIN)
message(WARNING "Doxygen not found, unable to add target for generating API documentation for ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}")
if (NOT DOXYGEN_BIN)
message(
WARNING
"Doxygen not found, unable to add target for generating API documentation for ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}"
)
return()
endif()
endif ()
# load cached configuration and other variables
set(DOXY_LANGUAGE "English" CACHE STRING "specifies the language of the API documentation generated with Doxygen")
set(DOXY_CUSTOM_CONFIG "" CACHE STRING "specifies extra options for Doxygen")
set(DOXY_NUMBER "${META_APP_VERSION}")
set(DOXY_INPUT_FILES
${HEADER_FILES} ${SRC_FILES} ${TEST_HEADER_FILES} ${TEST_SRC_FILES} ${WIDGETS_HEADER_FILES} ${WIDGETS_SRC_FILES}
${QML_HEADER_FILES} ${QML_SRC_FILES} ${DOC_FILES} ${DOC_ONLY_FILES}
)
${HEADER_FILES}
${SRC_FILES}
${TEST_HEADER_FILES}
${TEST_SRC_FILES}
${WIDGETS_HEADER_FILES}
${WIDGETS_SRC_FILES}
${QML_HEADER_FILES}
${QML_SRC_FILES}
${DOC_FILES}
${DOC_ONLY_FILES})
set(DOXY_PATH_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/")
list(GET DOC_FILES 0 DOXY_MAIN_PAGE_FILE)
set(DOXY_MAIN_PAGE_FILE "${DOXY_PATH_PREFIX}${DOXY_MAIN_PAGE_FILE}")
@ -49,32 +59,30 @@ include(ListToString)
list_to_string(" " "\"${DOXY_PATH_PREFIX}" "\"" "${DOXY_INPUT_FILES}" DOXY_INPUT_FILES_WHITESPACE_SEPARATED)
# generate Doxygen configuration
configure_file(
"${DOXYGEN_TEMPLATE_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/doxygen.config"
)
configure_file("${DOXYGEN_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/doxygen.config")
# add target for generating API documentation
add_custom_target("${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_apidoc"
COMMAND "${DOXYGEN_BIN}" "${CMAKE_CURRENT_BINARY_DIR}/doxygen.config"
)
if(NOT TARGET apidoc)
COMMAND "${DOXYGEN_BIN}" "${CMAKE_CURRENT_BINARY_DIR}/doxygen.config")
if (NOT TARGET apidoc)
add_custom_target(apidoc)
endif()
endif ()
add_dependencies(apidoc "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_apidoc")
# add install target for API documentation
if(NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS)
if (NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS)
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/api-doc"
DESTINATION "share/${META_PROJECT_NAME}"
COMPONENT api-doc
OPTIONAL
)
if(NOT TARGET install-api-doc)
OPTIONAL)
if (NOT TARGET install-api-doc)
add_custom_target(install-api-doc
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=api-doc -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
endif()
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=api-doc -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif ()
endif ()
message(STATUS "Generating target for generating API documentation for ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} with Doxygen")
message(
STATUS
"Generating target for generating API documentation for ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} with Doxygen"
)

View File

@ -1,19 +1,22 @@
cmake_minimum_required(VERSION 3.3.0 FATAL_ERROR)
if(NOT BASIC_PROJECT_CONFIG_DONE)
if (NOT BASIC_PROJECT_CONFIG_DONE)
message(FATAL_ERROR "Before including the LibraryTarget module, the BasicConfig module must be included.")
endif()
if(TARGET_CONFIG_DONE)
endif ()
if (TARGET_CONFIG_DONE)
message(FATAL_ERROR "Can not include LibraryTarget module when targets are already configured.")
endif()
endif ()
# check whether project type is set correctly
if(("${META_PROJECT_TYPE}" STREQUAL "plugin") OR ("${META_PROJECT_TYPE}" STREQUAL "qtplugin"))
if (("${META_PROJECT_TYPE}" STREQUAL "plugin") OR ("${META_PROJECT_TYPE}" STREQUAL "qtplugin"))
set(META_IS_PLUGIN YES)
endif()
if((NOT "${META_PROJECT_TYPE}" STREQUAL "library") AND (NOT "${META_PROJECT_TYPE}" STREQUAL "") AND NOT META_IS_PLUGIN)
message(FATAL_ERROR "The LibraryTarget CMake module is intended to be used for building library projects only (and not for applications).")
endif()
endif ()
if ((NOT "${META_PROJECT_TYPE}" STREQUAL "library") AND (NOT "${META_PROJECT_TYPE}" STREQUAL "") AND NOT META_IS_PLUGIN)
message(
FATAL_ERROR
"The LibraryTarget CMake module is intended to be used for building library projects only (and not for applications)."
)
endif ()
# includes for configure_package_config_file, write_basic_package_version_file and find_template_file
include(CMakePackageConfigHelpers)
@ -28,507 +31,480 @@ set(CMAKE_MODULE_INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/share/${META_PROJE
set(CMAKE_CONFIG_INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/share/${META_PROJECT_NAME}/cmake")
# remove library prefix when building with mingw-w64 (just for consistency with qmake)
if(MINGW)
if (MINGW)
set(CMAKE_SHARED_LIBRARY_PREFIX "")
endif(MINGW)
endif (MINGW)
# set the windows extension to "dll", this is required by the mingw-w64 specific WindowsResources module
if(MINGW)
if (MINGW)
set(WINDOWS_EXT "dll")
endif(MINGW)
endif (MINGW)
# set compile definitions
if(NOT META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS)
set(META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS ${META_PUBLIC_COMPILE_DEFINITIONS} ${META_ADDITIONAL_PUBLIC_SHARED_COMPILE_DEFINITIONS})
endif()
if(NOT META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS)
set(META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS ${META_PRIVATE_COMPILE_DEFINITIONS} ${META_ADDITIONAL_PRIVATE_SHARED_COMPILE_DEFINITIONS})
endif()
if(NOT META_PUBLIC_STATIC_LIB_COMPILE_DEFINITIONS)
set(META_PUBLIC_STATIC_LIB_COMPILE_DEFINITIONS ${META_PUBLIC_COMPILE_DEFINITIONS} ${META_PROJECT_VARNAME_UPPER}_STATIC ${META_ADDITIONAL_PUBLIC_STATIC_COMPILE_DEFINITIONS})
endif()
if(NOT META_PRIVATE_STATIC_LIB_COMPILE_DEFINITIONS)
set(META_PRIVATE_STATIC_LIB_COMPILE_DEFINITIONS ${META_PRIVATE_COMPILE_DEFINITIONS} ${META_ADDITIONAL_PRIVATE_STATIC_COMPILE_DEFINITIONS})
endif()
if (NOT META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS)
set(META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS ${META_PUBLIC_COMPILE_DEFINITIONS}
${META_ADDITIONAL_PUBLIC_SHARED_COMPILE_DEFINITIONS})
endif ()
if (NOT META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS)
set(META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS ${META_PRIVATE_COMPILE_DEFINITIONS}
${META_ADDITIONAL_PRIVATE_SHARED_COMPILE_DEFINITIONS})
endif ()
if (NOT META_PUBLIC_STATIC_LIB_COMPILE_DEFINITIONS)
set(META_PUBLIC_STATIC_LIB_COMPILE_DEFINITIONS
${META_PUBLIC_COMPILE_DEFINITIONS}
${META_PROJECT_VARNAME_UPPER}_STATIC
${META_ADDITIONAL_PUBLIC_STATIC_COMPILE_DEFINITIONS})
endif ()
if (NOT META_PRIVATE_STATIC_LIB_COMPILE_DEFINITIONS)
set(META_PRIVATE_STATIC_LIB_COMPILE_DEFINITIONS ${META_PRIVATE_COMPILE_DEFINITIONS}
${META_ADDITIONAL_PRIVATE_STATIC_COMPILE_DEFINITIONS})
endif ()
# add global library-specific header
find_template_file("global.h" CPP_UTILITIES GLOBAL_H_TEMPLATE_FILE)
if("${META_PROJECT_NAME}" STREQUAL "c++utilities")
if ("${META_PROJECT_NAME}" STREQUAL "c++utilities")
set(GENERAL_GLOBAL_H_INCLUDE_PATH "\"./application/global.h\"")
else()
else ()
set(GENERAL_GLOBAL_H_INCLUDE_PATH "<c++utilities/application/global.h>")
endif()
configure_file(
"${GLOBAL_H_TEMPLATE_FILE}"
"${CMAKE_CURRENT_SOURCE_DIR}/global.h" # simply add this to source to ease inclusion
NEWLINE_STYLE UNIX # since this goes to sources ensure consistency
)
endif ()
configure_file("${GLOBAL_H_TEMPLATE_FILE}"
"${CMAKE_CURRENT_SOURCE_DIR}/global.h" # simply add this to source to ease inclusion
NEWLINE_STYLE UNIX # since this goes to sources ensure consistency
)
list(APPEND HEADER_FILES global.h)
# determine SOVERSION
if(NOT META_SOVERSION AND NOT META_IS_PLUGIN)
if(META_VERSION_EXACT_SONAME)
if (NOT META_SOVERSION AND NOT META_IS_PLUGIN)
if (META_VERSION_EXACT_SONAME)
set(META_SOVERSION "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}")
else()
else ()
set(META_SOVERSION "${META_VERSION_MAJOR}")
endif()
endif()
endif ()
endif ()
message(STATUS "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}: BUILD_SHARED_LIBS=${BUILD_SHARED_LIBS}")
# define relevant files
set(ALL_FILES ${HEADER_FILES} ${SRC_FILES} ${GENERATED_DBUS_FILES} ${WIDGETS_FILES} ${QML_FILES} ${RES_FILES} ${WINDOWS_ICON_PATH})
if(NOT BUILTIN_TRANSLATIONS)
set(ALL_FILES
${HEADER_FILES}
${SRC_FILES}
${GENERATED_DBUS_FILES}
${WIDGETS_FILES}
${QML_FILES}
${RES_FILES}
${WINDOWS_ICON_PATH})
if (NOT BUILTIN_TRANSLATIONS)
list(APPEND ALL_FILES ${QM_FILES})
endif()
endif ()
# determine include path used when building the project itself
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include")
if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include")
# use special include directory if available
set(TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include")
else()
else ()
# use the project folder itself
set(TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/..")
endif()
endif ()
# add target for building the library
if(BUILD_SHARED_LIBS)
if(STATIC_LIBRARY_LINKAGE)
if (BUILD_SHARED_LIBS)
if (STATIC_LIBRARY_LINKAGE)
set(ACTUAL_ADDITIONAL_LINK_FLAGS ${META_ADDITIONAL_STATIC_LINK_FLAGS})
else()
else ()
set(ACTUAL_ADDITIONAL_LINK_FLAGS ${META_ADDITIONAL_SHARED_LINK_FLAGS})
endif()
if(META_IS_PLUGIN)
endif ()
if (META_IS_PLUGIN)
set(META_SHARED_OBJECT_TYPE MODULE)
else()
else ()
set(META_SHARED_OBJECT_TYPE SHARED)
endif()
endif ()
# add library to be created, set libs to link against, set version and C++ standard
if(META_HEADER_ONLY_LIB)
if (META_HEADER_ONLY_LIB)
add_library(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} INTERFACE)
target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
INTERFACE ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}" "${PRIVATE_LIBRARIES}"
)
target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
INTERFACE
$<BUILD_INTERFACE:${TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE}>
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}>
${PUBLIC_SHARED_INCLUDE_DIRS}
)
INTERFACE ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}" "${PRIVATE_LIBRARIES}")
target_include_directories(
${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
INTERFACE $<BUILD_INTERFACE:${TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE}>
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> ${PUBLIC_SHARED_INCLUDE_DIRS})
target_compile_definitions(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
INTERFACE "${META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS}" "${META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS}"
)
INTERFACE
"${META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS}"
"${META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS}")
target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
INTERFACE "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}" "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}"
)
else()
INTERFACE "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}"
"${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}")
else ()
add_library(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} ${META_SHARED_OBJECT_TYPE} ${ALL_FILES})
target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
PUBLIC ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}"
PRIVATE "${PRIVATE_LIBRARIES}"
)
PUBLIC ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}"
PRIVATE "${PRIVATE_LIBRARIES}")
target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
PUBLIC
$<BUILD_INTERFACE:${TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE}>
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}>
${PUBLIC_SHARED_INCLUDE_DIRS}
PRIVATE
"${PRIVATE_SHARED_INCLUDE_DIRS}"
)
PUBLIC $<BUILD_INTERFACE:${TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE}>
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> ${PUBLIC_SHARED_INCLUDE_DIRS}
PRIVATE "${PRIVATE_SHARED_INCLUDE_DIRS}")
target_compile_definitions(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS}"
PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS}"
)
PUBLIC
"${META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS}"
PRIVATE
"${META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS}")
target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}"
PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}"
)
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} PROPERTIES
VERSION "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}"
SOVERSION "${META_SOVERSION}"
CXX_STANDARD "${META_CXX_STANDARD}"
LINK_SEARCH_START_STATIC ${STATIC_LINKAGE}
LINK_SEARCH_END_STATIC ${STATIC_LINKAGE}
AUTOGEN_TARGET_DEPENDS "${AUTOGEN_DEPS}"
)
endif()
endif()
PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}"
PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}")
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
PROPERTIES VERSION
"${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}"
SOVERSION
"${META_SOVERSION}"
CXX_STANDARD
"${META_CXX_STANDARD}"
LINK_SEARCH_START_STATIC
${STATIC_LINKAGE}
LINK_SEARCH_END_STATIC
${STATIC_LINKAGE}
AUTOGEN_TARGET_DEPENDS
"${AUTOGEN_DEPS}")
endif ()
endif ()
# add target for building a static version of the library
if(BUILD_STATIC_LIBS)
if (BUILD_STATIC_LIBS)
# add library to be created, set required libs, set version and C++ standard
if(META_HEADER_ONLY_LIB)
if (META_HEADER_ONLY_LIB)
add_library(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static INTERFACE)
target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
INTERFACE ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_STATIC_LIBRARIES}" "${PRIVATE_STATIC_LIBRARIES}"
)
target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
INTERFACE
$<BUILD_INTERFACE:${TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE}>
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}>
${PUBLIC_STATIC_INCLUDE_DIRS}
)
INTERFACE ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_STATIC_LIBRARIES}"
"${PRIVATE_STATIC_LIBRARIES}")
target_include_directories(
${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
INTERFACE $<BUILD_INTERFACE:${TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE}>
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> ${PUBLIC_STATIC_INCLUDE_DIRS})
target_compile_definitions(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
INTERFACE "${META_PUBLIC_STATIC_LIB_COMPILE_DEFINITIONS}" "${META_PRIVATE_STATIC_LIB_COMPILE_DEFINITIONS}"
)
INTERFACE
"${META_PUBLIC_STATIC_LIB_COMPILE_DEFINITIONS}"
"${META_PRIVATE_STATIC_LIB_COMPILE_DEFINITIONS}")
target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
INTERFACE "${META_PUBLIC_STATIC_LIB_COMPILE_OPTIONS}" "${META_PRIVATE_STATIC_LIB_COMPILE_OPTIONS}"
)
else()
INTERFACE "${META_PUBLIC_STATIC_LIB_COMPILE_OPTIONS}"
"${META_PRIVATE_STATIC_LIB_COMPILE_OPTIONS}")
else ()
add_library(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static STATIC ${ALL_FILES})
target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
PUBLIC "${PUBLIC_STATIC_LIBRARIES}" "${PRIVATE_STATIC_LIBRARIES}"
)
PUBLIC "${PUBLIC_STATIC_LIBRARIES}" "${PRIVATE_STATIC_LIBRARIES}")
target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
PUBLIC
$<BUILD_INTERFACE:${TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE}>
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}>
${PUBLIC_STATIC_INCLUDE_DIRS}
PRIVATE
"${PRIVATE_STATIC_INCLUDE_DIRS}"
)
PUBLIC $<BUILD_INTERFACE:${TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE}>
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> ${PUBLIC_STATIC_INCLUDE_DIRS}
PRIVATE "${PRIVATE_STATIC_INCLUDE_DIRS}")
target_compile_definitions(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
PUBLIC "${META_PUBLIC_STATIC_LIB_COMPILE_DEFINITIONS}"
PRIVATE "${META_PRIVATE_STATIC_LIB_COMPILE_DEFINITIONS}"
)
PUBLIC
"${META_PUBLIC_STATIC_LIB_COMPILE_DEFINITIONS}"
PRIVATE
"${META_PRIVATE_STATIC_LIB_COMPILE_DEFINITIONS}")
target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
PUBLIC "${META_PUBLIC_STATIC_LIB_COMPILE_OPTIONS}"
PRIVATE "${META_PRIVATE_STATIC_LIB_COMPILE_OPTIONS}"
)
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static PROPERTIES
VERSION "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}"
SOVERSION "${META_SOVERSION}"
OUTPUT_NAME "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}"
CXX_STANDARD "${META_CXX_STANDARD}"
AUTOGEN_TARGET_DEPENDS "${AUTOGEN_DEPS}"
)
endif()
foreach(DEPENDENCY ${PUBLIC_STATIC_LIBRARIES} ${PRIVATE_STATIC_LIBRARIES})
if(NOT ${DEPENDENCY} IN_LIST META_PUBLIC_STATIC_LIB_DEPENDS)
PUBLIC "${META_PUBLIC_STATIC_LIB_COMPILE_OPTIONS}"
PRIVATE "${META_PRIVATE_STATIC_LIB_COMPILE_OPTIONS}")
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
PROPERTIES VERSION
"${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}"
SOVERSION
"${META_SOVERSION}"
OUTPUT_NAME
"${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}"
CXX_STANDARD
"${META_CXX_STANDARD}"
AUTOGEN_TARGET_DEPENDS
"${AUTOGEN_DEPS}")
endif ()
foreach (DEPENDENCY ${PUBLIC_STATIC_LIBRARIES} ${PRIVATE_STATIC_LIBRARIES})
if (NOT ${DEPENDENCY} IN_LIST META_PUBLIC_STATIC_LIB_DEPENDS)
list(APPEND META_PRIVATE_STATIC_LIB_DEPENDS ${DEPENDENCY})
endif()
endforeach()
endif()
endif ()
endforeach ()
endif ()
# Qt Creator does not show INTERFACE_SOURCES in project tree, so create a custom target as workaround
if(META_HEADER_ONLY_LIB)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/headeronly.cpp" "// not belonging to a real target, only for header-only lib files showing up in Qt Creator")
if (META_HEADER_ONLY_LIB)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/headeronly.cpp"
"// not belonging to a real target, only for header-only lib files showing up in Qt Creator")
add_library(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_interface_sources_for_qtcreator
EXCLUDE_FROM_ALL
"${CMAKE_CURRENT_BINARY_DIR}/headeronly.cpp" ${HEADER_FILES}
)
EXCLUDE_FROM_ALL
"${CMAKE_CURRENT_BINARY_DIR}/headeronly.cpp"
${HEADER_FILES})
target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_interface_sources_for_qtcreator
INTERFACE
$<BUILD_INTERFACE:${TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE}>
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}>
${PUBLIC_SHARED_INCLUDE_DIRS}
)
INTERFACE $<BUILD_INTERFACE:${TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE}>
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> ${PUBLIC_SHARED_INCLUDE_DIRS})
target_compile_definitions(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_interface_sources_for_qtcreator
INTERFACE "${META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS}" "${META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS}"
)
target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_interface_sources_for_qtcreator
INTERFACE "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}" "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}"
)
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_interface_sources_for_qtcreator PROPERTIES
VERSION "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}"
SOVERSION "${META_SOVERSION}"
CXX_STANDARD "${META_CXX_STANDARD}"
AUTOGEN_TARGET_DEPENDS "${AUTOGEN_DEPS}"
)
endif()
INTERFACE
"${META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS}"
"${META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS}")
target_compile_options(
${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_interface_sources_for_qtcreator
INTERFACE "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}" "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}")
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_interface_sources_for_qtcreator
PROPERTIES VERSION
"${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}"
SOVERSION
"${META_SOVERSION}"
CXX_STANDARD
"${META_CXX_STANDARD}"
AUTOGEN_TARGET_DEPENDS
"${AUTOGEN_DEPS}")
endif ()
# create the CMake package config file from template
find_template_file("Config.cmake" CPP_UTILITIES CONFIG_TEMPLATE_FILE)
configure_package_config_file(
"${CONFIG_TEMPLATE_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION
"${CMAKE_CONFIG_INSTALL_DESTINATION}"
PATH_VARS
CMAKE_MODULE_INSTALL_DESTINATION
CMAKE_CONFIG_INSTALL_DESTINATION
HEADER_INSTALL_DESTINATION
BIN_INSTALL_DESTINATION
LIB_INSTALL_DESTINATION
)
list(APPEND CMAKE_CONFIG_FILES
"${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}Config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}ConfigVersion.cmake"
)
if(BUILD_SHARED_LIBS)
configure_package_config_file("${CONFIG_TEMPLATE_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION
"${CMAKE_CONFIG_INSTALL_DESTINATION}"
PATH_VARS
CMAKE_MODULE_INSTALL_DESTINATION
CMAKE_CONFIG_INSTALL_DESTINATION
HEADER_INSTALL_DESTINATION
BIN_INSTALL_DESTINATION
LIB_INSTALL_DESTINATION)
list(APPEND CMAKE_CONFIG_FILES "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}Config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}ConfigVersion.cmake")
if (BUILD_SHARED_LIBS)
find_template_file("SharedConfig.cmake" CPP_UTILITIES SHARED_CONFIG_TEMPLATE_FILE)
configure_file(
"${SHARED_CONFIG_TEMPLATE_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}SharedConfig.cmake"
@ONLY
)
list(APPEND CMAKE_CONFIG_FILES
"${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}SharedConfig.cmake"
)
endif()
if(BUILD_STATIC_LIBS)
configure_file("${SHARED_CONFIG_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}SharedConfig.cmake"
@ONLY)
list(APPEND CMAKE_CONFIG_FILES "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}SharedConfig.cmake")
endif ()
if (BUILD_STATIC_LIBS)
find_template_file("StaticConfig.cmake" CPP_UTILITIES STATIC_CONFIG_TEMPLATE_FILE)
configure_file(
"${STATIC_CONFIG_TEMPLATE_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}StaticConfig.cmake"
@ONLY
)
list(APPEND CMAKE_CONFIG_FILES
"${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}StaticConfig.cmake"
)
endif()
configure_file("${STATIC_CONFIG_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}StaticConfig.cmake"
@ONLY)
list(APPEND CMAKE_CONFIG_FILES "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}StaticConfig.cmake")
endif ()
# write the CMake version config file
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}ConfigVersion.cmake
VERSION "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}"
COMPATIBILITY SameMajorVersion
)
write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}ConfigVersion.cmake
VERSION "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}"
COMPATIBILITY SameMajorVersion)
# create pkg-config file from template
find_template_file("template.pc" CPP_UTILITIES PKGCONFIG_TEMPLATE_FILE)
macro(depends_for_pc LIB_TYPE DEPENDS OUTPUT_VAR_PKGS OUTPUT_VAR_LIBS)
macro (depends_for_pc LIB_TYPE DEPENDS OUTPUT_VAR_PKGS OUTPUT_VAR_LIBS)
unset(${OUTPUT_VAR_PKGS})
unset(${OUTPUT_VAR_LIBS})
foreach(DEPENDENCY ${${DEPENDS}})
if("${DEPENDENCY}" STREQUAL "general")
foreach (DEPENDENCY ${${DEPENDS}})
if ("${DEPENDENCY}" STREQUAL "general")
continue()
endif()
string(REPLACE "::" "_" DEPENDENCY_VARNAME "${DEPENDENCY}")
if(PC_PKG_${LIB_TYPE}_${DEPENDENCY_VARNAME})
endif ()
string(REPLACE "::"
"_"
DEPENDENCY_VARNAME
"${DEPENDENCY}")
if (PC_PKG_${LIB_TYPE}_${DEPENDENCY_VARNAME})
set(${OUTPUT_VAR_PKGS} "${${OUTPUT_VAR_PKGS}} ${PC_PKG_${LIB_TYPE}_${DEPENDENCY_VARNAME}}")
else()
else ()
set(${OUTPUT_VAR_LIBS} "${${OUTPUT_VAR_LIBS}} ${DEPENDENCY}")
endif()
endforeach()
endmacro()
macro(compile_defs_for_pc LIB_TYPE)
foreach(COMPILE_DEFINITION ${META_PUBLIC_${LIB_TYPE}_LIB_COMPILE_DEFINITIONS})
endif ()
endforeach ()
endmacro ()
macro (compile_defs_for_pc LIB_TYPE)
foreach (COMPILE_DEFINITION ${META_PUBLIC_${LIB_TYPE}_LIB_COMPILE_DEFINITIONS})
set(META_COMPILE_DEFINITIONS_FOR_PC "${META_COMPILE_DEFINITIONS_FOR_PC} -D${COMPILE_DEFINITION}")
endforeach()
endmacro()
endforeach ()
endmacro ()
unset(PC_FILES)
if(BUILD_SHARED_LIBS)
if (BUILD_SHARED_LIBS)
set(META_PROJECT_NAME_FOR_PC "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}")
depends_for_pc(SHARED META_PUBLIC_SHARED_LIB_DEPENDS META_PUBLIC_PC_PKGS META_PUBLIC_LIB_DEPENDS_FOR_PC)
depends_for_pc(SHARED META_PRIVATE_SHARED_LIB_DEPENDS META_PRIVATE_PC_PKGS META_PRIVATE_LIB_DEPENDS_FOR_PC)
compile_defs_for_pc(SHARED)
if(NOT META_HEADER_ONLY_LIB)
set(META_PUBLIC_LIB_DEPENDS_FOR_PC " -l${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}${META_PUBLIC_LIB_DEPENDS_FOR_PC}")
endif()
if(META_PUBLIC_LIB_DEPENDS_FOR_PC)
if (NOT META_HEADER_ONLY_LIB)
set(META_PUBLIC_LIB_DEPENDS_FOR_PC
" -l${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}${META_PUBLIC_LIB_DEPENDS_FOR_PC}")
endif ()
if (META_PUBLIC_LIB_DEPENDS_FOR_PC)
set(META_PUBLIC_LIB_DEPENDS_FOR_PC " -L\${libdir}${META_PUBLIC_LIB_DEPENDS_FOR_PC}")
endif()
configure_file(
"${PKGCONFIG_TEMPLATE_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME_FOR_PC}.pc"
@ONLY
)
endif ()
configure_file("${PKGCONFIG_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME_FOR_PC}.pc" @ONLY)
list(APPEND PC_FILES "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME_FOR_PC}.pc")
endif()
if(BUILD_STATIC_LIBS)
endif ()
if (BUILD_STATIC_LIBS)
set(META_PROJECT_NAME_FOR_PC "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static")
depends_for_pc(STATIC META_PUBLIC_STATIC_LIB_DEPENDS META_PUBLIC_PC_PKGS META_PUBLIC_LIB_DEPENDS_FOR_PC)
depends_for_pc(STATIC META_PRIVATE_STATIC_LIB_DEPENDS META_PRIVATE_PC_PKGS META_PRIVATE_LIB_DEPENDS_FOR_PC)
compile_defs_for_pc(STATIC)
if(NOT META_HEADER_ONLY_LIB)
set(META_PUBLIC_LIB_DEPENDS_FOR_PC " -l${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}${META_PUBLIC_LIB_DEPENDS_FOR_PC}")
endif()
if(META_PUBLIC_LIB_DEPENDS_FOR_PC)
if (NOT META_HEADER_ONLY_LIB)
set(META_PUBLIC_LIB_DEPENDS_FOR_PC
" -l${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}${META_PUBLIC_LIB_DEPENDS_FOR_PC}")
endif ()
if (META_PUBLIC_LIB_DEPENDS_FOR_PC)
set(META_PUBLIC_LIB_DEPENDS_FOR_PC " -L\${libdir}${META_PUBLIC_LIB_DEPENDS_FOR_PC}")
endif()
configure_file(
"${PKGCONFIG_TEMPLATE_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME_FOR_PC}.pc"
@ONLY
)
endif ()
configure_file("${PKGCONFIG_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME_FOR_PC}.pc" @ONLY)
list(APPEND PC_FILES "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME_FOR_PC}.pc")
endif()
endif ()
if(NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS)
if (NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS)
# add install target for the CMake config files
install(
FILES ${CMAKE_CONFIG_FILES}
DESTINATION "share/${META_PROJECT_NAME}/cmake"
COMPONENT cmake-config
)
if(NOT TARGET install-cmake-config)
install(FILES ${CMAKE_CONFIG_FILES} DESTINATION "share/${META_PROJECT_NAME}/cmake" COMPONENT cmake-config)
if (NOT TARGET install-cmake-config)
add_custom_target(install-cmake-config
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=cmake-config -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=cmake-config -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif ()
# add install target for pkg-config file
if(PC_FILES)
install(
FILES ${PC_FILES}
DESTINATION "lib${SELECTED_LIB_SUFFIX}/pkgconfig"
COMPONENT pkg-config
)
endif()
if(NOT TARGET install-pkg-config)
if (PC_FILES)
install(FILES ${PC_FILES} DESTINATION "lib${SELECTED_LIB_SUFFIX}/pkgconfig" COMPONENT pkg-config)
endif ()
if (NOT TARGET install-pkg-config)
add_custom_target(install-pkg-config
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=pkg-config -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=pkg-config -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif ()
# add install target for libs
if(NOT TARGET install-binary)
if (NOT TARGET install-binary)
add_custom_target(install-binary
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=binary -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=binary -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif ()
# add install target for stripped libs
if(NOT TARGET install-binary-strip)
if (NOT TARGET install-binary-strip)
add_custom_target(install-binary-strip
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_DO_STRIP=1 -DCMAKE_INSTALL_COMPONENT=binary -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_DO_STRIP=1 -DCMAKE_INSTALL_COMPONENT=binary -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif ()
# determine install dir for Qt plugins
if("${META_PROJECT_TYPE}" STREQUAL "qtplugin")
if(QT_PLUGIN_DIR)
if ("${META_PROJECT_TYPE}" STREQUAL "qtplugin")
if (QT_PLUGIN_DIR)
set(LIBRARY_DESTINATION ${QT_PLUGIN_DIR})
else()
else ()
set(LIBRARY_DESTINATION lib${SELECTED_LIB_SUFFIX}/qt/plugins)
endif()
if(META_PLUGIN_CATEGORY)
endif ()
if (META_PLUGIN_CATEGORY)
set(LIBRARY_DESTINATION ${LIBRARY_DESTINATION}/${META_PLUGIN_CATEGORY})
endif()
else()
endif ()
else ()
set(LIBRARY_DESTINATION lib${SELECTED_LIB_SUFFIX})
endif()
endif ()
# add install targets and export targets
if(BUILD_SHARED_LIBS)
install(
TARGETS ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
EXPORT ${META_PROJECT_NAME}SharedTargets
RUNTIME DESTINATION bin
COMPONENT binary
LIBRARY DESTINATION ${LIBRARY_DESTINATION}
COMPONENT binary
ARCHIVE DESTINATION ${LIBRARY_DESTINATION}
COMPONENT binary
)
if (BUILD_SHARED_LIBS)
install(TARGETS ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
EXPORT ${META_PROJECT_NAME}SharedTargets
RUNTIME DESTINATION bin COMPONENT binary
LIBRARY DESTINATION ${LIBRARY_DESTINATION} COMPONENT binary
ARCHIVE DESTINATION ${LIBRARY_DESTINATION} COMPONENT binary)
add_dependencies(install-binary ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX})
add_dependencies(install-binary-strip ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX})
# export shared lib
install(EXPORT ${META_PROJECT_NAME}SharedTargets
DESTINATION "share/${META_PROJECT_NAME}/cmake"
EXPORT_LINK_INTERFACE_LIBRARIES
COMPONENT cmake-config
)
endif()
if(BUILD_STATIC_LIBS)
install(
TARGETS ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
EXPORT ${META_PROJECT_NAME}StaticTargets
RUNTIME DESTINATION bin
COMPONENT binary
LIBRARY DESTINATION ${LIBRARY_DESTINATION}
COMPONENT binary
ARCHIVE DESTINATION ${LIBRARY_DESTINATION}
COMPONENT binary
)
DESTINATION "share/${META_PROJECT_NAME}/cmake"
EXPORT_LINK_INTERFACE_LIBRARIES
COMPONENT cmake-config)
endif ()
if (BUILD_STATIC_LIBS)
install(TARGETS ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
EXPORT ${META_PROJECT_NAME}StaticTargets
RUNTIME DESTINATION bin COMPONENT binary
LIBRARY DESTINATION ${LIBRARY_DESTINATION} COMPONENT binary
ARCHIVE DESTINATION ${LIBRARY_DESTINATION} COMPONENT binary)
add_dependencies(install-binary ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static)
add_dependencies(install-binary-strip ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static)
# export static target
install(EXPORT ${META_PROJECT_NAME}StaticTargets
DESTINATION "share/${META_PROJECT_NAME}/cmake"
EXPORT_LINK_INTERFACE_LIBRARIES
COMPONENT cmake-config
)
endif()
DESTINATION "share/${META_PROJECT_NAME}/cmake"
EXPORT_LINK_INTERFACE_LIBRARIES
COMPONENT cmake-config)
endif ()
# add install target for header files
if(NOT META_IS_PLUGIN)
foreach(HEADER_FILE ${HEADER_FILES} ${ADDITIONAL_HEADER_FILES})
if (NOT META_IS_PLUGIN)
foreach (HEADER_FILE ${HEADER_FILES} ${ADDITIONAL_HEADER_FILES})
get_filename_component(HEADER_DIR "${HEADER_FILE}" DIRECTORY)
install(
FILES "${HEADER_FILE}"
DESTINATION "include/${META_PROJECT_NAME}/${HEADER_DIR}"
COMPONENT header
)
endforeach()
if(NOT TARGET install-header)
install(FILES "${HEADER_FILE}" DESTINATION "include/${META_PROJECT_NAME}/${HEADER_DIR}" COMPONENT header)
endforeach ()
if (NOT TARGET install-header)
add_custom_target(install-header
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=header -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
endif()
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=header -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif ()
endif ()
# add install target for CMake modules
foreach(CMAKE_MODULE_FILE ${CMAKE_MODULE_FILES})
foreach (CMAKE_MODULE_FILE ${CMAKE_MODULE_FILES})
get_filename_component(CMAKE_MODULE_DIR ${CMAKE_MODULE_FILE} DIRECTORY)
install(
FILES ${CMAKE_MODULE_FILE}
DESTINATION share/${META_PROJECT_NAME}/${CMAKE_MODULE_DIR}
COMPONENT cmake-modules
)
endforeach()
if(NOT TARGET install-cmake-modules)
install(FILES ${CMAKE_MODULE_FILE}
DESTINATION share/${META_PROJECT_NAME}/${CMAKE_MODULE_DIR}
COMPONENT cmake-modules)
endforeach ()
if (NOT TARGET install-cmake-modules)
add_custom_target(install-cmake-modules
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=cmake-modules -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=cmake-modules -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif ()
# add install target for CMake templates
foreach(CMAKE_TEMPLATE_FILE ${CMAKE_TEMPLATE_FILES})
foreach (CMAKE_TEMPLATE_FILE ${CMAKE_TEMPLATE_FILES})
get_filename_component(CMAKE_TEMPLATE_DIR ${CMAKE_TEMPLATE_FILE} DIRECTORY)
install(
FILES ${CMAKE_TEMPLATE_FILE}
DESTINATION share/${META_PROJECT_NAME}/${CMAKE_TEMPLATE_DIR}
COMPONENT cmake-templates
)
endforeach()
if(NOT TARGET install-cmake-templates)
install(FILES ${CMAKE_TEMPLATE_FILE}
DESTINATION share/${META_PROJECT_NAME}/${CMAKE_TEMPLATE_DIR}
COMPONENT cmake-templates)
endforeach ()
if (NOT TARGET install-cmake-templates)
add_custom_target(install-cmake-templates
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=cmake-templates -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=cmake-templates -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif ()
# add install target for all the cmake stuff
if(NOT TARGET install-cmake-stuff)
if (NOT TARGET install-cmake-stuff)
add_custom_target(install-cmake-stuff)
add_dependencies(install-cmake-stuff install-cmake-config install-cmake-modules install-cmake-templates)
endif()
endif ()
# add mingw-w64 specific install targets
if(MINGW)
if(NOT TARGET install-mingw-w64)
if (MINGW)
if (NOT TARGET install-mingw-w64)
add_custom_target(install-mingw-w64)
endif()
endif ()
add_dependencies(install-mingw-w64 install-binary install-header install-cmake-stuff install-pkg-config)
if(NOT TARGET install-mingw-w64-strip)
if (NOT TARGET install-mingw-w64-strip)
add_custom_target(install-mingw-w64-strip)
endif()
endif ()
add_dependencies(install-mingw-w64-strip install-binary-strip install-header install-cmake-stuff install-pkg-config)
if(LOCALIZATION_TARGET)
if (LOCALIZATION_TARGET)
add_dependencies(install-mingw-w64 ${LOCALIZATION_TARGET})
add_dependencies(install-mingw-w64-strip ${LOCALIZATION_TARGET})
endif()
endif ()
find_program(STRIP_BINARY_PATH strip ONLY_CMAKE_FIND_ROOT_PATH)
if(NOT STRIP_BINARY_PATH)
if (NOT STRIP_BINARY_PATH)
message(FATAL_ERROR "Unable to find strip. Please set ${STRIP_BINARY_PATH}.")
else()
else ()
message(STATUS "Using strip binary under \"${STRIP_BINARY_PATH}\".")
endif()
if(BUILD_SHARED_LIBS AND NOT META_HEADER_ONLY_LIB)
add_custom_target(install-${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}-mingw-w64-importlib-strip
COMMAND "${STRIP_BINARY_PATH}" -g "\$\{DESTDIR\}\$\{DESTDIR:+/\}${CMAKE_INSTALL_PREFIX}/lib/lib${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}.dll.a"
)
add_dependencies(install-${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}-mingw-w64-importlib-strip install-binary-strip)
add_dependencies(install-mingw-w64-strip install-${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}-mingw-w64-importlib-strip)
endif()
if(BUILD_STATIC_LIBS AND NOT META_HEADER_ONLY_LIB)
add_custom_target(install-${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}-mingw-w64-staticlib-strip
COMMAND "${STRIP_BINARY_PATH}" -g "\$\{DESTDIR\}\$\{DESTDIR:+/\}${CMAKE_INSTALL_PREFIX}/lib/lib${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}.a"
)
add_dependencies(install-${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}-mingw-w64-staticlib-strip install-binary-strip)
add_dependencies(install-mingw-w64-strip install-${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}-mingw-w64-staticlib-strip)
endif()
endif()
endif()
endif ()
if (BUILD_SHARED_LIBS AND NOT META_HEADER_ONLY_LIB)
add_custom_target(
install-${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}-mingw-w64-importlib-strip
COMMAND
"${STRIP_BINARY_PATH}" -g
"\$\{DESTDIR\}\$\{DESTDIR:+/\}${CMAKE_INSTALL_PREFIX}/lib/lib${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}.dll.a"
)
add_dependencies(install-${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}-mingw-w64-importlib-strip
install-binary-strip)
add_dependencies(install-mingw-w64-strip
install-${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}-mingw-w64-importlib-strip)
endif ()
if (BUILD_STATIC_LIBS AND NOT META_HEADER_ONLY_LIB)
add_custom_target(
install-${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}-mingw-w64-staticlib-strip
COMMAND
"${STRIP_BINARY_PATH}" -g
"\$\{DESTDIR\}\$\{DESTDIR:+/\}${CMAKE_INSTALL_PREFIX}/lib/lib${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}.a"
)
add_dependencies(install-${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}-mingw-w64-staticlib-strip
install-binary-strip)
add_dependencies(install-mingw-w64-strip
install-${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}-mingw-w64-staticlib-strip)
endif ()
endif ()
endif ()
set(TARGET_CONFIG_DONE YES)

View File

@ -1,30 +1,30 @@
# prevent multiple inclusion
if(DEFINED LIST_TO_STRING_LOADED)
if (DEFINED LIST_TO_STRING_LOADED)
return()
endif()
endif ()
set(LIST_TO_STRING_LOADED ON)
function(list_to_string separator prefix suffix input_list output_string_var)
function (list_to_string separator prefix suffix input_list output_string_var)
set(res "")
# get list length
list(LENGTH input_list list_length)
# if the list has 0 or 1 element, there is no need to loop over
if(list_length LESS 2)
if (list_length LESS 2)
set(res "${prefix}${input_list}${suffix}")
else()
else ()
math(EXPR last_element_index "${list_length} - 1")
foreach(index RANGE ${last_element_index})
foreach (index RANGE ${last_element_index})
# get current item_value
list(GET input_list ${index} item_value)
if(NOT item_value STREQUAL "")
if (NOT item_value STREQUAL "")
# .. and append non-empty value to output string
set(res "${res}${prefix}${item_value}${suffix}")
# append separator if current element is NOT the last one.
if(NOT index EQUAL last_element_index)
if (NOT index EQUAL last_element_index)
set(res "${res}${separator}")
endif()
endif()
endforeach()
endif()
endif ()
endif ()
endforeach ()
endif ()
set(${output_string_var} "${res}" PARENT_SCOPE)
endfunction()
endfunction ()

View File

@ -1,38 +1,34 @@
if(NOT BASIC_PROJECT_CONFIG_DONE)
if (NOT BASIC_PROJECT_CONFIG_DONE)
message(FATAL_ERROR "Before including the ShellCompletion module, the BasicConfig module must be included.")
endif()
endif ()
option(SHELL_COMPLETION_ENABLED "controls whether shell completion is enabled in general" ON)
option(BASH_COMPLETION_ENABLED "controls whether shell completion for bash is enabled" ON)
if(NOT SHELL_COMPLETION_ENABLED)
if (NOT SHELL_COMPLETION_ENABLED)
return()
endif()
endif ()
# add bash completion (currently the only supported shell completion)
if(BASH_COMPLETION_ENABLED)
if (BASH_COMPLETION_ENABLED)
# find bash-completion.sh template
include(TemplateFinder)
find_template_file("bash-completion.sh" CPP_UTILITIES BASH_COMPLETION_TEMPLATE_FILE)
# generate wrapper script for bash completion
configure_file(
"${BASH_COMPLETION_TEMPLATE_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/bash-completion/completions/${META_PROJECT_NAME}"
@ONLY
)
configure_file("${BASH_COMPLETION_TEMPLATE_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/bash-completion/completions/${META_PROJECT_NAME}" @ONLY)
# add install target bash completion
if(NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS)
if (NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS)
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bash-completion/completions"
DESTINATION "share/bash-completion"
COMPONENT bash-completion
)
if(NOT TARGET install-bash-completion)
COMPONENT bash-completion)
if (NOT TARGET install-bash-completion)
add_custom_target(install-bash-completion
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=bash-completion -P "${CMAKE_BINARY_DIR}/cmake_install.cmake"
)
endif()
endif()
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=bash-completion -P
"${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif ()
endif ()
message(STATUS "Generating files for bash completion.")
endif()
endif ()

View File

@ -1,23 +1,23 @@
# prevent multiple inclusion
if(DEFINED TEMPLATE_FINDER_LOADED)
if (DEFINED TEMPLATE_FINDER_LOADED)
return()
endif()
endif ()
set(TEMPLATE_FINDER_LOADED YES)
function(find_template_file FILE_NAME PROJECT_VAR_NAME OUTPUT_VAR)
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/${FILE_NAME}.in")
function (find_template_file FILE_NAME PROJECT_VAR_NAME OUTPUT_VAR)
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/${FILE_NAME}.in")
# check own source directory
set(${OUTPUT_VAR} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/${FILE_NAME}.in" PARENT_SCOPE)
message(STATUS "Using template for ${FILE_NAME} from own (${META_PROJECT_NAME}) source directory.")
elseif(EXISTS "${${PROJECT_VAR_NAME}_SOURCE_DIR}/cmake/templates/${FILE_NAME}.in")
elseif (EXISTS "${${PROJECT_VAR_NAME}_SOURCE_DIR}/cmake/templates/${FILE_NAME}.in")
# check sources of project
set(${OUTPUT_VAR} "${${PROJECT_VAR_NAME}_SOURCE_DIR}/cmake/templates/${FILE_NAME}.in" PARENT_SCOPE)
message(STATUS "Using template for ${FILE_NAME} from ${PROJECT_VAR_NAME} source directory.")
elseif(EXISTS "${${PROJECT_VAR_NAME}_CONFIG_DIRS}/templates/${FILE_NAME}.in")
elseif (EXISTS "${${PROJECT_VAR_NAME}_CONFIG_DIRS}/templates/${FILE_NAME}.in")
# check installed version of project
set(${OUTPUT_VAR} "${${PROJECT_VAR_NAME}_CONFIG_DIRS}/templates/${FILE_NAME}.in" PARENT_SCOPE)
message(STATUS "Using template for ${FILE_NAME} from ${PROJECT_VAR_NAME} installation.")
else()
else ()
message(FATAL_ERROR "Template for ${FILE_NAME} file can not be located.")
endif()
endfunction()
endif ()
endfunction ()

View File

@ -1,360 +1,345 @@
if(NOT BASIC_PROJECT_CONFIG_DONE)
if (NOT BASIC_PROJECT_CONFIG_DONE)
message(FATAL_ERROR "Before including the TestTarget module, the BasicConfig module must be included.")
endif()
if(TEST_CONFIG_DONE)
endif ()
if (TEST_CONFIG_DONE)
message(FATAL_ERROR "Can not include TestTarget module when tests are already configured.")
endif()
endif ()
option(EXCLUDE_TESTS_FROM_ALL "specifies whether to exclude tests from the \"all\" target (enabled by default)" ON)
# find and link against cppunit if required (used by all my projects, so it is required by default)
if(NOT META_NO_CPP_UNIT)
if (NOT META_NO_CPP_UNIT)
# make cppunit library/include dir configurable
set(CPP_UNIT_LIB NOTFOUND CACHE FILEPATH "cppunit lib" FORCE)
set(CPP_UNIT_INCLUDE_DIR NOTFOUND CACHE FILEPATH "cppunit include dir" FORCE)
# set default for minimum version (only checked when using pkg-config)
if(NOT META_REQUIRED_CPP_UNIT_VERSION)
if (NOT META_REQUIRED_CPP_UNIT_VERSION)
set(META_REQUIRED_CPP_UNIT_VERSION 1.13.0)
endif()
endif ()
# auto-detection: try to find via pkg-config first
if(NOT CPP_UNIT_LIB AND NOT CPP_UNIT_INCLUDE_DIR)
if (NOT CPP_UNIT_LIB AND NOT CPP_UNIT_INCLUDE_DIR)
include(FindPkgConfig)
pkg_search_module(CPP_UNIT_CONFIG_${META_PROJECT_NAME} cppunit>=${META_REQUIRED_CPP_UNIT_VERSION})
if(CPP_UNIT_CONFIG_${META_PROJECT_NAME}_FOUND)
set(CPP_UNIT_LIB "${CPP_UNIT_CONFIG_${META_PROJECT_NAME}_LDFLAGS_OTHER}" "${CPP_UNIT_CONFIG_${META_PROJECT_NAME}_LIBRARIES}" CACHE FILEPATH "cppunit lib" FORCE)
set(CPP_UNIT_INCLUDE_DIR ${CPP_UNIT_CONFIG_${META_PROJECT_NAME}_INCLUDE_DIRS} CACHE FILEPATH "cppunit include dir" FORCE)
if (CPP_UNIT_CONFIG_${META_PROJECT_NAME}_FOUND)
set(CPP_UNIT_LIB "${CPP_UNIT_CONFIG_${META_PROJECT_NAME}_LDFLAGS_OTHER}"
"${CPP_UNIT_CONFIG_${META_PROJECT_NAME}_LIBRARIES}"
CACHE FILEPATH "cppunit lib"
FORCE)
set(CPP_UNIT_INCLUDE_DIR ${CPP_UNIT_CONFIG_${META_PROJECT_NAME}_INCLUDE_DIRS}
CACHE FILEPATH "cppunit include dir"
FORCE)
link_directories(${CPP_UNIT_CONFIG_${META_PROJECT_NAME}_LIBRARY_DIRS})
else()
else ()
# fall back to find_library
find_library(DETECTED_CPP_UNIT_LIB cppunit)
set(CPP_UNIT_LIB "${DETECTED_CPP_UNIT_LIB}" CACHE FILEPATH "cppunit lib" FORCE)
endif()
endif()
endif ()
endif ()
if(NOT CPP_UNIT_LIB)
if (NOT CPP_UNIT_LIB)
message(WARNING "Unable to add test target because cppunit could not be located.")
set(META_HAVE_TESTS NO)
set(TEST_CONFIG_DONE YES)
return()
endif()
endif ()
list(APPEND TEST_LIBRARIES "${CPP_UNIT_LIB}")
if(NOT CPP_UNIT_CONFIG_${META_PROJECT_NAME}_FOUND)
message(WARNING "Cppunit not detected via pkg-config so the version couldn't be checked. Required version for ${META_PROJECT_NAME} is ${META_REQUIRED_CPP_UNIT_VERSION}.")
endif()
if (NOT CPP_UNIT_CONFIG_${META_PROJECT_NAME}_FOUND)
message(
WARNING
"Cppunit not detected via pkg-config so the version couldn't be checked. Required version for ${META_PROJECT_NAME} is ${META_REQUIRED_CPP_UNIT_VERSION}."
)
endif ()
if(CPP_UNIT_INCLUDE_DIR)
if (CPP_UNIT_INCLUDE_DIR)
list(APPEND TEST_INCLUDE_DIRS "${CPP_UNIT_INCLUDE_DIR}")
endif()
endif()
endif ()
endif ()
# add default cppunit test application if requested
if(META_ADD_DEFAULT_CPP_UNIT_TEST_APPLICATION)
if(META_NO_CPP_UNIT)
message(FATAL_ERROR "Project ${META_PROJECT_NAME} has META_ADD_DEFAULT_CPP_UNIT_TEST_APPLICATION and META_NO_CPP_UNIT enabled at the same time.")
endif()
if (META_ADD_DEFAULT_CPP_UNIT_TEST_APPLICATION)
if (META_NO_CPP_UNIT)
message(
FATAL_ERROR
"Project ${META_PROJECT_NAME} has META_ADD_DEFAULT_CPP_UNIT_TEST_APPLICATION and META_NO_CPP_UNIT enabled at the same time."
)
endif ()
set(DEFAULT_CPP_UNIT_TEST_APPLICATION_SRC "${CMAKE_CURRENT_BINARY_DIR}/cppunit.cpp")
file(WRITE "${DEFAULT_CPP_UNIT_TEST_APPLICATION_SRC}" "#include <c++utilities/tests/cppunit.h>")
list(APPEND TEST_SRC_FILES "${DEFAULT_CPP_UNIT_TEST_APPLICATION_SRC}")
endif()
endif ()
# always link test applications against c++utilities
list(APPEND TEST_LIBRARIES ${CPP_UTILITIES_LIB})
# set compile definitions
if(NOT META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS)
set(META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS ${META_PUBLIC_COMPILE_DEFINITIONS} ${META_ADDITIONAL_PUBLIC_SHARED_COMPILE_DEFINITIONS})
endif()
if(NOT META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS)
set(META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS ${META_PRIVATE_COMPILE_DEFINITIONS} ${META_ADDITIONAL_PRIVATE_SHARED_COMPILE_DEFINITIONS})
endif()
if (NOT META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS)
set(META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS ${META_PUBLIC_COMPILE_DEFINITIONS}
${META_ADDITIONAL_PUBLIC_SHARED_COMPILE_DEFINITIONS})
endif ()
if (NOT META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS)
set(META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS ${META_PRIVATE_COMPILE_DEFINITIONS}
${META_ADDITIONAL_PRIVATE_SHARED_COMPILE_DEFINITIONS})
endif ()
# add target for test executable, but exclude it from the "all" target when EXCLUDE_TESTS_FROM_ALL is set
if(EXCLUDE_TESTS_FROM_ALL)
if (EXCLUDE_TESTS_FROM_ALL)
set(TESTS_EXCLUSION EXCLUDE_FROM_ALL)
else()
else ()
unset(TESTS_EXCLUSION)
endif()
add_executable(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests ${TESTS_EXCLUSION} ${TEST_HEADER_FILES} ${TEST_SRC_FILES})
endif ()
add_executable(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests
${TESTS_EXCLUSION}
${TEST_HEADER_FILES}
${TEST_SRC_FILES})
# add top-level target to build all test targets conveniently, also when excluded from "all" target
if(NOT TARGET tests)
if (NOT TARGET tests)
add_custom_target(tests DEPENDS ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests)
else()
else ()
add_dependencies(tests ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests)
endif()
endif ()
# handle testing a library (which is default project type)
if(NOT META_PROJECT_TYPE OR "${META_PROJECT_TYPE}" STREQUAL "library")
if (NOT META_PROJECT_TYPE OR "${META_PROJECT_TYPE}" STREQUAL "library")
# when testing a library, the test application always needs to link against it
if(BUILD_SHARED_LIBS)
if (BUILD_SHARED_LIBS)
list(APPEND TEST_LIBRARIES ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX})
message(STATUS "Linking test target dynamically against ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}")
else()
else ()
list(APPEND TEST_LIBRARIES ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static)
message(STATUS "Linking test target statically against ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}")
endif()
endif()
endif ()
endif ()
# handle testing an application
if("${META_PROJECT_TYPE}" STREQUAL "application")
if ("${META_PROJECT_TYPE}" STREQUAL "application")
# using functions directly from the tests might be required -> also create a 'testlib' and link tests against it
if(LINK_TESTS_AGAINST_APP_TARGET)
if (LINK_TESTS_AGAINST_APP_TARGET)
# create target for the 'testlib'
set(TESTLIB_FILES ${HEADER_FILES} ${SRC_FILES} ${WIDGETS_FILES} ${QML_FILES} ${RES_FILES} ${QM_FILES})
list(REMOVE_ITEM TESTLIB_FILES main.h main.cpp)
add_library(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib SHARED ${TESTLIB_FILES})
target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib
PUBLIC ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}"
PRIVATE "${PRIVATE_LIBRARIES}"
)
PUBLIC ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}"
PRIVATE "${PRIVATE_LIBRARIES}")
target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}>
${PUBLIC_SHARED_INCLUDE_DIRS}
PRIVATE
"${PRIVATE_SHARED_INCLUDE_DIRS}"
)
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> ${PUBLIC_SHARED_INCLUDE_DIRS}
PRIVATE "${PRIVATE_SHARED_INCLUDE_DIRS}")
target_compile_definitions(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib
PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS}"
PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS}"
)
PUBLIC
"${META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS}"
PRIVATE
"${META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS}")
target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib
PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}"
PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}"
)
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib PROPERTIES
CXX_STANDARD "${META_CXX_STANDARD}"
LINK_SEARCH_START_STATIC ${STATIC_LINKAGE}
LINK_SEARCH_END_STATIC ${STATIC_LINKAGE}
AUTOGEN_TARGET_DEPENDS "${AUTOGEN_DEPS}"
)
if(CPP_UNIT_CONFIG_${META_PROJECT_NAME}_FOUND)
PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}"
PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}")
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib
PROPERTIES CXX_STANDARD
"${META_CXX_STANDARD}"
LINK_SEARCH_START_STATIC
${STATIC_LINKAGE}
LINK_SEARCH_END_STATIC
${STATIC_LINKAGE}
AUTOGEN_TARGET_DEPENDS
"${AUTOGEN_DEPS}")
if (CPP_UNIT_CONFIG_${META_PROJECT_NAME}_FOUND)
target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib
PRIVATE "${CPP_UNIT_CONFIG_${META_PROJECT_NAME}_INCLUDE_DIRS}"
)
PRIVATE "${CPP_UNIT_CONFIG_${META_PROJECT_NAME}_INCLUDE_DIRS}")
target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib
PRIVATE "${CPP_UNIT_CONFIG_${META_PROJECT_NAME}_CFLAGS_OTHER}"
)
endif()
PRIVATE "${CPP_UNIT_CONFIG_${META_PROJECT_NAME}_CFLAGS_OTHER}")
endif ()
# link tests against it
list(APPEND TEST_LIBRARIES ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib)
# ensure all symbols are visible (man gcc: "Despite the nomenclature, default always means public")
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib PROPERTIES CXX_VISIBILITY_PRESET default)
endif()
endif()
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib
PROPERTIES CXX_VISIBILITY_PRESET default)
endif ()
endif ()
# actually apply configuration for test target
target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests
PUBLIC ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}"
PRIVATE "${TEST_LIBRARIES}" "${PRIVATE_LIBRARIES}"
)
PUBLIC ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}"
PRIVATE "${TEST_LIBRARIES}" "${PRIVATE_LIBRARIES}")
target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}>
${PUBLIC_SHARED_INCLUDE_DIRS}
PRIVATE
${TEST_INCLUDE_DIRS}
"${PRIVATE_SHARED_INCLUDE_DIRS}"
)
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> ${PUBLIC_SHARED_INCLUDE_DIRS}
PRIVATE ${TEST_INCLUDE_DIRS} "${PRIVATE_SHARED_INCLUDE_DIRS}")
target_compile_definitions(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests
PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS}"
PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS}"
)
PUBLIC
"${META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS}"
PRIVATE
"${META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS}")
target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests
PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}"
PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}"
)
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests PROPERTIES
CXX_STANDARD "${META_CXX_STANDARD}"
LINK_SEARCH_START_STATIC ${STATIC_LINKAGE}
LINK_SEARCH_END_STATIC ${STATIC_LINKAGE}
)
PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}"
PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}")
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests
PROPERTIES CXX_STANDARD
"${META_CXX_STANDARD}"
LINK_SEARCH_START_STATIC
${STATIC_LINKAGE}
LINK_SEARCH_END_STATIC
${STATIC_LINKAGE})
# make the test recognized by ctest
unset(RUN_TESTS_APPLICATION_ARG)
if(META_PROJECT_TYPE STREQUAL "application")
if (META_PROJECT_TYPE STREQUAL "application")
set(RUN_TESTS_APPLICATION_ARGS -a "$<TARGET_FILE:${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}>")
endif()
if(NOT META_TEST_TARGET_IS_MANUAL)
add_test(NAME ${META_PROJECT_NAME}_run_tests COMMAND
${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests
-p "${CMAKE_CURRENT_SOURCE_DIR}/testfiles"
-w "${CMAKE_CURRENT_BINARY_DIR}/testworkingdir"
${RUN_TESTS_APPLICATION_ARGS}
)
endif()
endif ()
if (NOT META_TEST_TARGET_IS_MANUAL)
add_test(NAME ${META_PROJECT_NAME}_run_tests
COMMAND ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests -p "${CMAKE_CURRENT_SOURCE_DIR}/testfiles" -w
"${CMAKE_CURRENT_BINARY_DIR}/testworkingdir" ${RUN_TESTS_APPLICATION_ARGS})
endif ()
# enable source code based coverage analysis using clang
if(CLANG_SOURCE_BASED_COVERAGE_AVAILABLE)
if (CLANG_SOURCE_BASED_COVERAGE_AVAILABLE)
# define path of raw profile data
set(LLVM_PROFILE_RAW_FILE "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests.profraw")
set(LLVM_PROFILE_RAW_FILE
"${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests.profraw")
# define path of list with additional raw profile data from fork processes spawned during tests
set(LLVM_PROFILE_RAW_LIST_FILE "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests.profraw.list")
set(LLVM_PROFILE_RAW_LIST_FILE
"${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests.profraw.list")
# define path of merged profile data generated from raw profiling data
set(LLVM_PROFILE_DATA_FILE "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests.profdata")
set(LLVM_PROFILE_DATA_FILE
"${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests.profdata")
# define paths of output files
set(COVERAGE_REPORT_FILE "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage.txt")
set(COVERAGE_PER_FILE_REPORT_FILE "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage_per_file.txt")
set(COVERAGE_OVERALL_REPORT_FILE "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage_overall.txt")
set(COVERAGE_HTML_REPORT_FILE "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage.html")
set(COVERAGE_REPORT_FILE
"${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage.txt")
set(COVERAGE_PER_FILE_REPORT_FILE
"${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage_per_file.txt")
set(COVERAGE_OVERALL_REPORT_FILE
"${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage_overall.txt")
set(COVERAGE_HTML_REPORT_FILE
"${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage.html")
set(COVERAGE_REPORT_FILES "${COVERAGE_REPORT_FILE}")
# specify where to store raw clang profiling data via environment variable
if(NOT META_TEST_TARGET_IS_MANUAL)
set_tests_properties(${META_PROJECT_NAME}_run_tests
if (NOT META_TEST_TARGET_IS_MANUAL)
set_tests_properties(
${META_PROJECT_NAME}_run_tests
PROPERTIES ENVIRONMENT
"LLVM_PROFILE_FILE=${LLVM_PROFILE_RAW_FILE};LLVM_PROFILE_LIST_FILE=${LLVM_PROFILE_RAW_LIST_FILE}"
)
endif()
"LLVM_PROFILE_FILE=${LLVM_PROFILE_RAW_FILE};LLVM_PROFILE_LIST_FILE=${LLVM_PROFILE_RAW_LIST_FILE}")
endif ()
add_custom_command(
OUTPUT "${LLVM_PROFILE_RAW_FILE}"
"${LLVM_PROFILE_RAW_LIST_FILE}"
COMMAND "${CMAKE_COMMAND}"
-E env
"LLVM_PROFILE_FILE=${LLVM_PROFILE_RAW_FILE}"
"LLVM_PROFILE_LIST_FILE=${LLVM_PROFILE_RAW_LIST_FILE}"
$<TARGET_FILE:${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests>
-p "${CMAKE_CURRENT_SOURCE_DIR}/testfiles"
-w "${CMAKE_CURRENT_BINARY_DIR}/testworkingdir"
${RUN_TESTS_APPLICATION_ARGS}
COMMENT "Executing ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests to generate raw profiling data for source-based coverage report"
DEPENDS "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests"
)
OUTPUT "${LLVM_PROFILE_RAW_FILE}" "${LLVM_PROFILE_RAW_LIST_FILE}"
COMMAND "${CMAKE_COMMAND}" -E env "LLVM_PROFILE_FILE=${LLVM_PROFILE_RAW_FILE}"
"LLVM_PROFILE_LIST_FILE=${LLVM_PROFILE_RAW_LIST_FILE}"
$<TARGET_FILE:${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests> -p
"${CMAKE_CURRENT_SOURCE_DIR}/testfiles" -w "${CMAKE_CURRENT_BINARY_DIR}/testworkingdir"
${RUN_TESTS_APPLICATION_ARGS}
COMMENT
"Executing ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests to generate raw profiling data for source-based coverage report"
DEPENDS "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests")
find_program(LLVM_PROFDATA_BIN llvm-profdata)
find_program(LLVM_COV_BIN llvm-cov)
if(LLVM_PROFDATA_BIN AND LLVM_COV_BIN)
if (LLVM_PROFDATA_BIN AND LLVM_COV_BIN)
# merge profiling data
add_custom_command(
OUTPUT "${LLVM_PROFILE_DATA_FILE}"
COMMAND cat "${LLVM_PROFILE_RAW_LIST_FILE}" | xargs
"${LLVM_PROFDATA_BIN}" merge
-o "${LLVM_PROFILE_DATA_FILE}"
-sparse
"${LLVM_PROFILE_RAW_FILE}"
COMMENT "Generating profiling data for source-based coverage report"
DEPENDS "${LLVM_PROFILE_RAW_FILE}"
"${LLVM_PROFILE_RAW_LIST_FILE}"
)
add_custom_command(OUTPUT "${LLVM_PROFILE_DATA_FILE}"
COMMAND cat "${LLVM_PROFILE_RAW_LIST_FILE}" | xargs "${LLVM_PROFDATA_BIN}" merge -o
"${LLVM_PROFILE_DATA_FILE}" -sparse "${LLVM_PROFILE_RAW_FILE}"
COMMENT "Generating profiling data for source-based coverage report"
DEPENDS "${LLVM_PROFILE_RAW_FILE}" "${LLVM_PROFILE_RAW_LIST_FILE}")
# determine llvm-cov version
execute_process(
COMMAND "${LLVM_COV_BIN}" -version
OUTPUT_VARIABLE LLVM_COV_VERSION
)
string(REGEX MATCH "LLVM version ([0-9](.[0-9])*)" LLVM_COV_VERSION "${LLVM_COV_VERSION}")
if(CMAKE_MATCH_1)
execute_process(COMMAND "${LLVM_COV_BIN}" -version OUTPUT_VARIABLE LLVM_COV_VERSION)
string(REGEX MATCH
"LLVM version ([0-9](.[0-9])*)"
LLVM_COV_VERSION
"${LLVM_COV_VERSION}")
if (CMAKE_MATCH_1)
set(LLVM_COV_VERSION "${CMAKE_MATCH_1}")
else()
message(FATAL_ERROR "Unable to determine version of llvm-cov. Output of ${LLVM_COV_BIN} -version:\n${LLVM_COV_VERSION}")
endif()
else ()
message(
FATAL_ERROR
"Unable to determine version of llvm-cov. Output of ${LLVM_COV_BIN} -version:\n${LLVM_COV_VERSION}")
endif ()
# determine the target file for llvm-cov
if(NOT META_HEADER_ONLY_LIB)
set(LLVM_COV_TARGET_FILE $<TARGET_FILE:${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}> $<TARGET_FILE:${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests>)
else()
if (NOT META_HEADER_ONLY_LIB)
set(LLVM_COV_TARGET_FILE $<TARGET_FILE:${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}>
$<TARGET_FILE:${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests>)
else ()
set(LLVM_COV_TARGET_FILE $<TARGET_FILE:${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests>)
endif()
endif ()
# generate coverage report with statistics per function
unset(LLVM_COV_ADDITIONAL_OPTIONS)
if(LLVM_COV_VERSION GREATER_EQUAL 5.0.0)
# LLVM 5 introduced -show-functions; this is required to get the same behavior as previously (statistics on function-level)
if (LLVM_COV_VERSION GREATER_EQUAL 5.0.0)
# LLVM 5 introduced -show-functions; this is required to get the same behavior as previously (statistics on
# function-level)
list(APPEND LLVM_COV_ADDITIONAL_OPTIONS -show-functions)
endif()
add_custom_command(
OUTPUT "${COVERAGE_REPORT_FILE}"
COMMAND "${LLVM_COV_BIN}" report
-format=text
-stats
-instr-profile "${LLVM_PROFILE_DATA_FILE}"
${LLVM_COV_ADDITIONAL_OPTIONS}
${LLVM_COV_TARGET_FILE}
${HEADER_FILES} ${SRC_FILES} ${WIDGETS_HEADER_FILES} ${WIDGETS_SOURCE_FILES} ${QML_HEADER_FILES} ${QML_SOURCE_FILES}
> "${COVERAGE_REPORT_FILE}"
COMMENT "Generating coverage report (statistics per function)"
DEPENDS "${LLVM_PROFILE_DATA_FILE}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
)
endif ()
add_custom_command(OUTPUT "${COVERAGE_REPORT_FILE}"
COMMAND "${LLVM_COV_BIN}" report -format=text -stats -instr-profile "${LLVM_PROFILE_DATA_FILE}"
${LLVM_COV_ADDITIONAL_OPTIONS} ${LLVM_COV_TARGET_FILE} ${HEADER_FILES} ${SRC_FILES}
${WIDGETS_HEADER_FILES} ${WIDGETS_SOURCE_FILES} ${QML_HEADER_FILES} ${QML_SOURCE_FILES} >
"${COVERAGE_REPORT_FILE}"
COMMENT "Generating coverage report (statistics per function)"
DEPENDS "${LLVM_PROFILE_DATA_FILE}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
# generate coverage report with statistics per file (only possible with LLVM 5 if source files are specified)
if(LLVM_COV_VERSION GREATER_EQUAL 5.0.0)
add_custom_command(
OUTPUT "${COVERAGE_PER_FILE_REPORT_FILE}"
COMMAND "${LLVM_COV_BIN}" report
-format=text
-stats
-instr-profile "${LLVM_PROFILE_DATA_FILE}"
${LLVM_COV_TARGET_FILE}
${HEADER_FILES} ${SRC_FILES} ${WIDGETS_HEADER_FILES} ${WIDGETS_SOURCE_FILES} ${QML_HEADER_FILES} ${QML_SOURCE_FILES}
> "${COVERAGE_PER_FILE_REPORT_FILE}"
COMMENT "Generating coverage report (statistics per file)"
DEPENDS "${LLVM_PROFILE_DATA_FILE}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
)
if (LLVM_COV_VERSION GREATER_EQUAL 5.0.0)
add_custom_command(OUTPUT "${COVERAGE_PER_FILE_REPORT_FILE}"
COMMAND "${LLVM_COV_BIN}" report -format=text -stats -instr-profile
"${LLVM_PROFILE_DATA_FILE}" ${LLVM_COV_TARGET_FILE} ${HEADER_FILES} ${SRC_FILES}
${WIDGETS_HEADER_FILES} ${WIDGETS_SOURCE_FILES} ${QML_HEADER_FILES}
${QML_SOURCE_FILES} > "${COVERAGE_PER_FILE_REPORT_FILE}"
COMMENT "Generating coverage report (statistics per file)"
DEPENDS "${LLVM_PROFILE_DATA_FILE}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
list(APPEND COVERAGE_REPORT_FILES "${COVERAGE_PER_FILE_REPORT_FILE}")
endif()
endif ()
# add target for the coverage reports
add_custom_target("${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage_summary"
DEPENDS ${COVERAGE_REPORT_FILES}
)
# generate coverage overall report (total region/line coverage)
# NOTE: added before release of LLVM 5 where coverage report with statistics per file could not be generated
DEPENDS ${COVERAGE_REPORT_FILES})
# generate coverage overall report (total region/line coverage) NOTE: added before release of LLVM 5 where coverage
# report with statistics per file could not be generated
set(OVERALL_COVERAGE_AKW_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/tests/calculateoverallcoverage.awk")
if(CPP_UTILITIES_SOURCE_DIR AND NOT EXISTS "${OVERALL_COVERAGE_AKW_SCRIPT}")
if (CPP_UTILITIES_SOURCE_DIR AND NOT EXISTS "${OVERALL_COVERAGE_AKW_SCRIPT}")
set(OVERALL_COVERAGE_AKW_SCRIPT "${CPP_UTILITIES_SOURCE_DIR}/tests/calculateoverallcoverage.awk")
endif()
if(NOT EXISTS "${OVERALL_COVERAGE_AKW_SCRIPT}")
endif ()
if (NOT EXISTS "${OVERALL_COVERAGE_AKW_SCRIPT}")
set(OVERALL_COVERAGE_AKW_SCRIPT "${CPP_UTILITIES_CONFIG_DIRS}/tests/calculateoverallcoverage.awk")
endif()
add_custom_command(
OUTPUT "${COVERAGE_OVERALL_REPORT_FILE}"
COMMAND awk
-f "${OVERALL_COVERAGE_AKW_SCRIPT}" "${COVERAGE_REPORT_FILE}"
> "${COVERAGE_OVERALL_REPORT_FILE}"
COMMENT "Generating coverage report (overall figures)"
DEPENDS "${OVERALL_COVERAGE_AKW_SCRIPT}" "${COVERAGE_REPORT_FILE}"
)
endif ()
add_custom_command(OUTPUT "${COVERAGE_OVERALL_REPORT_FILE}"
COMMAND awk -f "${OVERALL_COVERAGE_AKW_SCRIPT}" "${COVERAGE_REPORT_FILE}" >
"${COVERAGE_OVERALL_REPORT_FILE}"
COMMENT "Generating coverage report (overall figures)"
DEPENDS "${OVERALL_COVERAGE_AKW_SCRIPT}" "${COVERAGE_REPORT_FILE}")
add_custom_target("${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage_overall_summary"
DEPENDS "${COVERAGE_OVERALL_REPORT_FILE}"
)
DEPENDS "${COVERAGE_OVERALL_REPORT_FILE}")
# generate HTML document showing covered/uncovered code
add_custom_command(
OUTPUT "${COVERAGE_HTML_REPORT_FILE}"
COMMAND "${LLVM_COV_BIN}" show
-project-title="${META_APP_NAME}"
-format=html
-instr-profile "${LLVM_PROFILE_DATA_FILE}"
${LLVM_COV_TARGET_FILE}
${HEADER_FILES} ${SRC_FILES} ${WIDGETS_FILES} ${QML_FILES}
> "${COVERAGE_HTML_REPORT_FILE}"
COMMENT "Generating HTML document showing covered/uncovered code"
DEPENDS "${LLVM_PROFILE_DATA_FILE}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
)
add_custom_command(OUTPUT "${COVERAGE_HTML_REPORT_FILE}"
COMMAND "${LLVM_COV_BIN}" show -project-title="${META_APP_NAME}" -format=html -instr-profile
"${LLVM_PROFILE_DATA_FILE}" ${LLVM_COV_TARGET_FILE} ${HEADER_FILES} ${SRC_FILES}
${WIDGETS_FILES} ${QML_FILES} > "${COVERAGE_HTML_REPORT_FILE}"
COMMENT "Generating HTML document showing covered/uncovered code"
DEPENDS "${LLVM_PROFILE_DATA_FILE}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
add_custom_target("${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage_html"
DEPENDS "${COVERAGE_HTML_REPORT_FILE}"
)
DEPENDS "${COVERAGE_HTML_REPORT_FILE}")
# create target for all coverage docs
add_custom_target("${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage"
DEPENDS ${COVERAGE_REPORT_FILES}
DEPENDS "${COVERAGE_OVERALL_REPORT_FILE}"
DEPENDS "${COVERAGE_HTML_REPORT_FILE}"
)
DEPENDS ${COVERAGE_REPORT_FILES}
DEPENDS "${COVERAGE_OVERALL_REPORT_FILE}"
DEPENDS "${COVERAGE_HTML_REPORT_FILE}")
# add targets to global coverage target
if(NOT TARGET coverage)
if (NOT TARGET coverage)
add_custom_target(coverage)
endif()
endif ()
add_dependencies(coverage "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage")
else()
message(FATAL_ERROR "Unable to generate target for coverage report because llvm-profdata and llvm-cov are not available.")
endif()
endif()
else ()
message(
FATAL_ERROR "Unable to generate target for coverage report because llvm-profdata and llvm-cov are not available."
)
endif ()
endif ()
# add the test executable to the dependencies of the check target
if(NOT META_TEST_TARGET_IS_MANUAL)
if (NOT META_TEST_TARGET_IS_MANUAL)
add_dependencies(check ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests)
endif()
endif ()
set(META_HAVE_TESTS YES)
set(TEST_CONFIG_DONE YES)

View File

@ -1,17 +1,18 @@
# generates and adds a Windows rc file for the application/library
# also attaches the application icon if ffmpeg is available
# generates and adds a Windows rc file for the application/library also attaches the application icon if ffmpeg is available
# does nothing if not building with mingw-w64
if(NOT BASIC_PROJECT_CONFIG_DONE)
message(FATAL_ERROR "Before including the WindowsResources module, the LibraryConfig/ApplicationConfig module must be included.")
endif()
if (NOT BASIC_PROJECT_CONFIG_DONE)
message(
FATAL_ERROR
"Before including the WindowsResources module, the LibraryConfig/ApplicationConfig module must be included.")
endif ()
option(WINDOWS_RESOURCES_ENABLED "controls whether Windows resources are enabled" ON)
option(WINDOWS_ICON_ENABLED "controls whether Windows icon is enabled" ON)
if(NOT MINGW OR NOT WINDOWS_RESOURCES_ENABLED)
if (NOT MINGW OR NOT WINDOWS_RESOURCES_ENABLED)
return()
endif()
endif ()
# find rc template, define path of output rc file
include(TemplateFinder)
@ -21,43 +22,37 @@ set(WINDOWS_RC_FILE "${CMAKE_CURRENT_BINARY_DIR}/resources/windows.rc")
# create Windows icon from png with ffmpeg if available
unset(WINDOWS_ICON_PATH)
unset(WINDOWS_ICON_RC_ENTRY)
if(WINDOWS_ICON_ENABLED)
if (WINDOWS_ICON_ENABLED)
find_program(FFMPEG_BIN ffmpeg avconv)
if(FFMPEG_BIN)
if(NOT PNG_ICON_PATH)
if (FFMPEG_BIN)
if (NOT PNG_ICON_PATH)
set(PNG_ICON_PATH "${CMAKE_CURRENT_SOURCE_DIR}/resources/icons/hicolor/128x128/apps/${META_PROJECT_NAME}.png")
set(USING_DEFAULT_PNG_ICON_PATH true)
endif()
if(PNG_ICON_NO_CROP)
endif ()
if (PNG_ICON_NO_CROP)
unset(PNG_ICON_CROP)
elseif(NOT PNG_ICON_CROP)
elseif (NOT PNG_ICON_CROP)
# default cropping
set(PNG_ICON_CROP "iw-20:ih-20:10:10")
endif()
if(EXISTS "${PNG_ICON_PATH}")
endif ()
if (EXISTS "${PNG_ICON_PATH}")
set(WINDOWS_ICON_PATH "${CMAKE_CURRENT_BINARY_DIR}/resources/${META_PROJECT_NAME}.ico")
set(WINDOWS_ICON_RC_ENTRY "IDI_ICON1 ICON DISCARDABLE \"${WINDOWS_ICON_PATH}\"")
add_custom_command(
OUTPUT "${WINDOWS_ICON_PATH}"
COMMAND ${FFMPEG_BIN} -y -i "${PNG_ICON_PATH}" -vf crop=${PNG_ICON_CROP},scale=64:64 "${WINDOWS_ICON_PATH}"
DEPENDS "${PNG_ICON_PATH}"
)
set_source_files_properties("${WINDOWS_RC_FILE}"
PROPERTIES OBJECT_DEPENDS "${WINDOWS_ICON_PATH}"
)
add_custom_command(OUTPUT "${WINDOWS_ICON_PATH}"
COMMAND ${FFMPEG_BIN} -y -i "${PNG_ICON_PATH}" -vf crop=${PNG_ICON_CROP},scale=64:64
"${WINDOWS_ICON_PATH}"
DEPENDS "${PNG_ICON_PATH}")
set_source_files_properties("${WINDOWS_RC_FILE}" PROPERTIES OBJECT_DEPENDS "${WINDOWS_ICON_PATH}")
message(STATUS "Generating Windows icon from \"${PNG_ICON_PATH}\" via ${FFMPEG_BIN}.")
elseif(NOT USING_DEFAULT_PNG_ICON_PATH)
elseif (NOT USING_DEFAULT_PNG_ICON_PATH)
message(FATAL_ERROR "The specified PNG_ICON_PATH \"${PNG_ICON_PATH}\" is invalid.")
endif()
endif ()
unset(USING_DEFAULT_PNG_ICON_PATH)
endif()
endif()
endif ()
endif ()
# create Windows rc file from template
configure_file(
"${RC_TEMPLATE_FILE}"
"${WINDOWS_RC_FILE}"
)
configure_file("${RC_TEMPLATE_FILE}" "${WINDOWS_RC_FILE}")
# set windres as resource compiler
list(APPEND RES_FILES "${WINDOWS_RC_FILE}")