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

View File

@ -1,195 +1,258 @@
cmake_minimum_required(VERSION 3.3.0 FATAL_ERROR) cmake_minimum_required(VERSION 3.3.0 FATAL_ERROR)
# prevent multiple inclusion # prevent multiple inclusion
if(DEFINED THIRD_PARTY_MODULE_LOADED) if (DEFINED THIRD_PARTY_MODULE_LOADED)
return() return()
endif() endif ()
set(THIRD_PARTY_MODULE_LOADED YES) 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}) 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}) set(CMAKE_FIND_LIBRARY_SUFFIXES ${DEFAULT_CMAKE_FIND_LIBRARY_SUFFIXES})
unset(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 # allows to look for static libraries in particular
if(WIN32) if (WIN32)
set(CMAKE_FIND_LIBRARY_SUFFIXES .a .lib) set(CMAKE_FIND_LIBRARY_SUFFIXES .a .lib)
else() else ()
set(CMAKE_FIND_LIBRARY_SUFFIXES .a) set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
endif() endif ()
endmacro() endmacro ()
macro(configure_dynamic_library_suffixes) macro (configure_dynamic_library_suffixes)
# allows to look for dynamic libraries in particular # allows to look for dynamic libraries in particular
if(WIN32) if (WIN32)
set(CMAKE_FIND_LIBRARY_SUFFIXES .dll .dll.a) set(CMAKE_FIND_LIBRARY_SUFFIXES .dll .dll.a)
elseif(APPLE) elseif (APPLE)
set(CMAKE_FIND_LIBRARY_SUFFIXES .dylib .so) set(CMAKE_FIND_LIBRARY_SUFFIXES .dylib .so)
else() else ()
set(CMAKE_FIND_LIBRARY_SUFFIXES .so) set(CMAKE_FIND_LIBRARY_SUFFIXES .so)
endif() endif ()
endmacro() endmacro ()
macro(link_against_library_varnames NAME LINKAGE REQUIRED PRIVATE_LIBRARIES_VARNAME PUBLIC_LIBRARIES_VARNAME PRIVATE_STATIC_LIBRARIES_VARNAME PUBLIC_STATIC_LIBRARIES_VARNAME) macro (link_against_library_varnames
# determine whether the library is required or optional NAME
# FIXME: improve passing required argument LINKAGE
if("${REQUIRED}" STREQUAL "OPTIONAL") 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") set(${NAME}_REQUIRED "NO")
elseif("${REQUIRED}" STREQUAL "REQUIRED") elseif ("${REQUIRED}" STREQUAL "REQUIRED")
set(${NAME}_REQUIRED "REQUIRED") set(${NAME}_REQUIRED "REQUIRED")
else() else ()
message(FATAL_ERROR "Invalid use of link_against_library; must specify either REQUIRED or OPTIONAL.") 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 # add library to list of libraries to link against when building dynamic libraries or applications - prefer dynamic lib
# - prefer dynamic lib if linkage not explicitely specified # 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"))) 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_${NAME} ON)
set(USE_STATIC_${NAME} ON) set(USE_STATIC_${NAME} ON)
list(APPEND LIBRARIES ${${NAME}_STATIC_LIB}) list(APPEND LIBRARIES ${${NAME}_STATIC_LIB})
message(STATUS "Linking ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} statically against external library ${NAME} (${${NAME}_STATIC_LIB}).") message(
if(${NAME}_STATIC_INCLUDE_DIR) 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}) 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}") message(
endif() STATUS
if(${NAME}_STATIC_COMPILE_DEFINITIONS) "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}) 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}) 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}) list(APPEND PUBLIC_SHARED_INCLUDE_DIRS ${${NAME}_STATIC_INCLUDE_DIR})
endif() endif ()
else() else ()
list(APPEND ${PRIVATE_LIBRARIES_VARNAME} ${${NAME}_STATIC_LIB}) 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}) list(APPEND PRIVATE_SHARED_INCLUDE_DIRS ${${NAME}_STATIC_INCLUDE_DIR})
endif() endif ()
endif() endif ()
# add Qt resources of static library to be enabled # 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}.") message(STATUS "Adding ${${NAME}_QT_RESOURCES} to LIBRARIES_QT_RESOURCES for ${META_PROJECT_NAME}.")
list(APPEND LIBRARIES_QT_RESOURCES ${${NAME}_QT_RESOURCES}) 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_${NAME} ON)
set(USE_SHARED_${NAME} ON) set(USE_SHARED_${NAME} ON)
if(NOT ${NAME}_DYNAMIC_LIB) if (NOT ${NAME}_DYNAMIC_LIB)
set(${NAME}_DYNAMIC_LIB ${${NAME}_SHARED_LIB}) set(${NAME}_DYNAMIC_LIB ${${NAME}_SHARED_LIB})
endif() endif ()
list(APPEND LIBRARIES ${${NAME}_DYNAMIC_LIB}) list(APPEND LIBRARIES ${${NAME}_DYNAMIC_LIB})
message(STATUS "Linking ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} dynamically against external library ${NAME} (${${NAME}_DYNAMIC_LIB}).") message(
if(${NAME}_DYNAMIC_INCLUDE_DIR) 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}) 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}") message(
endif() STATUS
if(${NAME}_DYNAMIC_COMPILE_DEFINITIONS) "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}) 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}) 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}) list(APPEND PUBLIC_SHARED_INCLUDE_DIRS ${${NAME}_DYNAMIC_INCLUDE_DIR})
endif() endif ()
else() else ()
list(APPEND ${PRIVATE_LIBRARIES_VARNAME} ${${NAME}_DYNAMIC_LIB}) 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}) list(APPEND PRIVATE_SHARED_INCLUDE_DIRS ${${NAME}_DYNAMIC_INCLUDE_DIR})
endif() endif ()
endif() endif ()
else() else ()
if(${NAME}_REQUIRED) 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}.") message(
else() FATAL_ERROR
message(WARNING "External library ${NAME} required by ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} is not available for the specified linkage ${LINKAGE}.") "External library ${NAME} required by ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} is not available for the specified linkage ${LINKAGE}."
endif() )
endif() 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 # add library to list of libraries to be provided as transitive dependencies when building static libraries - prefer
# - prefer static lib if linkage not explicitely specified # static lib if linkage not explicitely specified
if(${NAME}_STATIC_LIB AND ("${LINKAGE}" STREQUAL "AUTO_LINKAGE") OR ("${LINKAGE}" STREQUAL "STATIC")) if (${NAME}_STATIC_LIB AND ("${LINKAGE}" STREQUAL "AUTO_LINKAGE") OR ("${LINKAGE}" STREQUAL "STATIC"))
set(USE_${NAME} ON) set(USE_${NAME} ON)
set(USE_STATIC_${NAME} ON) set(USE_STATIC_${NAME} ON)
list(APPEND STATIC_LIBRARIES ${${NAME}_STATIC_LIB}) 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}.") message(
if(${NAME}_STATIC_INCLUDE_DIR) 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}) 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}") message(
endif() 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}) 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}) list(APPEND PUBLIC_STATIC_INCLUDE_DIRS ${${NAME}_STATIC_INCLUDE_DIR})
endif() endif ()
else() else ()
list(APPEND ${PRIVATE_STATIC_LIBRARIES_VARNAME} ${${NAME}_STATIC_LIB}) 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}) list(APPEND PRIVATE_STATIC_INCLUDE_DIRS ${${NAME}_STATIC_INCLUDE_DIR})
endif() endif ()
endif() endif ()
# add Qt resources of static library for exporting it # 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}.") message(STATUS "Adding ${${NAME}_QT_RESOURCES} to STATIC_LIBRARIES_QT_RESOURCES for ${META_PROJECT_NAME}.")
list(APPEND STATIC_LIBRARIES_QT_RESOURCES ${${NAME}_QT_RESOURCES}) 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_${NAME} ON)
set(USE_SHARED_${NAME} ON) set(USE_SHARED_${NAME} ON)
if(NOT ${NAME}_DYNAMIC_LIB) if (NOT ${NAME}_DYNAMIC_LIB)
set(${NAME}_DYNAMIC_LIB ${${NAME}_SHARED_LIB}) set(${NAME}_DYNAMIC_LIB ${${NAME}_SHARED_LIB})
endif() endif ()
list(APPEND STATIC_LIBRARIES ${${NAME}_DYNAMIC_LIB}) 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}.") message(
if(${NAME}_DYNAMIC_INCLUDE_DIR) 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}) 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}") message(
endif() 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}) 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}) list(APPEND PUBLIC_STATIC_INCLUDE_DIRS ${${NAME}_DYNAMIC_INCLUDE_DIR})
endif() endif ()
else() else ()
list(APPEND ${PRIVATE_STATIC_LIBRARIES_VARNAME} ${${NAME}_DYNAMIC_LIB}) 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}) list(APPEND PRIVATE_STATIC_INCLUDE_DIRS ${${NAME}_DYNAMIC_INCLUDE_DIR})
endif() endif ()
endif() endif ()
else() else ()
if(${NAME}_REQUIRED) 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}.") message(
else() FATAL_ERROR
message(WARNING "External library ${NAME} required by ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} is not available for the specified linkage ${LINKAGE}.") "External library ${NAME} required by ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} is not available for the specified linkage ${LINKAGE}."
endif() )
endif() else ()
endmacro() 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) macro (link_against_library NAME LINKAGE REQUIRED)
link_against_library_varnames("${NAME}" "${LINKAGE}" "${REQUIRED}" link_against_library_varnames("${NAME}"
PRIVATE_LIBRARIES PUBLIC_LIBRARIES PRIVATE_STATIC_LIBRARIES PUBLIC_STATIC_LIBRARIES "${LINKAGE}"
) "${REQUIRED}"
endmacro() PRIVATE_LIBRARIES
PUBLIC_LIBRARIES
PRIVATE_STATIC_LIBRARIES
PUBLIC_STATIC_LIBRARIES)
endmacro ()
macro(link_tests_against_library NAME LINKAGE REQUIRED) macro (link_tests_against_library NAME LINKAGE REQUIRED)
link_against_library_varnames("${NAME}" "${LINKAGE}" "${REQUIRED}" link_against_library_varnames("${NAME}"
TEST_LIBRARIES TEST_LIBRARIES STATIC_TEST_LIBRARIES STATIC_TEST_LIBRARIES "${LINKAGE}"
) "${REQUIRED}"
endmacro() 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_INCLUDE_DIR NOTFOUND CACHE PATH "${NAME} include dir (dynamic)")
set(${NAME}_DYNAMIC_LIB NOTFOUND CACHE FILEPATH "${NAME} lib (dynamic)") set(${NAME}_DYNAMIC_LIB NOTFOUND CACHE FILEPATH "${NAME} lib (dynamic)")
set(${NAME}_STATIC_INCLUDE_DIR NOTFOUND CACHE PATH "${NAME} include dir (static)") 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() save_default_library_suffixes()
if(NOT ${NAME}_DYNAMIC_LIB) if (NOT ${NAME}_DYNAMIC_LIB)
configure_dynamic_library_suffixes() configure_dynamic_library_suffixes()
find_library(DETECTED_${NAME}_DYNAMIC_LIB ${NAME}) find_library(DETECTED_${NAME}_DYNAMIC_LIB ${NAME})
set(${NAME}_DYNAMIC_LIB ${DETECTED_${NAME}_DYNAMIC_LIB} CACHE FILEPATH "${NAME} lib (dynamic)" FORCE) 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() configure_static_library_suffixes()
find_library(DETECTED_${NAME}_STATIC_LIB ${NAME}) find_library(DETECTED_${NAME}_STATIC_LIB ${NAME})
set(${NAME}_STATIC_LIB ${DETECTED_${NAME}_STATIC_LIB} CACHE FILEPATH "${NAME} lib (static)" FORCE) set(${NAME}_STATIC_LIB ${DETECTED_${NAME}_STATIC_LIB} CACHE FILEPATH "${NAME} lib (static)" FORCE)
endif() endif ()
restore_default_library_suffixes() 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}") find_external_library("${NAME}" "${LINKAGE}" "${REQUIRED}")
link_against_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 # internally used by find_external_library_from_package to find dynamic libraries
configure_dynamic_library_suffixes() configure_dynamic_library_suffixes()
find_package(${PKGNAME} ${COMPAT_VERSION}) find_package(${PKGNAME} ${COMPAT_VERSION})
set(${NAME}_DYNAMIC_INCLUDE_DIR ${${INCLUDE_VAR}} CACHE PATH "${NAME} include dir (dynamic)" FORCE) 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) 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 # internally used by find_external_library_from_package to find static libraries
configure_static_library_suffixes() configure_static_library_suffixes()
find_package(${PKGNAME} ${COMPAT_VERSION}) find_package(${PKGNAME} ${COMPAT_VERSION})
set(${NAME}_STATIC_INCLUDE_DIR ${${INCLUDE_VAR}} CACHE PATH "${NAME} include dir (static)" FORCE) 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) 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 # handle specified VERSION
if("${VERSION}" STREQUAL "ANY_VERSION") if ("${VERSION}" STREQUAL "ANY_VERSION")
set(${NAME}_COMPATIBLE_VERSION "") set(${NAME}_COMPATIBLE_VERSION "")
else() else ()
set(${NAME}_COMPATIBLE_VERSION ${VERSION}) set(${NAME}_COMPATIBLE_VERSION ${VERSION})
endif() endif ()
# use the find_library approach first because it is less buggy when trying to detect static libraries # use the find_library approach first because it is less buggy when trying to detect static libraries caveat: this way
# caveat: this way include dirs are not detected - however those are mostly the default anyways and # include dirs are not detected - however those are mostly the default anyways and can also be set manually by the user
# can also be set manually by the user in case the auto-detection is not sufficient # in case the auto-detection is not sufficient
find_external_library("${NAME}" "${LINKAGE}" OPTIONAL) find_external_library("${NAME}" "${LINKAGE}" OPTIONAL)
# fall back to actual use of find_package # fall back to actual use of find_package use separate functions to get a new scope
# use separate functions to get a new scope
save_default_library_suffixes() save_default_library_suffixes()
if(NOT ${NAME}_DYNAMIC_LIB) if (NOT ${NAME}_DYNAMIC_LIB)
use_external_library_from_package_dynamic(${NAME} ${PKGNAME} ${INCLUDE_VAR} "${LIBRARY_VAR}" "${${NAME}_COMPATIBLE_VERSION}") use_external_library_from_package_dynamic(${NAME}
endif() ${PKGNAME}
if(NOT ${NAME}_STATIC_LIB) ${INCLUDE_VAR}
use_external_library_from_package_static(${NAME} ${PKGNAME} ${INCLUDE_VAR} "${LIBRARY_VAR}" "${${NAME}_COMPATIBLE_VERSION}") "${LIBRARY_VAR}"
endif() "${${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() restore_default_library_suffixes()
endmacro() endmacro ()
macro(use_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}") find_external_library_from_package("${NAME}"
"${PKGNAME}"
"${VERSION}"
"${INCLUDE_VAR}"
"${LIBRARY_VAR}"
"${LINKAGE}"
"${REQUIRED}")
link_against_library("${NAME}" "${LINKAGE}" "${REQUIRED}") link_against_library("${NAME}" "${LINKAGE}" "${REQUIRED}")
endmacro() endmacro ()
macro(use_iconv LINKAGE REQUIRED) 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)") set(FORCE_EXTERNAL_ICONV OFF
if(NOT FORCE_EXTERNAL_ICONV) 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 # check whether iconv exists in standard lib
include(CheckFunctionExists) include(CheckFunctionExists)
check_function_exists(iconv HAS_ICONV) check_function_exists(iconv HAS_ICONV)
endif() endif ()
if(NOT FORCE_EXTERNAL_ICONV AND HAS_ICONV) if (NOT FORCE_EXTERNAL_ICONV AND HAS_ICONV)
message(STATUS "Using iconv from the standard library for ${META_PROJECT_NAME}.") message(STATUS "Using iconv from the standard library for ${META_PROJECT_NAME}.")
else() else ()
# find external iconv library # find external iconv library
use_external_library(iconv ${LINKAGE} ${REQUIRED}) use_external_library(iconv ${LINKAGE} ${REQUIRED})
endif() endif ()
endmacro() 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.") message(FATAL_ERROR "Before including the AppTarget module, the BasicConfig module must be included.")
endif() endif ()
if(TARGET_CONFIG_DONE) if (TARGET_CONFIG_DONE)
message(FATAL_ERROR "Can not include AppTarget module when targets are already configured.") message(FATAL_ERROR "Can not include AppTarget module when targets are already configured.")
endif() endif ()
# check whether project type is set correctly # check whether project type is set correctly
if(NOT "${META_PROJECT_TYPE}" STREQUAL "application") 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).") message(
endif() 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 # set the windows extension to "exe", this is required by the Windows specific WindowsResources module
if(WIN32) if (WIN32)
set(WINDOWS_EXT "exe") set(WINDOWS_EXT "exe")
endif(WIN32) endif (WIN32)
# set compile definitions # set compile definitions
if(NOT META_PUBLIC_SHARED_LIB_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}) set(META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS ${META_PUBLIC_COMPILE_DEFINITIONS}
endif() ${META_ADDITIONAL_PUBLIC_SHARED_COMPILE_DEFINITIONS})
if(NOT META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS) endif ()
set(META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS ${META_PRIVATE_COMPILE_DEFINITIONS} ${META_ADDITIONAL_PRIVATE_SHARED_COMPILE_DEFINITIONS}) if (NOT META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS)
if(STATIC_LINKAGE) 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) list(APPEND META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS APP_STATICALLY_LINKED)
endif() endif ()
endif() endif ()
# set linker flags # set linker flags
if(STATIC_LINKAGE) if (STATIC_LINKAGE)
set(ACTUAL_ADDITIONAL_LINK_FLAGS ${META_ADDITIONAL_STATIC_LINK_FLAGS}) set(ACTUAL_ADDITIONAL_LINK_FLAGS ${META_ADDITIONAL_STATIC_LINK_FLAGS})
else() else ()
set(ACTUAL_ADDITIONAL_LINK_FLAGS ${META_ADDITIONAL_LINK_FLAGS}) set(ACTUAL_ADDITIONAL_LINK_FLAGS ${META_ADDITIONAL_LINK_FLAGS})
endif() endif ()
# define relevant files # define relevant files
set(ALL_FILES ${HEADER_FILES} ${SRC_FILES} ${GENERATED_DBUS_FILES} ${WIDGETS_FILES} ${QML_FILES} ${RES_FILES} ${WINDOWS_ICON_PATH}) set(ALL_FILES
if(NOT BUILTIN_TRANSLATIONS) ${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}) list(APPEND ALL_FILES ${QM_FILES})
endif() endif ()
# add target for building the application # add target for building the application
if (NOT ANDROID) if (NOT ANDROID)
add_executable(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} ${GUI_TYPE} ${ALL_FILES}) 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 # 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}) 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} target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
PUBLIC ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}" PUBLIC ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}"
PRIVATE "${PRIVATE_LIBRARIES}" PRIVATE "${PRIVATE_LIBRARIES}")
)
target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
PUBLIC PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> $<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> ${PUBLIC_SHARED_INCLUDE_DIRS}
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> PRIVATE "${PRIVATE_SHARED_INCLUDE_DIRS}")
${PUBLIC_SHARED_INCLUDE_DIRS}
PRIVATE
"${PRIVATE_SHARED_INCLUDE_DIRS}"
)
target_compile_definitions(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} target_compile_definitions(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS}" PUBLIC
PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS}" "${META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS}"
) PRIVATE
"${META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS}")
target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}" PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}"
PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}" PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}")
) set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} PROPERTIES PROPERTIES CXX_STANDARD
CXX_STANDARD "${META_CXX_STANDARD}" "${META_CXX_STANDARD}"
LINK_SEARCH_START_STATIC ${STATIC_LINKAGE} LINK_SEARCH_START_STATIC
LINK_SEARCH_END_STATIC ${STATIC_LINKAGE} ${STATIC_LINKAGE}
AUTOGEN_TARGET_DEPENDS "${AUTOGEN_DEPS}" 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 # add install target for binary
if(APPLE) if (APPLE)
set(BUNDLE_INSTALL_DESTINATION bin CACHE STRING "specifies the install destination for bundles") set(BUNDLE_INSTALL_DESTINATION bin CACHE STRING "specifies the install destination for bundles")
install(TARGETS ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} install(TARGETS ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
RUNTIME DESTINATION bin RUNTIME DESTINATION bin
BUNDLE DESTINATION "${BUNDLE_INSTALL_DESTINATION}" BUNDLE DESTINATION "${BUNDLE_INSTALL_DESTINATION}" COMPONENT binary)
COMPONENT binary elseif (ANDROID)
)
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()
install(TARGETS ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} install(TARGETS ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
RUNTIME DESTINATION bin RUNTIME DESTINATION bin COMPONENT binary
COMPONENT binary LIBRARY DESTINATION lib${SELECTED_LIB_SUFFIX} COMPONENT binary
) ARCHIVE DESTINATION lib${SELECTED_LIB_SUFFIX} COMPONENT binary)
endif() 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 add_custom_target(install-binary
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=binary -P "${CMAKE_BINARY_DIR}/cmake_install.cmake" COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=binary -P
) "${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif() endif ()
add_dependencies(install-binary ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}) add_dependencies(install-binary ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX})
# add mingw-w64 specific install target # 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_custom_target(install-mingw-w64)
add_dependencies(install-mingw-w64 install-binary) add_dependencies(install-mingw-w64 install-binary)
endif() endif ()
add_dependencies(install-mingw-w64 ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}) add_dependencies(install-mingw-w64 ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX})
# add install target for desktop entries and icons # add install target for desktop entries and icons
foreach(DESKTOP_FILE ${DESKTOP_FILES}) foreach (DESKTOP_FILE ${DESKTOP_FILES})
install( install(FILES "${DESKTOP_FILE}" DESTINATION "share/applications" COMPONENT desktop)
FILES "${DESKTOP_FILE}" endforeach ()
DESTINATION "share/applications"
COMPONENT desktop
)
endforeach()
foreach(ICON_FILE ${ICON_FILES}) foreach (ICON_FILE ${ICON_FILES})
install( install(FILES "${ICON_FILE}" DESTINATION "share/icons/hicolor/scalable/apps" COMPONENT desktop)
FILES "${ICON_FILE}" endforeach ()
DESTINATION "share/icons/hicolor/scalable/apps" if (NOT TARGET install-desktop)
COMPONENT desktop
)
endforeach()
if(NOT TARGET install-desktop)
add_custom_target(install-desktop add_custom_target(install-desktop
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=desktop -P "${CMAKE_BINARY_DIR}/cmake_install.cmake" COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=desktop -P
) "${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif() endif ()
add_dependencies(install-desktop ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}) 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 add_custom_target(install-appimage
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=appimage -P "${CMAKE_BINARY_DIR}/cmake_install.cmake" COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=appimage -P
) "${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif() endif ()
add_dependencies(install-appimage ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}) add_dependencies(install-appimage ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX})
# add install target for stripped binaries # add install target for stripped binaries
if(NOT TARGET install-binary-strip) if (NOT TARGET install-binary-strip)
add_custom_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" COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_DO_STRIP=1 -DCMAKE_INSTALL_COMPONENT=binary -P
) "${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif() endif ()
add_dependencies(install-binary-strip ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}) add_dependencies(install-binary-strip ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX})
# add mingw-w64 specific install targets # add mingw-w64 specific install targets
if(MINGW) if (MINGW)
if(NOT TARGET install-mingw-w64) if (NOT TARGET install-mingw-w64)
add_custom_target(install-mingw-w64) add_custom_target(install-mingw-w64)
add_dependencies(install-mingw-w64 install-binary) add_dependencies(install-mingw-w64 install-binary)
endif() endif ()
if(NOT TARGET install-mingw-w64-strip) if (NOT TARGET install-mingw-w64-strip)
add_custom_target(install-mingw-w64-strip) add_custom_target(install-mingw-w64-strip)
add_dependencies(install-mingw-w64-strip install-binary-strip) add_dependencies(install-mingw-w64-strip install-binary-strip)
endif() endif ()
if(LOCALIZATION_TARGET) if (LOCALIZATION_TARGET)
add_dependencies(install-mingw-w64 ${LOCALIZATION_TARGET}) add_dependencies(install-mingw-w64 ${LOCALIZATION_TARGET})
add_dependencies(install-mingw-w64-strip ${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 # add target for launching application with wine ensuring the WINEPATH is set correctly so wine is able to find all required
# requires script from c++utilities, hence the sources of c++utilities must be present # *.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 (MINGW AND CMAKE_CROSSCOMPILING AND CPP_UTILITIES_SOURCE_DIR)
if(NOT TARGET ${META_PROJECT_NAME}_run) if (NOT TARGET ${META_PROJECT_NAME}_run)
if(CMAKE_FIND_ROOT_PATH) if (CMAKE_FIND_ROOT_PATH)
list(APPEND RUNTIME_LIBRARY_PATH "${CMAKE_FIND_ROOT_PATH}/bin") list(APPEND RUNTIME_LIBRARY_PATH "${CMAKE_FIND_ROOT_PATH}/bin")
endif() 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_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}) add_dependencies(${META_PROJECT_NAME}_run ${META_PROJECT_NAME})
endif() endif ()
endif() endif ()
# find template for *.desktop files # find template for *.desktop files
include(TemplateFinder) include(TemplateFinder)
find_template_file("desktop" CPP_UTILITIES APP_DESKTOP_TEMPLATE_FILE) find_template_file("desktop" CPP_UTILITIES APP_DESKTOP_TEMPLATE_FILE)
find_template_file("appdata.xml" CPP_UTILITIES APP_APPSTREAM_TEMPLATE_FILE) find_template_file("appdata.xml" CPP_UTILITIES APP_APPSTREAM_TEMPLATE_FILE)
# function to add *.desktop files with additional entries # function to add *.desktop files with additional entries FIXME v5: use "include(CMakeParseArguments)" like in
# FIXME v5: use "include(CMakeParseArguments)" like in ReflectionGenerator.cmake # ReflectionGenerator.cmake
function(add_custom_desktop_file_with_additional_entries function (add_custom_desktop_file_with_additional_entries
FILE_NAME FILE_NAME
DESKTOP_FILE_APP_NAME DESKTOP_FILE_APP_NAME
DESKTOP_FILE_GENERIC_NAME DESKTOP_FILE_GENERIC_NAME
DESKTOP_FILE_DESCRIPTION DESKTOP_FILE_DESCRIPTION
DESKTOP_FILE_CATEGORIES DESKTOP_FILE_CATEGORIES
DESKTOP_FILE_CMD DESKTOP_FILE_CMD
DESKTOP_FILE_ICON DESKTOP_FILE_ICON
DESKTOP_FILE_ADDITIONAL_ENTRIES) DESKTOP_FILE_ADDITIONAL_ENTRIES)
# create desktop file from template # create desktop file from template
configure_file( configure_file("${APP_DESKTOP_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/resources/${FILE_NAME}.desktop")
"${APP_DESKTOP_TEMPLATE_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/resources/${FILE_NAME}.desktop"
)
# add install for the desktop file # add install for the desktop file
install( install(FILES "${CMAKE_CURRENT_BINARY_DIR}/resources/${FILE_NAME}.desktop"
FILES "${CMAKE_CURRENT_BINARY_DIR}/resources/${FILE_NAME}.desktop" DESTINATION "share/applications"
DESTINATION "share/applications" COMPONENT desktop)
COMPONENT desktop endfunction ()
)
endfunction()
# function to add *.desktop files # function to add *.desktop files
function(add_custom_desktop_file function (add_custom_desktop_file
FILE_NAME FILE_NAME
DESKTOP_FILE_APP_NAME DESKTOP_FILE_APP_NAME
DESKTOP_FILE_GENERIC_NAME DESKTOP_FILE_GENERIC_NAME
DESKTOP_FILE_DESCRIPTION DESKTOP_FILE_DESCRIPTION
DESKTOP_FILE_CATEGORIES DESKTOP_FILE_CATEGORIES
DESKTOP_FILE_CMD DESKTOP_FILE_CMD
DESKTOP_FILE_ICON) DESKTOP_FILE_ICON)
add_custom_desktop_file_with_additional_entries( add_custom_desktop_file_with_additional_entries("${FILE_NAME}"
"${FILE_NAME}" "${DESKTOP_FILE_APP_NAME}"
"${DESKTOP_FILE_APP_NAME}" "${DESKTOP_FILE_GENERIC_NAME}"
"${DESKTOP_FILE_GENERIC_NAME}" "${DESKTOP_FILE_DESCRIPTION}"
"${DESKTOP_FILE_DESCRIPTION}" "${DESKTOP_FILE_CATEGORIES}"
"${DESKTOP_FILE_CATEGORIES}" "${DESKTOP_FILE_CMD}"
"${DESKTOP_FILE_CMD}" "${DESKTOP_FILE_ICON}"
"${DESKTOP_FILE_ICON}" "")
"" endfunction ()
)
endfunction()
# convenience function to add *.desktop file and meta info from project meta data # convenience function to add *.desktop file and meta info from project meta data
function(add_desktop_file) function (add_desktop_file)
# compose actions # compose actions
set(DESKTOP_FILE_ADDITIONAL_ENTRIES "") 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} 0 ACTION_ID)
list(GET META_APP_ACTION_${ACTION_VAR} 1 ACTION_NAME) list(GET META_APP_ACTION_${ACTION_VAR} 1 ACTION_NAME)
list(GET META_APP_ACTION_${ACTION_VAR} 2 ACTION_ARGS) 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}") set(
endforeach() 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 # create desktop file
add_custom_desktop_file_with_additional_entries( add_custom_desktop_file_with_additional_entries("${META_ID}"
"${META_ID}" "${META_APP_NAME}"
"${META_APP_NAME}" "${META_GENERIC_NAME}"
"${META_GENERIC_NAME}" "${META_APP_DESCRIPTION}"
"${META_APP_DESCRIPTION}" "${META_APP_CATEGORIES}"
"${META_APP_CATEGORIES}" "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}"
"${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}" "${META_PROJECT_NAME}"
"${META_PROJECT_NAME}" "${DESKTOP_FILE_ADDITIONAL_ENTRIES}")
"${DESKTOP_FILE_ADDITIONAL_ENTRIES}"
)
# read body for appstream desktop file from resources # 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_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") set(META_APP_APPDATA_SUBSTITUTED_BODY_FILE "${CMAKE_CURRENT_BINARY_DIR}/resources/${META_ID}.body.appdata.xml")
if(EXISTS "${META_APP_APPDATA_BODY_FILE}") if (EXISTS "${META_APP_APPDATA_BODY_FILE}")
configure_file( configure_file("${META_APP_APPDATA_BODY_FILE}" "${META_APP_APPDATA_SUBSTITUTED_BODY_FILE}" @ONLY)
"${META_APP_APPDATA_BODY_FILE}"
"${META_APP_APPDATA_SUBSTITUTED_BODY_FILE}"
@ONLY
)
file(READ "${META_APP_APPDATA_SUBSTITUTED_BODY_FILE}" META_APP_APPDATA_BODY) file(READ "${META_APP_APPDATA_SUBSTITUTED_BODY_FILE}" META_APP_APPDATA_BODY)
# add indentation of two additional spaces # add indentation of two additional spaces
string(REGEX REPLACE "\n([^$])" "\n \\1" META_APP_APPDATA_BODY "${META_APP_APPDATA_BODY}") string(REGEX
endif() REPLACE "\n([^$])"
"\n \\1"
META_APP_APPDATA_BODY
"${META_APP_APPDATA_BODY}")
endif ()
# create appstream desktop file from template # create appstream desktop file from template
configure_file( configure_file("${APP_APPSTREAM_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/resources/${META_ID}.appdata.xml" @ONLY)
"${APP_APPSTREAM_TEMPLATE_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/resources/${META_ID}.appdata.xml"
@ONLY
)
# add install for the appstream file # add install for the appstream file
install( install(FILES "${CMAKE_CURRENT_BINARY_DIR}/resources/${META_ID}.appdata.xml"
FILES "${CMAKE_CURRENT_BINARY_DIR}/resources/${META_ID}.appdata.xml" DESTINATION "share/metainfo"
DESTINATION "share/metainfo" COMPONENT appimage)
COMPONENT appimage endfunction ()
)
endfunction()
set(TARGET_CONFIG_DONE YES) set(TARGET_CONFIG_DONE YES)

View File

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

View File

@ -1,64 +1,69 @@
# before including this module, all relevant variables must be set # before including this module, all relevant variables must be set just include this module as last one since nothing should
# just include this module as last one since nothing should depend on it # 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.") message(FATAL_ERROR "Before including the ConfigHeader module, the AppTarget/LibraryTarget module must be included.")
endif() endif ()
# find config.h template # find config.h template
include(TemplateFinder) include(TemplateFinder)
find_template_file("config.h" CPP_UTILITIES CONFIG_H_TEMPLATE_FILE) 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 # create list of dependency versions present at link time (one list for shared library and another for the static library
# the static library since the lists might differ) # since the lists might differ)
include(ListToString) include(ListToString)
foreach(LINKAGE IN ITEMS "" "STATIC_") foreach (LINKAGE IN ITEMS "" "STATIC_")
unset(DEPENCENCY_VERSIONS) unset(DEPENCENCY_VERSIONS)
unset(${LINKAGE}DEPENCENCY_VERSIONS_ARRAY) unset(${LINKAGE}DEPENCENCY_VERSIONS_ARRAY)
# iterate through public and private libraries of shared/static library # iterate through public and private libraries of shared/static library
foreach(DEPENDENCY IN LISTS PUBLIC_${LINKAGE}LIBRARIES PRIVATE_${LINKAGE}LIBRARIES) foreach (DEPENDENCY IN LISTS PUBLIC_${LINKAGE}LIBRARIES PRIVATE_${LINKAGE}LIBRARIES)
if(TARGET ${DEPENDENCY}) if (TARGET ${DEPENDENCY})
unset(DEPENDENCY_DISPLAY_NAME) unset(DEPENDENCY_DISPLAY_NAME)
unset(DEPENDENCY_VER) unset(DEPENDENCY_VER)
# find version and display name for target # 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 # read meta-data of Qt module
set(DEPENDENCY_MODULE_NAME "${CMAKE_MATCH_2}") set(DEPENDENCY_MODULE_NAME "${CMAKE_MATCH_2}")
set(DEPENDENCY_DISPLAY_NAME "Qt ${DEPENDENCY_MODULE_NAME}") set(DEPENDENCY_DISPLAY_NAME "Qt ${DEPENDENCY_MODULE_NAME}")
set(DEPENDENCY_VER "${Qt5${DEPENDENCY_MODULE_NAME}_VERSION_STRING}") set(DEPENDENCY_VER "${Qt5${DEPENDENCY_MODULE_NAME}_VERSION_STRING}")
elseif(${DEPENDENCY}_varname) elseif (${DEPENDENCY}_varname)
# read meta-data of one of my own libraries # read meta-data of one of my own libraries
set(DEPENDENCY_VARNAME "${${DEPENDENCY}_varname}") set(DEPENDENCY_VARNAME "${${DEPENDENCY}_varname}")
set(DEPENDENCY_DISPLAY_NAME "${DEPENDENCY}") set(DEPENDENCY_DISPLAY_NAME "${DEPENDENCY}")
if(${DEPENDENCY_VARNAME}_DISPLAY_NAME) if (${DEPENDENCY_VARNAME}_DISPLAY_NAME)
set(DEPENDENCY_DISPLAY_NAME "${${DEPENDENCY_VARNAME}_DISPLAY_NAME}") set(DEPENDENCY_DISPLAY_NAME "${${DEPENDENCY_VARNAME}_DISPLAY_NAME}")
endif() endif ()
set(DEPENDENCY_VER "${${DEPENDENCY_VARNAME}_VERSION}") set(DEPENDENCY_VER "${${DEPENDENCY_VARNAME}_VERSION}")
endif() endif ()
# FIXME: provide meta-data for other libs, too # 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}") list(APPEND DEPENCENCY_VERSIONS "${DEPENDENCY_DISPLAY_NAME}: ${DEPENDENCY_VER}")
endif() endif ()
endif() endif ()
endforeach() endforeach ()
if(DEPENCENCY_VERSIONS) if (DEPENCENCY_VERSIONS)
list_to_string("," " \\\n \"" "\"" "${DEPENCENCY_VERSIONS}" ${LINKAGE}DEPENCENCY_VERSIONS_ARRAY) list_to_string("," " \\\n \"" "\"" "${DEPENCENCY_VERSIONS}" ${LINKAGE}DEPENCENCY_VERSIONS_ARRAY)
endif() endif ()
endforeach() endforeach ()
# add configuration header # add configuration header
configure_file( configure_file("${CONFIG_H_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/resources/config.h")
"${CONFIG_H_TEMPLATE_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/resources/config.h"
)
# ensure generated include files can be included via #include "resources/config.h" # ensure generated include files can be included via #include "resources/config.h"
if(NOT META_HEADER_ONLY_LIB) 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) foreach (TARGET_NAME
if(TARGET ${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}") target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
endif() endif ()
endforeach() endforeach ()
endif() 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.") 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) option(NO_DOXYGEN "whether creation of Doxygen targets is disabled (enabled by default)" OFF)
if(NO_DOXYGEN) if (NO_DOXYGEN)
return() return()
endif() endif ()
# find doxygen.h template # find doxygen.h template
include(TemplateFinder) include(TemplateFinder)
@ -15,31 +15,41 @@ find_template_file("doxygen" CPP_UTILITIES DOXYGEN_TEMPLATE_FILE)
find_program(DOXYGEN_BIN doxygen) find_program(DOXYGEN_BIN doxygen)
find_program(PERL_BIN perl) find_program(PERL_BIN perl)
find_program(DIA_BIN dia) find_program(DIA_BIN dia)
if(DIA_BIN) if (DIA_BIN)
set(HAVE_DIA "YES") set(HAVE_DIA "YES")
else() else ()
set(HAVE_DIA "NO") set(HAVE_DIA "NO")
endif() endif ()
find_program(DOT_BIN dot) find_program(DOT_BIN dot)
if(DOT_BIN) if (DOT_BIN)
set(HAVE_DOT "YES") set(HAVE_DOT "YES")
else() else ()
set(HAVE_DOT "NO") set(HAVE_DOT "NO")
endif() endif ()
if(NOT DOXYGEN_BIN) 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}") message(
WARNING
"Doxygen not found, unable to add target for generating API documentation for ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}"
)
return() return()
endif() endif ()
# load cached configuration and other variables # load cached configuration and other variables
set(DOXY_LANGUAGE "English" CACHE STRING "specifies the language of the API documentation generated with Doxygen") 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_CUSTOM_CONFIG "" CACHE STRING "specifies extra options for Doxygen")
set(DOXY_NUMBER "${META_APP_VERSION}") set(DOXY_NUMBER "${META_APP_VERSION}")
set(DOXY_INPUT_FILES set(DOXY_INPUT_FILES
${HEADER_FILES} ${SRC_FILES} ${TEST_HEADER_FILES} ${TEST_SRC_FILES} ${WIDGETS_HEADER_FILES} ${WIDGETS_SRC_FILES} ${HEADER_FILES}
${QML_HEADER_FILES} ${QML_SRC_FILES} ${DOC_FILES} ${DOC_ONLY_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}/") set(DOXY_PATH_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/")
list(GET DOC_FILES 0 DOXY_MAIN_PAGE_FILE) list(GET DOC_FILES 0 DOXY_MAIN_PAGE_FILE)
set(DOXY_MAIN_PAGE_FILE "${DOXY_PATH_PREFIX}${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) list_to_string(" " "\"${DOXY_PATH_PREFIX}" "\"" "${DOXY_INPUT_FILES}" DOXY_INPUT_FILES_WHITESPACE_SEPARATED)
# generate Doxygen configuration # generate Doxygen configuration
configure_file( configure_file("${DOXYGEN_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/doxygen.config")
"${DOXYGEN_TEMPLATE_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/doxygen.config"
)
# add target for generating API documentation # add target for generating API documentation
add_custom_target("${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_apidoc" add_custom_target("${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_apidoc"
COMMAND "${DOXYGEN_BIN}" "${CMAKE_CURRENT_BINARY_DIR}/doxygen.config" COMMAND "${DOXYGEN_BIN}" "${CMAKE_CURRENT_BINARY_DIR}/doxygen.config")
) if (NOT TARGET apidoc)
if(NOT TARGET apidoc)
add_custom_target(apidoc) add_custom_target(apidoc)
endif() endif ()
add_dependencies(apidoc "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_apidoc") add_dependencies(apidoc "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_apidoc")
# add install target for API documentation # 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" install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/api-doc"
DESTINATION "share/${META_PROJECT_NAME}" DESTINATION "share/${META_PROJECT_NAME}"
COMPONENT api-doc COMPONENT api-doc
OPTIONAL OPTIONAL)
) if (NOT TARGET install-api-doc)
if(NOT TARGET install-api-doc)
add_custom_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" COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=api-doc -P
) "${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif() endif ()
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) 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.") message(FATAL_ERROR "Before including the LibraryTarget module, the BasicConfig module must be included.")
endif() endif ()
if(TARGET_CONFIG_DONE) if (TARGET_CONFIG_DONE)
message(FATAL_ERROR "Can not include LibraryTarget module when targets are already configured.") message(FATAL_ERROR "Can not include LibraryTarget module when targets are already configured.")
endif() endif ()
# check whether project type is set correctly # 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) set(META_IS_PLUGIN YES)
endif() endif ()
if((NOT "${META_PROJECT_TYPE}" STREQUAL "library") AND (NOT "${META_PROJECT_TYPE}" STREQUAL "") AND NOT META_IS_PLUGIN) 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).") message(
endif() 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 # includes for configure_package_config_file, write_basic_package_version_file and find_template_file
include(CMakePackageConfigHelpers) 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") 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) # remove library prefix when building with mingw-w64 (just for consistency with qmake)
if(MINGW) if (MINGW)
set(CMAKE_SHARED_LIBRARY_PREFIX "") 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 # set the windows extension to "dll", this is required by the mingw-w64 specific WindowsResources module
if(MINGW) if (MINGW)
set(WINDOWS_EXT "dll") set(WINDOWS_EXT "dll")
endif(MINGW) endif (MINGW)
# set compile definitions # set compile definitions
if(NOT META_PUBLIC_SHARED_LIB_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}) set(META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS ${META_PUBLIC_COMPILE_DEFINITIONS}
endif() ${META_ADDITIONAL_PUBLIC_SHARED_COMPILE_DEFINITIONS})
if(NOT META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS) endif ()
set(META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS ${META_PRIVATE_COMPILE_DEFINITIONS} ${META_ADDITIONAL_PRIVATE_SHARED_COMPILE_DEFINITIONS}) if (NOT META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS)
endif() set(META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS ${META_PRIVATE_COMPILE_DEFINITIONS}
if(NOT META_PUBLIC_STATIC_LIB_COMPILE_DEFINITIONS) ${META_ADDITIONAL_PRIVATE_SHARED_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 ()
endif() if (NOT META_PUBLIC_STATIC_LIB_COMPILE_DEFINITIONS)
if(NOT META_PRIVATE_STATIC_LIB_COMPILE_DEFINITIONS) set(META_PUBLIC_STATIC_LIB_COMPILE_DEFINITIONS
set(META_PRIVATE_STATIC_LIB_COMPILE_DEFINITIONS ${META_PRIVATE_COMPILE_DEFINITIONS} ${META_ADDITIONAL_PRIVATE_STATIC_COMPILE_DEFINITIONS}) ${META_PUBLIC_COMPILE_DEFINITIONS}
endif() ${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 # add global library-specific header
find_template_file("global.h" CPP_UTILITIES GLOBAL_H_TEMPLATE_FILE) 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\"") set(GENERAL_GLOBAL_H_INCLUDE_PATH "\"./application/global.h\"")
else() else ()
set(GENERAL_GLOBAL_H_INCLUDE_PATH "<c++utilities/application/global.h>") set(GENERAL_GLOBAL_H_INCLUDE_PATH "<c++utilities/application/global.h>")
endif() endif ()
configure_file( configure_file("${GLOBAL_H_TEMPLATE_FILE}"
"${GLOBAL_H_TEMPLATE_FILE}" "${CMAKE_CURRENT_SOURCE_DIR}/global.h" # simply add this to source to ease inclusion
"${CMAKE_CURRENT_SOURCE_DIR}/global.h" # simply add this to source to ease inclusion NEWLINE_STYLE UNIX # since this goes to sources ensure consistency
NEWLINE_STYLE UNIX # since this goes to sources ensure consistency )
)
list(APPEND HEADER_FILES global.h) list(APPEND HEADER_FILES global.h)
# determine SOVERSION # determine SOVERSION
if(NOT META_SOVERSION AND NOT META_IS_PLUGIN) if (NOT META_SOVERSION AND NOT META_IS_PLUGIN)
if(META_VERSION_EXACT_SONAME) if (META_VERSION_EXACT_SONAME)
set(META_SOVERSION "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}") set(META_SOVERSION "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}")
else() else ()
set(META_SOVERSION "${META_VERSION_MAJOR}") 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}") message(STATUS "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}: BUILD_SHARED_LIBS=${BUILD_SHARED_LIBS}")
# define relevant files # define relevant files
set(ALL_FILES ${HEADER_FILES} ${SRC_FILES} ${GENERATED_DBUS_FILES} ${WIDGETS_FILES} ${QML_FILES} ${RES_FILES} ${WINDOWS_ICON_PATH}) set(ALL_FILES
if(NOT BUILTIN_TRANSLATIONS) ${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}) list(APPEND ALL_FILES ${QM_FILES})
endif() endif ()
# determine include path used when building the project itself # 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 # use special include directory if available
set(TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include") set(TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include")
else() else ()
# use the project folder itself # use the project folder itself
set(TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/..") set(TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/..")
endif() endif ()
# add target for building the library # add target for building the library
if(BUILD_SHARED_LIBS) if (BUILD_SHARED_LIBS)
if(STATIC_LIBRARY_LINKAGE) if (STATIC_LIBRARY_LINKAGE)
set(ACTUAL_ADDITIONAL_LINK_FLAGS ${META_ADDITIONAL_STATIC_LINK_FLAGS}) set(ACTUAL_ADDITIONAL_LINK_FLAGS ${META_ADDITIONAL_STATIC_LINK_FLAGS})
else() else ()
set(ACTUAL_ADDITIONAL_LINK_FLAGS ${META_ADDITIONAL_SHARED_LINK_FLAGS}) set(ACTUAL_ADDITIONAL_LINK_FLAGS ${META_ADDITIONAL_SHARED_LINK_FLAGS})
endif() endif ()
if(META_IS_PLUGIN) if (META_IS_PLUGIN)
set(META_SHARED_OBJECT_TYPE MODULE) set(META_SHARED_OBJECT_TYPE MODULE)
else() else ()
set(META_SHARED_OBJECT_TYPE SHARED) set(META_SHARED_OBJECT_TYPE SHARED)
endif() endif ()
# add library to be created, set libs to link against, set version and C++ standard # 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) add_library(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} INTERFACE)
target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
INTERFACE ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}" "${PRIVATE_LIBRARIES}" INTERFACE ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}" "${PRIVATE_LIBRARIES}")
) target_include_directories(
target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
INTERFACE INTERFACE $<BUILD_INTERFACE:${TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE}>
$<BUILD_INTERFACE:${TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE}> $<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> ${PUBLIC_SHARED_INCLUDE_DIRS})
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}>
${PUBLIC_SHARED_INCLUDE_DIRS}
)
target_compile_definitions(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} 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} target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
INTERFACE "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}" "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}" INTERFACE "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}"
) "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}")
else() else ()
add_library(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} ${META_SHARED_OBJECT_TYPE} ${ALL_FILES}) 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} target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
PUBLIC ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}" PUBLIC ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}"
PRIVATE "${PRIVATE_LIBRARIES}" PRIVATE "${PRIVATE_LIBRARIES}")
)
target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
PUBLIC PUBLIC $<BUILD_INTERFACE:${TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE}>
$<BUILD_INTERFACE:${TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE}> $<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> ${PUBLIC_SHARED_INCLUDE_DIRS}
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> PRIVATE "${PRIVATE_SHARED_INCLUDE_DIRS}")
${PUBLIC_SHARED_INCLUDE_DIRS}
PRIVATE
"${PRIVATE_SHARED_INCLUDE_DIRS}"
)
target_compile_definitions(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} target_compile_definitions(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS}" PUBLIC
PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS}" "${META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS}"
) PRIVATE
"${META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS}")
target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}" PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}"
PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}" PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}")
) set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} PROPERTIES PROPERTIES VERSION
VERSION "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}" "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}"
SOVERSION "${META_SOVERSION}" SOVERSION
CXX_STANDARD "${META_CXX_STANDARD}" "${META_SOVERSION}"
LINK_SEARCH_START_STATIC ${STATIC_LINKAGE} CXX_STANDARD
LINK_SEARCH_END_STATIC ${STATIC_LINKAGE} "${META_CXX_STANDARD}"
AUTOGEN_TARGET_DEPENDS "${AUTOGEN_DEPS}" LINK_SEARCH_START_STATIC
) ${STATIC_LINKAGE}
endif() LINK_SEARCH_END_STATIC
endif() ${STATIC_LINKAGE}
AUTOGEN_TARGET_DEPENDS
"${AUTOGEN_DEPS}")
endif ()
endif ()
# add target for building a static version of the library # 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 # 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) add_library(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static INTERFACE)
target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
INTERFACE ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_STATIC_LIBRARIES}" "${PRIVATE_STATIC_LIBRARIES}" INTERFACE ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_STATIC_LIBRARIES}"
) "${PRIVATE_STATIC_LIBRARIES}")
target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static target_include_directories(
INTERFACE ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
$<BUILD_INTERFACE:${TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE}> INTERFACE $<BUILD_INTERFACE:${TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE}>
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> $<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> ${PUBLIC_STATIC_INCLUDE_DIRS})
${PUBLIC_STATIC_INCLUDE_DIRS}
)
target_compile_definitions(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static 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 target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
INTERFACE "${META_PUBLIC_STATIC_LIB_COMPILE_OPTIONS}" "${META_PRIVATE_STATIC_LIB_COMPILE_OPTIONS}" INTERFACE "${META_PUBLIC_STATIC_LIB_COMPILE_OPTIONS}"
) "${META_PRIVATE_STATIC_LIB_COMPILE_OPTIONS}")
else() else ()
add_library(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static STATIC ${ALL_FILES}) add_library(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static STATIC ${ALL_FILES})
target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static 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 target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
PUBLIC PUBLIC $<BUILD_INTERFACE:${TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE}>
$<BUILD_INTERFACE:${TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE}> $<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> ${PUBLIC_STATIC_INCLUDE_DIRS}
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> PRIVATE "${PRIVATE_STATIC_INCLUDE_DIRS}")
${PUBLIC_STATIC_INCLUDE_DIRS}
PRIVATE
"${PRIVATE_STATIC_INCLUDE_DIRS}"
)
target_compile_definitions(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static target_compile_definitions(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
PUBLIC "${META_PUBLIC_STATIC_LIB_COMPILE_DEFINITIONS}" PUBLIC
PRIVATE "${META_PRIVATE_STATIC_LIB_COMPILE_DEFINITIONS}" "${META_PUBLIC_STATIC_LIB_COMPILE_DEFINITIONS}"
) PRIVATE
"${META_PRIVATE_STATIC_LIB_COMPILE_DEFINITIONS}")
target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
PUBLIC "${META_PUBLIC_STATIC_LIB_COMPILE_OPTIONS}" PUBLIC "${META_PUBLIC_STATIC_LIB_COMPILE_OPTIONS}"
PRIVATE "${META_PRIVATE_STATIC_LIB_COMPILE_OPTIONS}" PRIVATE "${META_PRIVATE_STATIC_LIB_COMPILE_OPTIONS}")
) set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static PROPERTIES PROPERTIES VERSION
VERSION "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}" "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}"
SOVERSION "${META_SOVERSION}" SOVERSION
OUTPUT_NAME "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}" "${META_SOVERSION}"
CXX_STANDARD "${META_CXX_STANDARD}" OUTPUT_NAME
AUTOGEN_TARGET_DEPENDS "${AUTOGEN_DEPS}" "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}"
) CXX_STANDARD
endif() "${META_CXX_STANDARD}"
foreach(DEPENDENCY ${PUBLIC_STATIC_LIBRARIES} ${PRIVATE_STATIC_LIBRARIES}) AUTOGEN_TARGET_DEPENDS
if(NOT ${DEPENDENCY} IN_LIST META_PUBLIC_STATIC_LIB_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}) list(APPEND META_PRIVATE_STATIC_LIB_DEPENDS ${DEPENDENCY})
endif() endif ()
endforeach() endforeach ()
endif() endif ()
# Qt Creator does not show INTERFACE_SOURCES in project tree, so create a custom target as workaround # Qt Creator does not show INTERFACE_SOURCES in project tree, so create a custom target as workaround
if(META_HEADER_ONLY_LIB) 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") 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 add_library(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_interface_sources_for_qtcreator
EXCLUDE_FROM_ALL EXCLUDE_FROM_ALL
"${CMAKE_CURRENT_BINARY_DIR}/headeronly.cpp" ${HEADER_FILES} "${CMAKE_CURRENT_BINARY_DIR}/headeronly.cpp"
) ${HEADER_FILES})
target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_interface_sources_for_qtcreator target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_interface_sources_for_qtcreator
INTERFACE INTERFACE $<BUILD_INTERFACE:${TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE}>
$<BUILD_INTERFACE:${TARGET_INCLUDE_DIRECTORY_BUILD_INTERFACE}> $<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> ${PUBLIC_SHARED_INCLUDE_DIRS})
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}>
${PUBLIC_SHARED_INCLUDE_DIRS}
)
target_compile_definitions(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_interface_sources_for_qtcreator 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}" INTERFACE
) "${META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS}"
target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_interface_sources_for_qtcreator "${META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS}")
INTERFACE "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}" "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}" target_compile_options(
) ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_interface_sources_for_qtcreator
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_interface_sources_for_qtcreator PROPERTIES INTERFACE "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}" "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}")
VERSION "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}" set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_interface_sources_for_qtcreator
SOVERSION "${META_SOVERSION}" PROPERTIES VERSION
CXX_STANDARD "${META_CXX_STANDARD}" "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}"
AUTOGEN_TARGET_DEPENDS "${AUTOGEN_DEPS}" SOVERSION
) "${META_SOVERSION}"
endif() CXX_STANDARD
"${META_CXX_STANDARD}"
AUTOGEN_TARGET_DEPENDS
"${AUTOGEN_DEPS}")
endif ()
# create the CMake package config file from template # create the CMake package config file from template
find_template_file("Config.cmake" CPP_UTILITIES CONFIG_TEMPLATE_FILE) find_template_file("Config.cmake" CPP_UTILITIES CONFIG_TEMPLATE_FILE)
configure_package_config_file( configure_package_config_file("${CONFIG_TEMPLATE_FILE}"
"${CONFIG_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}Config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}Config.cmake" INSTALL_DESTINATION
INSTALL_DESTINATION "${CMAKE_CONFIG_INSTALL_DESTINATION}"
"${CMAKE_CONFIG_INSTALL_DESTINATION}" PATH_VARS
PATH_VARS CMAKE_MODULE_INSTALL_DESTINATION
CMAKE_MODULE_INSTALL_DESTINATION CMAKE_CONFIG_INSTALL_DESTINATION
CMAKE_CONFIG_INSTALL_DESTINATION HEADER_INSTALL_DESTINATION
HEADER_INSTALL_DESTINATION BIN_INSTALL_DESTINATION
BIN_INSTALL_DESTINATION LIB_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")
list(APPEND CMAKE_CONFIG_FILES if (BUILD_SHARED_LIBS)
"${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) find_template_file("SharedConfig.cmake" CPP_UTILITIES SHARED_CONFIG_TEMPLATE_FILE)
configure_file( configure_file("${SHARED_CONFIG_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}SharedConfig.cmake"
"${SHARED_CONFIG_TEMPLATE_FILE}" @ONLY)
"${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}SharedConfig.cmake" list(APPEND CMAKE_CONFIG_FILES "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}SharedConfig.cmake")
@ONLY endif ()
) if (BUILD_STATIC_LIBS)
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) find_template_file("StaticConfig.cmake" CPP_UTILITIES STATIC_CONFIG_TEMPLATE_FILE)
configure_file( configure_file("${STATIC_CONFIG_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}StaticConfig.cmake"
"${STATIC_CONFIG_TEMPLATE_FILE}" @ONLY)
"${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}StaticConfig.cmake" list(APPEND CMAKE_CONFIG_FILES "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}StaticConfig.cmake")
@ONLY endif ()
)
list(APPEND CMAKE_CONFIG_FILES
"${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}StaticConfig.cmake"
)
endif()
# write the CMake version config file # write the CMake version config file
write_basic_package_version_file( write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}ConfigVersion.cmake
${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}ConfigVersion.cmake VERSION "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}"
VERSION "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}" COMPATIBILITY SameMajorVersion)
COMPATIBILITY SameMajorVersion
)
# create pkg-config file from template # create pkg-config file from template
find_template_file("template.pc" CPP_UTILITIES PKGCONFIG_TEMPLATE_FILE) 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_PKGS})
unset(${OUTPUT_VAR_LIBS}) unset(${OUTPUT_VAR_LIBS})
foreach(DEPENDENCY ${${DEPENDS}}) foreach (DEPENDENCY ${${DEPENDS}})
if("${DEPENDENCY}" STREQUAL "general") if ("${DEPENDENCY}" STREQUAL "general")
continue() continue()
endif() endif ()
string(REPLACE "::" "_" DEPENDENCY_VARNAME "${DEPENDENCY}") string(REPLACE "::"
if(PC_PKG_${LIB_TYPE}_${DEPENDENCY_VARNAME}) "_"
DEPENDENCY_VARNAME
"${DEPENDENCY}")
if (PC_PKG_${LIB_TYPE}_${DEPENDENCY_VARNAME})
set(${OUTPUT_VAR_PKGS} "${${OUTPUT_VAR_PKGS}} ${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}") set(${OUTPUT_VAR_LIBS} "${${OUTPUT_VAR_LIBS}} ${DEPENDENCY}")
endif() endif ()
endforeach() endforeach ()
endmacro() endmacro ()
macro(compile_defs_for_pc LIB_TYPE) macro (compile_defs_for_pc LIB_TYPE)
foreach(COMPILE_DEFINITION ${META_PUBLIC_${LIB_TYPE}_LIB_COMPILE_DEFINITIONS}) foreach (COMPILE_DEFINITION ${META_PUBLIC_${LIB_TYPE}_LIB_COMPILE_DEFINITIONS})
set(META_COMPILE_DEFINITIONS_FOR_PC "${META_COMPILE_DEFINITIONS_FOR_PC} -D${COMPILE_DEFINITION}") set(META_COMPILE_DEFINITIONS_FOR_PC "${META_COMPILE_DEFINITIONS_FOR_PC} -D${COMPILE_DEFINITION}")
endforeach() endforeach ()
endmacro() endmacro ()
unset(PC_FILES) unset(PC_FILES)
if(BUILD_SHARED_LIBS) if (BUILD_SHARED_LIBS)
set(META_PROJECT_NAME_FOR_PC "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}") 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_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) depends_for_pc(SHARED META_PRIVATE_SHARED_LIB_DEPENDS META_PRIVATE_PC_PKGS META_PRIVATE_LIB_DEPENDS_FOR_PC)
compile_defs_for_pc(SHARED) compile_defs_for_pc(SHARED)
if(NOT META_HEADER_ONLY_LIB) 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}") set(META_PUBLIC_LIB_DEPENDS_FOR_PC
endif() " -l${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}${META_PUBLIC_LIB_DEPENDS_FOR_PC}")
if(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}") set(META_PUBLIC_LIB_DEPENDS_FOR_PC " -L\${libdir}${META_PUBLIC_LIB_DEPENDS_FOR_PC}")
endif() endif ()
configure_file( configure_file("${PKGCONFIG_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME_FOR_PC}.pc" @ONLY)
"${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") list(APPEND PC_FILES "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME_FOR_PC}.pc")
endif() endif ()
if(BUILD_STATIC_LIBS) if (BUILD_STATIC_LIBS)
set(META_PROJECT_NAME_FOR_PC "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static") 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_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) depends_for_pc(STATIC META_PRIVATE_STATIC_LIB_DEPENDS META_PRIVATE_PC_PKGS META_PRIVATE_LIB_DEPENDS_FOR_PC)
compile_defs_for_pc(STATIC) compile_defs_for_pc(STATIC)
if(NOT META_HEADER_ONLY_LIB) 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}") set(META_PUBLIC_LIB_DEPENDS_FOR_PC
endif() " -l${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}${META_PUBLIC_LIB_DEPENDS_FOR_PC}")
if(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}") set(META_PUBLIC_LIB_DEPENDS_FOR_PC " -L\${libdir}${META_PUBLIC_LIB_DEPENDS_FOR_PC}")
endif() endif ()
configure_file( configure_file("${PKGCONFIG_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME_FOR_PC}.pc" @ONLY)
"${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") 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 # add install target for the CMake config files
install( install(FILES ${CMAKE_CONFIG_FILES} DESTINATION "share/${META_PROJECT_NAME}/cmake" COMPONENT cmake-config)
FILES ${CMAKE_CONFIG_FILES} if (NOT TARGET install-cmake-config)
DESTINATION "share/${META_PROJECT_NAME}/cmake"
COMPONENT cmake-config
)
if(NOT TARGET install-cmake-config)
add_custom_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" COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=cmake-config -P
) "${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif() endif ()
# add install target for pkg-config file # add install target for pkg-config file
if(PC_FILES) if (PC_FILES)
install( install(FILES ${PC_FILES} DESTINATION "lib${SELECTED_LIB_SUFFIX}/pkgconfig" COMPONENT pkg-config)
FILES ${PC_FILES} endif ()
DESTINATION "lib${SELECTED_LIB_SUFFIX}/pkgconfig" if (NOT TARGET install-pkg-config)
COMPONENT pkg-config
)
endif()
if(NOT TARGET install-pkg-config)
add_custom_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" COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=pkg-config -P
) "${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif() endif ()
# add install target for libs # add install target for libs
if(NOT TARGET install-binary) if (NOT TARGET install-binary)
add_custom_target(install-binary add_custom_target(install-binary
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=binary -P "${CMAKE_BINARY_DIR}/cmake_install.cmake" COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=binary -P
) "${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif() endif ()
# add install target for stripped libs # add install target for stripped libs
if(NOT TARGET install-binary-strip) if (NOT TARGET install-binary-strip)
add_custom_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" COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_DO_STRIP=1 -DCMAKE_INSTALL_COMPONENT=binary -P
) "${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif() endif ()
# determine install dir for Qt plugins # determine install dir for Qt plugins
if("${META_PROJECT_TYPE}" STREQUAL "qtplugin") if ("${META_PROJECT_TYPE}" STREQUAL "qtplugin")
if(QT_PLUGIN_DIR) if (QT_PLUGIN_DIR)
set(LIBRARY_DESTINATION ${QT_PLUGIN_DIR}) set(LIBRARY_DESTINATION ${QT_PLUGIN_DIR})
else() else ()
set(LIBRARY_DESTINATION lib${SELECTED_LIB_SUFFIX}/qt/plugins) set(LIBRARY_DESTINATION lib${SELECTED_LIB_SUFFIX}/qt/plugins)
endif() endif ()
if(META_PLUGIN_CATEGORY) if (META_PLUGIN_CATEGORY)
set(LIBRARY_DESTINATION ${LIBRARY_DESTINATION}/${META_PLUGIN_CATEGORY}) set(LIBRARY_DESTINATION ${LIBRARY_DESTINATION}/${META_PLUGIN_CATEGORY})
endif() endif ()
else() else ()
set(LIBRARY_DESTINATION lib${SELECTED_LIB_SUFFIX}) set(LIBRARY_DESTINATION lib${SELECTED_LIB_SUFFIX})
endif() endif ()
# add install targets and export targets # add install targets and export targets
if(BUILD_SHARED_LIBS) if (BUILD_SHARED_LIBS)
install( install(TARGETS ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}
TARGETS ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} EXPORT ${META_PROJECT_NAME}SharedTargets
EXPORT ${META_PROJECT_NAME}SharedTargets RUNTIME DESTINATION bin COMPONENT binary
RUNTIME DESTINATION bin LIBRARY DESTINATION ${LIBRARY_DESTINATION} COMPONENT binary
COMPONENT binary ARCHIVE DESTINATION ${LIBRARY_DESTINATION} 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 ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX})
add_dependencies(install-binary-strip ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}) add_dependencies(install-binary-strip ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX})
# export shared lib # export shared lib
install(EXPORT ${META_PROJECT_NAME}SharedTargets install(EXPORT ${META_PROJECT_NAME}SharedTargets
DESTINATION "share/${META_PROJECT_NAME}/cmake" DESTINATION "share/${META_PROJECT_NAME}/cmake"
EXPORT_LINK_INTERFACE_LIBRARIES EXPORT_LINK_INTERFACE_LIBRARIES
COMPONENT cmake-config COMPONENT cmake-config)
) endif ()
endif() if (BUILD_STATIC_LIBS)
if(BUILD_STATIC_LIBS) install(TARGETS ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static
install( EXPORT ${META_PROJECT_NAME}StaticTargets
TARGETS ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static RUNTIME DESTINATION bin COMPONENT binary
EXPORT ${META_PROJECT_NAME}StaticTargets LIBRARY DESTINATION ${LIBRARY_DESTINATION} COMPONENT binary
RUNTIME DESTINATION bin ARCHIVE DESTINATION ${LIBRARY_DESTINATION} COMPONENT binary)
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 ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static)
add_dependencies(install-binary-strip ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static) add_dependencies(install-binary-strip ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_static)
# export static target # export static target
install(EXPORT ${META_PROJECT_NAME}StaticTargets install(EXPORT ${META_PROJECT_NAME}StaticTargets
DESTINATION "share/${META_PROJECT_NAME}/cmake" DESTINATION "share/${META_PROJECT_NAME}/cmake"
EXPORT_LINK_INTERFACE_LIBRARIES EXPORT_LINK_INTERFACE_LIBRARIES
COMPONENT cmake-config COMPONENT cmake-config)
) endif ()
endif()
# add install target for header files # add install target for header files
if(NOT META_IS_PLUGIN) if (NOT META_IS_PLUGIN)
foreach(HEADER_FILE ${HEADER_FILES} ${ADDITIONAL_HEADER_FILES}) foreach (HEADER_FILE ${HEADER_FILES} ${ADDITIONAL_HEADER_FILES})
get_filename_component(HEADER_DIR "${HEADER_FILE}" DIRECTORY) get_filename_component(HEADER_DIR "${HEADER_FILE}" DIRECTORY)
install( install(FILES "${HEADER_FILE}" DESTINATION "include/${META_PROJECT_NAME}/${HEADER_DIR}" COMPONENT header)
FILES "${HEADER_FILE}" endforeach ()
DESTINATION "include/${META_PROJECT_NAME}/${HEADER_DIR}" if (NOT TARGET install-header)
COMPONENT header
)
endforeach()
if(NOT TARGET install-header)
add_custom_target(install-header add_custom_target(install-header
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=header -P "${CMAKE_BINARY_DIR}/cmake_install.cmake" COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=header -P
) "${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif() endif ()
endif() endif ()
# add install target for CMake modules # 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) get_filename_component(CMAKE_MODULE_DIR ${CMAKE_MODULE_FILE} DIRECTORY)
install( install(FILES ${CMAKE_MODULE_FILE}
FILES ${CMAKE_MODULE_FILE} DESTINATION share/${META_PROJECT_NAME}/${CMAKE_MODULE_DIR}
DESTINATION share/${META_PROJECT_NAME}/${CMAKE_MODULE_DIR} COMPONENT cmake-modules)
COMPONENT cmake-modules endforeach ()
) if (NOT TARGET install-cmake-modules)
endforeach()
if(NOT TARGET install-cmake-modules)
add_custom_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" COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=cmake-modules -P
) "${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif() endif ()
# add install target for CMake templates # 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) get_filename_component(CMAKE_TEMPLATE_DIR ${CMAKE_TEMPLATE_FILE} DIRECTORY)
install( install(FILES ${CMAKE_TEMPLATE_FILE}
FILES ${CMAKE_TEMPLATE_FILE} DESTINATION share/${META_PROJECT_NAME}/${CMAKE_TEMPLATE_DIR}
DESTINATION share/${META_PROJECT_NAME}/${CMAKE_TEMPLATE_DIR} COMPONENT cmake-templates)
COMPONENT cmake-templates endforeach ()
) if (NOT TARGET install-cmake-templates)
endforeach()
if(NOT TARGET install-cmake-templates)
add_custom_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" COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=cmake-templates -P
) "${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif() endif ()
# add install target for all the cmake stuff # 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_custom_target(install-cmake-stuff)
add_dependencies(install-cmake-stuff install-cmake-config install-cmake-modules install-cmake-templates) add_dependencies(install-cmake-stuff install-cmake-config install-cmake-modules install-cmake-templates)
endif() endif ()
# add mingw-w64 specific install targets # add mingw-w64 specific install targets
if(MINGW) if (MINGW)
if(NOT TARGET install-mingw-w64) if (NOT TARGET install-mingw-w64)
add_custom_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) 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) 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) 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 ${LOCALIZATION_TARGET})
add_dependencies(install-mingw-w64-strip ${LOCALIZATION_TARGET}) add_dependencies(install-mingw-w64-strip ${LOCALIZATION_TARGET})
endif() endif ()
find_program(STRIP_BINARY_PATH strip ONLY_CMAKE_FIND_ROOT_PATH) 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}.") message(FATAL_ERROR "Unable to find strip. Please set ${STRIP_BINARY_PATH}.")
else() else ()
message(STATUS "Using strip binary under \"${STRIP_BINARY_PATH}\".") message(STATUS "Using strip binary under \"${STRIP_BINARY_PATH}\".")
endif() endif ()
if(BUILD_SHARED_LIBS AND NOT META_HEADER_ONLY_LIB) 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 add_custom_target(
COMMAND "${STRIP_BINARY_PATH}" -g "\$\{DESTDIR\}\$\{DESTDIR:+/\}${CMAKE_INSTALL_PREFIX}/lib/lib${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}.dll.a" install-${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}-mingw-w64-importlib-strip
) COMMAND
add_dependencies(install-${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}-mingw-w64-importlib-strip install-binary-strip) "${STRIP_BINARY_PATH}" -g
add_dependencies(install-mingw-w64-strip install-${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}-mingw-w64-importlib-strip) "\$\{DESTDIR\}\$\{DESTDIR:+/\}${CMAKE_INSTALL_PREFIX}/lib/lib${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}.dll.a"
endif() )
if(BUILD_STATIC_LIBS AND NOT META_HEADER_ONLY_LIB) add_dependencies(install-${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}-mingw-w64-importlib-strip
add_custom_target(install-${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}-mingw-w64-staticlib-strip install-binary-strip)
COMMAND "${STRIP_BINARY_PATH}" -g "\$\{DESTDIR\}\$\{DESTDIR:+/\}${CMAKE_INSTALL_PREFIX}/lib/lib${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}.a" add_dependencies(install-mingw-w64-strip
) install-${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}-mingw-w64-importlib-strip)
add_dependencies(install-${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}-mingw-w64-staticlib-strip install-binary-strip) endif ()
add_dependencies(install-mingw-w64-strip install-${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}-mingw-w64-staticlib-strip) if (BUILD_STATIC_LIBS AND NOT META_HEADER_ONLY_LIB)
endif() add_custom_target(
endif() install-${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}-mingw-w64-staticlib-strip
endif() 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) set(TARGET_CONFIG_DONE YES)

View File

@ -1,30 +1,30 @@
# prevent multiple inclusion # prevent multiple inclusion
if(DEFINED LIST_TO_STRING_LOADED) if (DEFINED LIST_TO_STRING_LOADED)
return() return()
endif() endif ()
set(LIST_TO_STRING_LOADED ON) 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 "") set(res "")
# get list length # get list length
list(LENGTH input_list list_length) list(LENGTH input_list list_length)
# if the list has 0 or 1 element, there is no need to loop over # 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}") set(res "${prefix}${input_list}${suffix}")
else() else ()
math(EXPR last_element_index "${list_length} - 1") math(EXPR last_element_index "${list_length} - 1")
foreach(index RANGE ${last_element_index}) foreach (index RANGE ${last_element_index})
# get current item_value # get current item_value
list(GET input_list ${index} 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 # .. and append non-empty value to output string
set(res "${res}${prefix}${item_value}${suffix}") set(res "${res}${prefix}${item_value}${suffix}")
# append separator if current element is NOT the last one. # 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}") set(res "${res}${separator}")
endif() endif ()
endif() endif ()
endforeach() endforeach ()
endif() endif ()
set(${output_string_var} "${res}" PARENT_SCOPE) 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.") 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(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) option(BASH_COMPLETION_ENABLED "controls whether shell completion for bash is enabled" ON)
if(NOT SHELL_COMPLETION_ENABLED) if (NOT SHELL_COMPLETION_ENABLED)
return() return()
endif() endif ()
# add bash completion (currently the only supported shell completion) # add bash completion (currently the only supported shell completion)
if(BASH_COMPLETION_ENABLED) if (BASH_COMPLETION_ENABLED)
# find bash-completion.sh template # find bash-completion.sh template
include(TemplateFinder) include(TemplateFinder)
find_template_file("bash-completion.sh" CPP_UTILITIES BASH_COMPLETION_TEMPLATE_FILE) find_template_file("bash-completion.sh" CPP_UTILITIES BASH_COMPLETION_TEMPLATE_FILE)
# generate wrapper script for bash completion # generate wrapper script for bash completion
configure_file( configure_file("${BASH_COMPLETION_TEMPLATE_FILE}"
"${BASH_COMPLETION_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/bash-completion/completions/${META_PROJECT_NAME}" @ONLY)
"${CMAKE_CURRENT_BINARY_DIR}/bash-completion/completions/${META_PROJECT_NAME}"
@ONLY
)
# add install target bash completion # 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" install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bash-completion/completions"
DESTINATION "share/bash-completion" DESTINATION "share/bash-completion"
COMPONENT bash-completion COMPONENT bash-completion)
) if (NOT TARGET install-bash-completion)
if(NOT TARGET install-bash-completion)
add_custom_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" COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=bash-completion -P
) "${CMAKE_BINARY_DIR}/cmake_install.cmake")
endif() endif ()
endif() endif ()
message(STATUS "Generating files for bash completion.") message(STATUS "Generating files for bash completion.")
endif() endif ()

View File

@ -1,23 +1,23 @@
# prevent multiple inclusion # prevent multiple inclusion
if(DEFINED TEMPLATE_FINDER_LOADED) if (DEFINED TEMPLATE_FINDER_LOADED)
return() return()
endif() endif ()
set(TEMPLATE_FINDER_LOADED YES) set(TEMPLATE_FINDER_LOADED YES)
function(find_template_file FILE_NAME PROJECT_VAR_NAME OUTPUT_VAR) function (find_template_file FILE_NAME PROJECT_VAR_NAME OUTPUT_VAR)
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/${FILE_NAME}.in") if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/${FILE_NAME}.in")
# check own source directory # check own source directory
set(${OUTPUT_VAR} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/${FILE_NAME}.in" PARENT_SCOPE) 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.") 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 # check sources of project
set(${OUTPUT_VAR} "${${PROJECT_VAR_NAME}_SOURCE_DIR}/cmake/templates/${FILE_NAME}.in" PARENT_SCOPE) 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.") 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 # check installed version of project
set(${OUTPUT_VAR} "${${PROJECT_VAR_NAME}_CONFIG_DIRS}/templates/${FILE_NAME}.in" PARENT_SCOPE) 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.") 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.") message(FATAL_ERROR "Template for ${FILE_NAME} file can not be located.")
endif() endif ()
endfunction() 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.") message(FATAL_ERROR "Before including the TestTarget module, the BasicConfig module must be included.")
endif() endif ()
if(TEST_CONFIG_DONE) if (TEST_CONFIG_DONE)
message(FATAL_ERROR "Can not include TestTarget module when tests are already configured.") 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) 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) # 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 # make cppunit library/include dir configurable
set(CPP_UNIT_LIB NOTFOUND CACHE FILEPATH "cppunit lib" FORCE) set(CPP_UNIT_LIB NOTFOUND CACHE FILEPATH "cppunit lib" FORCE)
set(CPP_UNIT_INCLUDE_DIR NOTFOUND CACHE FILEPATH "cppunit include dir" FORCE) set(CPP_UNIT_INCLUDE_DIR NOTFOUND CACHE FILEPATH "cppunit include dir" FORCE)
# set default for minimum version (only checked when using pkg-config) # 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) set(META_REQUIRED_CPP_UNIT_VERSION 1.13.0)
endif() endif ()
# auto-detection: try to find via pkg-config first # 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) include(FindPkgConfig)
pkg_search_module(CPP_UNIT_CONFIG_${META_PROJECT_NAME} cppunit>=${META_REQUIRED_CPP_UNIT_VERSION}) pkg_search_module(CPP_UNIT_CONFIG_${META_PROJECT_NAME} cppunit>=${META_REQUIRED_CPP_UNIT_VERSION})
if(CPP_UNIT_CONFIG_${META_PROJECT_NAME}_FOUND) 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_LIB "${CPP_UNIT_CONFIG_${META_PROJECT_NAME}_LDFLAGS_OTHER}"
set(CPP_UNIT_INCLUDE_DIR ${CPP_UNIT_CONFIG_${META_PROJECT_NAME}_INCLUDE_DIRS} CACHE FILEPATH "cppunit include dir" FORCE) "${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}) link_directories(${CPP_UNIT_CONFIG_${META_PROJECT_NAME}_LIBRARY_DIRS})
else() else ()
# fall back to find_library # fall back to find_library
find_library(DETECTED_CPP_UNIT_LIB cppunit) find_library(DETECTED_CPP_UNIT_LIB cppunit)
set(CPP_UNIT_LIB "${DETECTED_CPP_UNIT_LIB}" CACHE FILEPATH "cppunit lib" FORCE) 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.") message(WARNING "Unable to add test target because cppunit could not be located.")
set(META_HAVE_TESTS NO) set(META_HAVE_TESTS NO)
set(TEST_CONFIG_DONE YES) set(TEST_CONFIG_DONE YES)
return() return()
endif() endif ()
list(APPEND TEST_LIBRARIES "${CPP_UNIT_LIB}") list(APPEND TEST_LIBRARIES "${CPP_UNIT_LIB}")
if(NOT CPP_UNIT_CONFIG_${META_PROJECT_NAME}_FOUND) 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}.") message(
endif() 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}") list(APPEND TEST_INCLUDE_DIRS "${CPP_UNIT_INCLUDE_DIR}")
endif() endif ()
endif() endif ()
# add default cppunit test application if requested # add default cppunit test application if requested
if(META_ADD_DEFAULT_CPP_UNIT_TEST_APPLICATION) if (META_ADD_DEFAULT_CPP_UNIT_TEST_APPLICATION)
if(META_NO_CPP_UNIT) 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.") message(
endif() 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") 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>") 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}") list(APPEND TEST_SRC_FILES "${DEFAULT_CPP_UNIT_TEST_APPLICATION_SRC}")
endif() endif ()
# always link test applications against c++utilities # always link test applications against c++utilities
list(APPEND TEST_LIBRARIES ${CPP_UTILITIES_LIB}) list(APPEND TEST_LIBRARIES ${CPP_UTILITIES_LIB})
# set compile definitions # set compile definitions
if(NOT META_PUBLIC_SHARED_LIB_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}) set(META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS ${META_PUBLIC_COMPILE_DEFINITIONS}
endif() ${META_ADDITIONAL_PUBLIC_SHARED_COMPILE_DEFINITIONS})
if(NOT META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS) endif ()
set(META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS ${META_PRIVATE_COMPILE_DEFINITIONS} ${META_ADDITIONAL_PRIVATE_SHARED_COMPILE_DEFINITIONS}) if (NOT META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS)
endif() 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 # 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) set(TESTS_EXCLUSION EXCLUDE_FROM_ALL)
else() else ()
unset(TESTS_EXCLUSION) unset(TESTS_EXCLUSION)
endif() endif ()
add_executable(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests ${TESTS_EXCLUSION} ${TEST_HEADER_FILES} ${TEST_SRC_FILES}) 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 # 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) 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) add_dependencies(tests ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests)
endif() endif ()
# handle testing a library (which is default project type) # 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 # 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}) 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}") 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) 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}") message(STATUS "Linking test target statically against ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}")
endif() endif ()
endif() endif ()
# handle testing an application # 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 # 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' # create target for the 'testlib'
set(TESTLIB_FILES ${HEADER_FILES} ${SRC_FILES} ${WIDGETS_FILES} ${QML_FILES} ${RES_FILES} ${QM_FILES}) set(TESTLIB_FILES ${HEADER_FILES} ${SRC_FILES} ${WIDGETS_FILES} ${QML_FILES} ${RES_FILES} ${QM_FILES})
list(REMOVE_ITEM TESTLIB_FILES main.h main.cpp) list(REMOVE_ITEM TESTLIB_FILES main.h main.cpp)
add_library(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib SHARED ${TESTLIB_FILES}) add_library(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib SHARED ${TESTLIB_FILES})
target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib
PUBLIC ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}" PUBLIC ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}"
PRIVATE "${PRIVATE_LIBRARIES}" PRIVATE "${PRIVATE_LIBRARIES}")
)
target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib
PUBLIC PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> $<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> ${PUBLIC_SHARED_INCLUDE_DIRS}
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> PRIVATE "${PRIVATE_SHARED_INCLUDE_DIRS}")
${PUBLIC_SHARED_INCLUDE_DIRS}
PRIVATE
"${PRIVATE_SHARED_INCLUDE_DIRS}"
)
target_compile_definitions(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib target_compile_definitions(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib
PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS}" PUBLIC
PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS}" "${META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS}"
) PRIVATE
"${META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS}")
target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib
PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}" PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}"
PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}" PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}")
) set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib PROPERTIES PROPERTIES CXX_STANDARD
CXX_STANDARD "${META_CXX_STANDARD}" "${META_CXX_STANDARD}"
LINK_SEARCH_START_STATIC ${STATIC_LINKAGE} LINK_SEARCH_START_STATIC
LINK_SEARCH_END_STATIC ${STATIC_LINKAGE} ${STATIC_LINKAGE}
AUTOGEN_TARGET_DEPENDS "${AUTOGEN_DEPS}" LINK_SEARCH_END_STATIC
) ${STATIC_LINKAGE}
if(CPP_UNIT_CONFIG_${META_PROJECT_NAME}_FOUND) AUTOGEN_TARGET_DEPENDS
"${AUTOGEN_DEPS}")
if (CPP_UNIT_CONFIG_${META_PROJECT_NAME}_FOUND)
target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib 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 target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib
PRIVATE "${CPP_UNIT_CONFIG_${META_PROJECT_NAME}_CFLAGS_OTHER}" PRIVATE "${CPP_UNIT_CONFIG_${META_PROJECT_NAME}_CFLAGS_OTHER}")
) endif ()
endif()
# link tests against it # link tests against it
list(APPEND TEST_LIBRARIES ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib) 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") # 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) set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_testlib
endif() PROPERTIES CXX_VISIBILITY_PRESET default)
endif() endif ()
endif ()
# actually apply configuration for test target # actually apply configuration for test target
target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests target_link_libraries(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests
PUBLIC ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}" PUBLIC ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}"
PRIVATE "${TEST_LIBRARIES}" "${PRIVATE_LIBRARIES}" PRIVATE "${TEST_LIBRARIES}" "${PRIVATE_LIBRARIES}")
)
target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests target_include_directories(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests
PUBLIC PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> $<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> ${PUBLIC_SHARED_INCLUDE_DIRS}
$<INSTALL_INTERFACE:${HEADER_INSTALL_DESTINATION}> PRIVATE ${TEST_INCLUDE_DIRS} "${PRIVATE_SHARED_INCLUDE_DIRS}")
${PUBLIC_SHARED_INCLUDE_DIRS}
PRIVATE
${TEST_INCLUDE_DIRS}
"${PRIVATE_SHARED_INCLUDE_DIRS}"
)
target_compile_definitions(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests target_compile_definitions(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests
PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS}" PUBLIC
PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS}" "${META_PUBLIC_SHARED_LIB_COMPILE_DEFINITIONS}"
) PRIVATE
"${META_PRIVATE_SHARED_LIB_COMPILE_DEFINITIONS}")
target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests target_compile_options(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests
PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}" PUBLIC "${META_PUBLIC_SHARED_LIB_COMPILE_OPTIONS}"
PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}" PRIVATE "${META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS}")
) set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests
set_target_properties(${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests PROPERTIES PROPERTIES CXX_STANDARD
CXX_STANDARD "${META_CXX_STANDARD}" "${META_CXX_STANDARD}"
LINK_SEARCH_START_STATIC ${STATIC_LINKAGE} LINK_SEARCH_START_STATIC
LINK_SEARCH_END_STATIC ${STATIC_LINKAGE} ${STATIC_LINKAGE}
) LINK_SEARCH_END_STATIC
${STATIC_LINKAGE})
# make the test recognized by ctest # make the test recognized by ctest
unset(RUN_TESTS_APPLICATION_ARG) 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}>") set(RUN_TESTS_APPLICATION_ARGS -a "$<TARGET_FILE:${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}>")
endif() endif ()
if(NOT META_TEST_TARGET_IS_MANUAL) if (NOT META_TEST_TARGET_IS_MANUAL)
add_test(NAME ${META_PROJECT_NAME}_run_tests COMMAND add_test(NAME ${META_PROJECT_NAME}_run_tests
${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests COMMAND ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests -p "${CMAKE_CURRENT_SOURCE_DIR}/testfiles" -w
-p "${CMAKE_CURRENT_SOURCE_DIR}/testfiles" "${CMAKE_CURRENT_BINARY_DIR}/testworkingdir" ${RUN_TESTS_APPLICATION_ARGS})
-w "${CMAKE_CURRENT_BINARY_DIR}/testworkingdir" endif ()
${RUN_TESTS_APPLICATION_ARGS}
)
endif()
# enable source code based coverage analysis using clang # 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 # 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 # 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 # 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 # 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_REPORT_FILE
set(COVERAGE_PER_FILE_REPORT_FILE "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage_per_file.txt") "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage.txt")
set(COVERAGE_OVERALL_REPORT_FILE "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage_overall.txt") set(COVERAGE_PER_FILE_REPORT_FILE
set(COVERAGE_HTML_REPORT_FILE "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage.html") "${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}") set(COVERAGE_REPORT_FILES "${COVERAGE_REPORT_FILE}")
# specify where to store raw clang profiling data via environment variable # specify where to store raw clang profiling data via environment variable
if(NOT META_TEST_TARGET_IS_MANUAL) if (NOT META_TEST_TARGET_IS_MANUAL)
set_tests_properties(${META_PROJECT_NAME}_run_tests set_tests_properties(
${META_PROJECT_NAME}_run_tests
PROPERTIES ENVIRONMENT PROPERTIES ENVIRONMENT
"LLVM_PROFILE_FILE=${LLVM_PROFILE_RAW_FILE};LLVM_PROFILE_LIST_FILE=${LLVM_PROFILE_RAW_LIST_FILE}" "LLVM_PROFILE_FILE=${LLVM_PROFILE_RAW_FILE};LLVM_PROFILE_LIST_FILE=${LLVM_PROFILE_RAW_LIST_FILE}")
) endif ()
endif()
add_custom_command( add_custom_command(
OUTPUT "${LLVM_PROFILE_RAW_FILE}" OUTPUT "${LLVM_PROFILE_RAW_FILE}" "${LLVM_PROFILE_RAW_LIST_FILE}"
"${LLVM_PROFILE_RAW_LIST_FILE}" COMMAND "${CMAKE_COMMAND}" -E env "LLVM_PROFILE_FILE=${LLVM_PROFILE_RAW_FILE}"
COMMAND "${CMAKE_COMMAND}" "LLVM_PROFILE_LIST_FILE=${LLVM_PROFILE_RAW_LIST_FILE}"
-E env $<TARGET_FILE:${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests> -p
"LLVM_PROFILE_FILE=${LLVM_PROFILE_RAW_FILE}" "${CMAKE_CURRENT_SOURCE_DIR}/testfiles" -w "${CMAKE_CURRENT_BINARY_DIR}/testworkingdir"
"LLVM_PROFILE_LIST_FILE=${LLVM_PROFILE_RAW_LIST_FILE}" ${RUN_TESTS_APPLICATION_ARGS}
$<TARGET_FILE:${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests> COMMENT
-p "${CMAKE_CURRENT_SOURCE_DIR}/testfiles" "Executing ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests to generate raw profiling data for source-based coverage report"
-w "${CMAKE_CURRENT_BINARY_DIR}/testworkingdir" DEPENDS "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests")
${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_PROFDATA_BIN llvm-profdata)
find_program(LLVM_COV_BIN llvm-cov) 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 # merge profiling data
add_custom_command( add_custom_command(OUTPUT "${LLVM_PROFILE_DATA_FILE}"
OUTPUT "${LLVM_PROFILE_DATA_FILE}" COMMAND cat "${LLVM_PROFILE_RAW_LIST_FILE}" | xargs "${LLVM_PROFDATA_BIN}" merge -o
COMMAND cat "${LLVM_PROFILE_RAW_LIST_FILE}" | xargs "${LLVM_PROFILE_DATA_FILE}" -sparse "${LLVM_PROFILE_RAW_FILE}"
"${LLVM_PROFDATA_BIN}" merge COMMENT "Generating profiling data for source-based coverage report"
-o "${LLVM_PROFILE_DATA_FILE}" DEPENDS "${LLVM_PROFILE_RAW_FILE}" "${LLVM_PROFILE_RAW_LIST_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 # determine llvm-cov version
execute_process( execute_process(COMMAND "${LLVM_COV_BIN}" -version OUTPUT_VARIABLE LLVM_COV_VERSION)
COMMAND "${LLVM_COV_BIN}" -version string(REGEX MATCH
OUTPUT_VARIABLE LLVM_COV_VERSION "LLVM version ([0-9](.[0-9])*)"
) LLVM_COV_VERSION
string(REGEX MATCH "LLVM version ([0-9](.[0-9])*)" LLVM_COV_VERSION "${LLVM_COV_VERSION}") "${LLVM_COV_VERSION}")
if(CMAKE_MATCH_1) if (CMAKE_MATCH_1)
set(LLVM_COV_VERSION "${CMAKE_MATCH_1}") set(LLVM_COV_VERSION "${CMAKE_MATCH_1}")
else() else ()
message(FATAL_ERROR "Unable to determine version of llvm-cov. Output of ${LLVM_COV_BIN} -version:\n${LLVM_COV_VERSION}") message(
endif() 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 # determine the target file for llvm-cov
if(NOT META_HEADER_ONLY_LIB) 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>) set(LLVM_COV_TARGET_FILE $<TARGET_FILE:${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}>
else() $<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>) set(LLVM_COV_TARGET_FILE $<TARGET_FILE:${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests>)
endif() endif ()
# generate coverage report with statistics per function # generate coverage report with statistics per function
unset(LLVM_COV_ADDITIONAL_OPTIONS) unset(LLVM_COV_ADDITIONAL_OPTIONS)
if(LLVM_COV_VERSION GREATER_EQUAL 5.0.0) 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) # 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) list(APPEND LLVM_COV_ADDITIONAL_OPTIONS -show-functions)
endif() endif ()
add_custom_command( add_custom_command(OUTPUT "${COVERAGE_REPORT_FILE}"
OUTPUT "${COVERAGE_REPORT_FILE}" COMMAND "${LLVM_COV_BIN}" report -format=text -stats -instr-profile "${LLVM_PROFILE_DATA_FILE}"
COMMAND "${LLVM_COV_BIN}" report ${LLVM_COV_ADDITIONAL_OPTIONS} ${LLVM_COV_TARGET_FILE} ${HEADER_FILES} ${SRC_FILES}
-format=text ${WIDGETS_HEADER_FILES} ${WIDGETS_SOURCE_FILES} ${QML_HEADER_FILES} ${QML_SOURCE_FILES} >
-stats "${COVERAGE_REPORT_FILE}"
-instr-profile "${LLVM_PROFILE_DATA_FILE}" COMMENT "Generating coverage report (statistics per function)"
${LLVM_COV_ADDITIONAL_OPTIONS} DEPENDS "${LLVM_PROFILE_DATA_FILE}"
${LLVM_COV_TARGET_FILE} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
${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) # 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) if (LLVM_COV_VERSION GREATER_EQUAL 5.0.0)
add_custom_command( add_custom_command(OUTPUT "${COVERAGE_PER_FILE_REPORT_FILE}"
OUTPUT "${COVERAGE_PER_FILE_REPORT_FILE}" COMMAND "${LLVM_COV_BIN}" report -format=text -stats -instr-profile
COMMAND "${LLVM_COV_BIN}" report "${LLVM_PROFILE_DATA_FILE}" ${LLVM_COV_TARGET_FILE} ${HEADER_FILES} ${SRC_FILES}
-format=text ${WIDGETS_HEADER_FILES} ${WIDGETS_SOURCE_FILES} ${QML_HEADER_FILES}
-stats ${QML_SOURCE_FILES} > "${COVERAGE_PER_FILE_REPORT_FILE}"
-instr-profile "${LLVM_PROFILE_DATA_FILE}" COMMENT "Generating coverage report (statistics per file)"
${LLVM_COV_TARGET_FILE} DEPENDS "${LLVM_PROFILE_DATA_FILE}"
${HEADER_FILES} ${SRC_FILES} ${WIDGETS_HEADER_FILES} ${WIDGETS_SOURCE_FILES} ${QML_HEADER_FILES} ${QML_SOURCE_FILES} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
> "${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}") list(APPEND COVERAGE_REPORT_FILES "${COVERAGE_PER_FILE_REPORT_FILE}")
endif() endif ()
# add target for the coverage reports # add target for the coverage reports
add_custom_target("${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage_summary" add_custom_target("${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage_summary"
DEPENDS ${COVERAGE_REPORT_FILES} DEPENDS ${COVERAGE_REPORT_FILES})
) # generate coverage overall report (total region/line coverage) NOTE: added before release of LLVM 5 where coverage
# generate coverage overall report (total region/line coverage) # report with statistics per file could not be generated
# 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") 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") set(OVERALL_COVERAGE_AKW_SCRIPT "${CPP_UTILITIES_SOURCE_DIR}/tests/calculateoverallcoverage.awk")
endif() endif ()
if(NOT EXISTS "${OVERALL_COVERAGE_AKW_SCRIPT}") if (NOT EXISTS "${OVERALL_COVERAGE_AKW_SCRIPT}")
set(OVERALL_COVERAGE_AKW_SCRIPT "${CPP_UTILITIES_CONFIG_DIRS}/tests/calculateoverallcoverage.awk") set(OVERALL_COVERAGE_AKW_SCRIPT "${CPP_UTILITIES_CONFIG_DIRS}/tests/calculateoverallcoverage.awk")
endif() endif ()
add_custom_command( add_custom_command(OUTPUT "${COVERAGE_OVERALL_REPORT_FILE}"
OUTPUT "${COVERAGE_OVERALL_REPORT_FILE}" COMMAND awk -f "${OVERALL_COVERAGE_AKW_SCRIPT}" "${COVERAGE_REPORT_FILE}" >
COMMAND awk "${COVERAGE_OVERALL_REPORT_FILE}"
-f "${OVERALL_COVERAGE_AKW_SCRIPT}" "${COVERAGE_REPORT_FILE}" COMMENT "Generating coverage report (overall figures)"
> "${COVERAGE_OVERALL_REPORT_FILE}" DEPENDS "${OVERALL_COVERAGE_AKW_SCRIPT}" "${COVERAGE_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" 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 # generate HTML document showing covered/uncovered code
add_custom_command( add_custom_command(OUTPUT "${COVERAGE_HTML_REPORT_FILE}"
OUTPUT "${COVERAGE_HTML_REPORT_FILE}" COMMAND "${LLVM_COV_BIN}" show -project-title="${META_APP_NAME}" -format=html -instr-profile
COMMAND "${LLVM_COV_BIN}" show "${LLVM_PROFILE_DATA_FILE}" ${LLVM_COV_TARGET_FILE} ${HEADER_FILES} ${SRC_FILES}
-project-title="${META_APP_NAME}" ${WIDGETS_FILES} ${QML_FILES} > "${COVERAGE_HTML_REPORT_FILE}"
-format=html COMMENT "Generating HTML document showing covered/uncovered code"
-instr-profile "${LLVM_PROFILE_DATA_FILE}" DEPENDS "${LLVM_PROFILE_DATA_FILE}"
${LLVM_COV_TARGET_FILE} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
${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" 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 # create target for all coverage docs
add_custom_target("${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage" add_custom_target("${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage"
DEPENDS ${COVERAGE_REPORT_FILES} DEPENDS ${COVERAGE_REPORT_FILES}
DEPENDS "${COVERAGE_OVERALL_REPORT_FILE}" DEPENDS "${COVERAGE_OVERALL_REPORT_FILE}"
DEPENDS "${COVERAGE_HTML_REPORT_FILE}" DEPENDS "${COVERAGE_HTML_REPORT_FILE}")
)
# add targets to global coverage target # add targets to global coverage target
if(NOT TARGET coverage) if (NOT TARGET coverage)
add_custom_target(coverage) add_custom_target(coverage)
endif() endif ()
add_dependencies(coverage "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage") add_dependencies(coverage "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests_coverage")
else() else ()
message(FATAL_ERROR "Unable to generate target for coverage report because llvm-profdata and llvm-cov are not available.") message(
endif() FATAL_ERROR "Unable to generate target for coverage report because llvm-profdata and llvm-cov are not available."
endif() )
endif ()
endif ()
# add the test executable to the dependencies of the check target # 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) add_dependencies(check ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tests)
endif() endif ()
set(META_HAVE_TESTS YES) set(META_HAVE_TESTS YES)
set(TEST_CONFIG_DONE YES) set(TEST_CONFIG_DONE YES)

View File

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