From 1480d9ab63e080d42f166f1818701e8ed0e20070 Mon Sep 17 00:00:00 2001 From: Martchus Date: Tue, 23 Apr 2019 00:26:19 +0200 Subject: [PATCH] Support installing multiple configurations within the same prefix --- cmake/modules/3rdParty.cmake | 63 ++++++++++++---- cmake/modules/AppTarget.cmake | 11 +-- cmake/modules/BasicConfig.cmake | 53 ++++++++++--- cmake/modules/ConfigHeader.cmake | 29 ++++--- cmake/modules/Doxygen.cmake | 3 +- cmake/modules/LibraryTarget.cmake | 113 ++++++++++++++++++---------- cmake/modules/ShellCompletion.cmake | 2 +- cmake/modules/TestTarget.cmake | 24 +++++- cmake/templates/Config.cmake.in | 39 ++++++++-- cmake/templates/config.h.in | 3 + 10 files changed, 240 insertions(+), 100 deletions(-) diff --git a/cmake/modules/3rdParty.cmake b/cmake/modules/3rdParty.cmake index 8bcd291..3dc3139 100644 --- a/cmake/modules/3rdParty.cmake +++ b/cmake/modules/3rdParty.cmake @@ -17,6 +17,7 @@ endmacro () macro (configure_static_library_suffixes) # allows to look for static libraries in particular + # NOTE: code duplicated in Config.cmake.in if (WIN32) set(CMAKE_FIND_LIBRARY_SUFFIXES .a .lib) else () @@ -44,7 +45,7 @@ endfunction() function(parse_arguments_for_use_functions) # parse arguments set(OPTIONAL_ARGS OPTIONAL) - set(ONE_VALUE_ARGS VISIBILITY LIBRARIES_VARIABLE TARGET_NAME) + set(ONE_VALUE_ARGS VISIBILITY LIBRARIES_VARIABLE PACKAGES_VARIABLE TARGET_NAME) set(MULTI_VALUE_ARGS) cmake_parse_arguments(ARGS "${OPTIONAL_ARGS}" "${ONE_VALUE_ARGS}" "${MULTI_VALUE_ARGS}" ${ARGN}) @@ -58,10 +59,16 @@ function(parse_arguments_for_use_functions) if (NOT ARGS_LIBRARIES_VARIABLE) set (ARGS_LIBRARIES_VARIABLE "${ARGS_VISIBILITY}_LIBRARIES") endif() + if (NOT ARGS_PACKAGES_VARIABLE AND (NOT BUILD_SHARED_LIBS OR VISIBILITY STREQUAL PUBLIC)) + set (ARGS_PACKAGES_VARIABLE "INTERFACE_REQUIRED_PACKAGES") + else () + set (ARGS_PACKAGES_VARIABLE "REQUIRED_PACKAGES") + endif () # export parsed values to parent scope set(ARGS_VISIBILITY "${ARGS_VISIBILITY}" PARENT_SCOPE) set(ARGS_LIBRARIES_VARIABLE "${ARGS_LIBRARIES_VARIABLE}" PARENT_SCOPE) + set(ARGS_PACKAGES_VARIABLE "${ARGS_PACKAGES_VARIABLE}" PARENT_SCOPE) set(ARGS_TARGET_NAME "${ARGS_TARGET_NAME}" PARENT_SCOPE) set(ARGS_OPTIONAL "${ARGS_OPTIONAL}" PARENT_SCOPE) if (NOT ARGS_OPTIONAL) @@ -86,26 +93,30 @@ function (use_iconv) endif() # find external iconv library - if (NOT TARGET ICONV::LIBICONV) - find_library(ICONV_LIBRARY_PATH iconv) - if (NOT EXISTS "${ICONV_LIBRARY_PATH}") - if (ARGS_OPTIONAL) - return() - endif() - message(FATAL_ERROR "Unable to find iconv library for project ${META_PROJECT_NAME}.") + if (NOT TARGET Iconv::Iconv) + set(Iconv_IS_BUILT_IN FALSE) + find_package(Iconv ${ARGS_FIND_PACKAGE}) + if (NOT Iconv_FOUND) + return() endif() - add_library(ICONV::LIBICONV STATIC IMPORTED) - set_property(TARGET ICONV::LIBICONV PROPERTY IMPORTED_LOCATION "${ICONV_LIBRARY_PATH}") endif() - set("${ARGS_LIBRARIES_VARIABLE}" "${${ARGS_LIBRARIES_VARIABLE}};ICONV::LIBICONV" PARENT_SCOPE) + set("${ARGS_LIBRARIES_VARIABLE}" "${${ARGS_LIBRARIES_VARIABLE}};Iconv::Iconv" PARENT_SCOPE) + set("${ARGS_PACKAGES_VARIABLE}" "${${ARGS_PACKAGES_VARIABLE}};Iconv" PARENT_SCOPE) endfunction() function (use_openssl) parse_arguments_for_use_functions(${ARGN}) find_package(OpenSSL ${ARGS_FIND_PACKAGE}) + if (NOT OpenSSL_FOUND) + return() + endif() set("${ARGS_LIBRARIES_VARIABLE}" "${${ARGS_LIBRARIES_VARIABLE}};OpenSSL::SSL;OpenSSL::Crypto" PARENT_SCOPE) + set("${ARGS_PACKAGES_VARIABLE}" "${${ARGS_PACKAGES_VARIABLE}};OpenSSL" PARENT_SCOPE) + if (WIN32 AND OPENSSL_USE_STATIC_LIBS) + set("${ARGS_LIBRARIES_VARIABLE}" "${${ARGS_LIBRARIES_VARIABLE}};-lws2_32;-lgdi32;-lcrypt32" PARENT_SCOPE) + endif () set("PKG_CONFIG_OpenSSL_SSL" "libssl" PARENT_SCOPE) set("PKG_CONFIG_OpenSSL_Crypto" "libcrypto" PARENT_SCOPE) endfunction() @@ -114,7 +125,14 @@ function (use_crypto) parse_arguments_for_use_functions(${ARGN}) find_package(OpenSSL ${ARGS_FIND_PACKAGE}) + if (NOT OpenSSL_FOUND) + return() + endif() set("${ARGS_LIBRARIES_VARIABLE}" "${${ARGS_LIBRARIES_VARIABLE}};OpenSSL::Crypto" PARENT_SCOPE) + set("${ARGS_PACKAGES_VARIABLE}" "${${ARGS_PACKAGES_VARIABLE}};OpenSSL" PARENT_SCOPE) + if (WIN32 AND OPENSSL_USE_STATIC_LIBS) + set("${ARGS_LIBRARIES_VARIABLE}" "${${ARGS_LIBRARIES_VARIABLE}};OpenSSL::Crypto;-lws2_32;-lgdi32;-lcrypt32" PARENT_SCOPE) + endif () set("PKG_CONFIG_OpenSSL_Crypto" "libcrypto" PARENT_SCOPE) endfunction() @@ -122,7 +140,11 @@ function (use_zlib) parse_arguments_for_use_functions(${ARGN}) find_package(ZLIB ${ARGS_FIND_PACKAGE}) + if (NOT ZLIB_FOUND) + return() + endif() set("${ARGS_LIBRARIES_VARIABLE}" "${${ARGS_LIBRARIES_VARIABLE}};ZLIB::ZLIB" PARENT_SCOPE) + set("${ARGS_PACKAGES_VARIABLE}" "${${ARGS_PACKAGES_VARIABLE}};ZLIB" PARENT_SCOPE) set("PKG_CONFIG_ZLIB_ZLIB" "zlib" PARENT_SCOPE) endfunction() @@ -161,14 +183,25 @@ endif() # configure "static linkage" if ((STATIC_LINKAGE AND META_PROJECT_IS_APPLICATION) OR (STATIC_LIBRARY_LINKAGE AND META_PROJECT_IS_LIBRARY)) + set(STATIC_LINKAGE_CONFIGURED ON) + # add additional linker flags to achieve a fully statically linked build + set(STATIC_LINKAGE_LINKER_FLAGS) + if (NOT APPLE) + list(APPEND STATIC_LINKAGE_LINKER_FLAGS -static) + endif () + list(APPEND STATIC_LINKAGE_LINKER_FLAGS -static-libstdc++ -static-libgcc) + if (META_PROJECT_IS_APPLICATION) - if (NOT APPLE) - list(APPEND META_ADDITIONAL_LINK_FLAGS -static) - endif () - list(APPEND META_ADDITIONAL_LINK_FLAGS -static-libstdc++ -static-libgcc) + list(APPEND META_ADDITIONAL_LINK_FLAGS ${STATIC_LINKAGE_LINKER_FLAGS}) endif() + list(APPEND META_ADDITIONAL_LINK_FLAGS_TEST_TARGET ${STATIC_LINKAGE_LINKER_FLAGS}) # prefer static libraries + set(OPENSSL_USE_STATIC_LIBS ON) + set(BOOST_USE_STATIC_LIBS ON) configure_static_library_suffixes() + +else() + set(STATIC_LINKAGE_CONFIGURED OFF) endif() diff --git a/cmake/modules/AppTarget.cmake b/cmake/modules/AppTarget.cmake index a5b0874..bf8f854 100644 --- a/cmake/modules/AppTarget.cmake +++ b/cmake/modules/AppTarget.cmake @@ -13,7 +13,7 @@ if (NOT "${META_PROJECT_TYPE}" STREQUAL "application") ) 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) set(WINDOWS_EXT "exe") endif (WIN32) @@ -38,15 +38,11 @@ if (ANDROID) else () add_executable(${META_TARGET_NAME} ${GUI_TYPE} ${ALL_FILES}) endif () -message(STATUS LINKING ${META_TARGET_NAME} - PUBLIC ${META_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}" - PRIVATE "${PRIVATE_LIBRARIES}") target_link_libraries(${META_TARGET_NAME} PUBLIC ${META_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}" PRIVATE "${PRIVATE_LIBRARIES}") target_include_directories(${META_TARGET_NAME} - PUBLIC $ - $ ${PUBLIC_SHARED_INCLUDE_DIRS} + PUBLIC $ ${PUBLIC_INCLUDE_DIRS} PRIVATE "${PRIVATE_INCLUDE_DIRS}") target_compile_definitions(${META_TARGET_NAME} PUBLIC @@ -66,6 +62,7 @@ set_target_properties(${META_TARGET_NAME} AUTOGEN_TARGET_DEPENDS "${AUTOGEN_DEPS}") +# add install targets if (NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS) # add install target for binary if (APPLE) @@ -156,7 +153,7 @@ if (MINGW AND CMAKE_CROSSCOMPILING AND CPP_UTILITIES_SOURCE_DIR) endif () endif () -# find template for *.desktop files +# find template for *.desktop and AppStream files include(TemplateFinder) find_template_file("desktop" CPP_UTILITIES APP_DESKTOP_TEMPLATE_FILE) find_template_file("appdata.xml" CPP_UTILITIES APP_APPSTREAM_TEMPLATE_FILE) diff --git a/cmake/modules/BasicConfig.cmake b/cmake/modules/BasicConfig.cmake index 0c601eb..ce8770a 100644 --- a/cmake/modules/BasicConfig.cmake +++ b/cmake/modules/BasicConfig.cmake @@ -1,4 +1,4 @@ -# before including this module, the project meta-data must be set +# check whether the required project meta-data has been set before including this module if (NOT META_PROJECT_NAME) message(FATAL_ERROR "No project name (META_PROJECT_NAME) specified.") endif () @@ -12,12 +12,8 @@ if (NOT META_APP_DESCRIPTION) message(FATAL_ERROR "No project name (META_APP_DESCRIPTION) specified.") endif () -# define a few variables -set(META_TARGET_NAME "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}") -string(TOUPPER "${CMAKE_BUILD_TYPE}" META_CURRENT_CONFIGURATION) - # set project name (displayed in Qt Creator) -message(STATUS "Configuring project ${META_TARGET_NAME}") +message(STATUS "Configuring project ${META_PROJECT_NAME}") project(${META_PROJECT_NAME}) # set META_PROJECT_VARNAME and META_PROJECT_VARNAME_UPPER if not specified explicitely @@ -36,6 +32,41 @@ if (NOT META_PROJECT_VARNAME_LOWER) string(TOLOWER "${META_PROJECT_VARNAME_LOWER}" META_PROJECT_VARNAME_LOWER) endif () +# allow setting a configuration name to allow installing multiple differently configured versions +# within the same prefix (intended to be used for installing Qt 5 and Qt 6 version or shared and +# static version within the same prefix) +set(${META_PROJECT_VARNAME_UPPER}_CONFIGURATION_NAME "" CACHE STRING "sets the configuration name for ${META_PROJECT_NAME}") +set(CONFIGURATION_NAME "" CACHE STRING "sets the configuration name for all projects within the current build") +if (${META_PROJECT_VARNAME_UPPER}_CONFIGURATION_NAME STREQUAL "none") + set(META_CONFIG_NAME "") +elseif (${META_PROJECT_VARNAME_UPPER}_CONFIGURATION_NAME) + set(META_CONFIG_NAME "${${META_PROJECT_VARNAME_UPPER}_CONFIGURATION_NAME}") +else() + set(META_CONFIG_NAME "${CONFIGURATION_NAME}") +endif () +if (META_CONFIG_NAME) + set(META_CONFIG_PREFIX "${META_CONFIG_NAME}-") + set(META_CONFIG_SUFFIX "-${META_CONFIG_NAME}") +endif () + +# allow setting a library/application target suffix - A different configuration name might not require +# a different target name since it might differ anyways (e.g. library extensions for static and shared +# configuration). Hence there's not simply the configuration name used to distinguish targets as well. +set(${META_PROJECT_VARNAME_UPPER}_CONFIGURATION_TARGET_SUFFIX "" CACHE STRING "sets a target suffix for ${META_PROJECT_NAME}") +set(CONFIGURATION_TARGET_SUFFIX "" CACHE STRING "sets the target suffix for all projects within the current build") +if (${META_PROJECT_VARNAME_UPPER}_CONFIGURATION_TARGET_SUFFIX STREQUAL "none") + set(TARGET_SUFFIX "") +elseif (${META_PROJECT_VARNAME_UPPER}_CONFIGURATION_TARGET_SUFFIX) + set(TARGET_SUFFIX "-${${META_PROJECT_VARNAME_UPPER}_CONFIGURATION_TARGET_SUFFIX}") +elseif (CONFIGURATION_TARGET_SUFFIX) + set(TARGET_SUFFIX "-${CONFIGURATION_TARGET_SUFFIX}") +endif () + +# define a few variables +set(META_TARGET_NAME "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}") +SET(META_DATA_DIR "share/${META_PROJECT_NAME}${META_CONFIG_SUFFIX}") +string(TOUPPER "${CMAKE_BUILD_TYPE}" META_CURRENT_CONFIGURATION) + # set META_GENERIC_NAME to META_APP_NAME if not specified explicitely if (NOT META_GENERIC_NAME) set(META_GENERIC_NAME "${META_APP_NAME}") @@ -417,10 +448,8 @@ if (CLANG_SOURCE_BASED_COVERAGE_ENABLED) endif () set(CLANG_SOURCE_BASED_COVERAGE_AVAILABLE YES) set(CLANG_SOURCE_BASED_COVERAGE_FLAGS -fprofile-instr-generate -fcoverage-mapping) - list(APPEND META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS ${CLANG_SOURCE_BASED_COVERAGE_FLAGS}) - list(APPEND META_PRIVATE_STATIC_LIB_COMPILE_OPTIONS ${CLANG_SOURCE_BASED_COVERAGE_FLAGS}) - list(APPEND META_ADDITIONAL_SHARED_LINK_FLAGS ${CLANG_SOURCE_BASED_COVERAGE_FLAGS}) - list(APPEND META_ADDITIONAL_STATIC_LINK_FLAGS ${CLANG_SOURCE_BASED_COVERAGE_FLAGS}) + list(APPEND META_PRIVATE_COMPILE_OPTIONS ${CLANG_SOURCE_BASED_COVERAGE_FLAGS}) + list(APPEND META_ADDITIONAL_LINK_FLAGS ${CLANG_SOURCE_BASED_COVERAGE_FLAGS}) endif () # configure creation of install targets @@ -434,7 +463,7 @@ endif () if (NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS) foreach (EXTRA_FILE ${EXTRA_FILES}) get_filename_component(EXTRA_DIR ${EXTRA_FILE} DIRECTORY) - install(FILES ${EXTRA_FILE} DESTINATION "share/${META_PROJECT_NAME}/${EXTRA_DIR}" COMPONENT extra-files) + install(FILES ${EXTRA_FILE} DESTINATION "${META_DATA_DIR}/${EXTRA_DIR}" COMPONENT extra-files) endforeach () if (NOT TARGET install-extra-files) add_custom_target(install-extra-files @@ -443,7 +472,7 @@ if (NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS) endif () endif () -# determine library directory suffix note: Applications might be built as libraries under some platforms (eg. Android). Hence +# determine library directory suffix - Applications might be built as libraries under some platforms (eg. Android). Hence # this is part of BasicConfig and not LibraryConfig. set(LIB_SUFFIX "" CACHE STRING "specifies the general suffix for the library directory") set(SELECTED_LIB_SUFFIX "${LIB_SUFFIX}") diff --git a/cmake/modules/ConfigHeader.cmake b/cmake/modules/ConfigHeader.cmake index a9cd892..32eb4b9 100644 --- a/cmake/modules/ConfigHeader.cmake +++ b/cmake/modules/ConfigHeader.cmake @@ -11,26 +11,30 @@ endif () include(TemplateFinder) find_template_file("config.h" CPP_UTILITIES CONFIG_H_TEMPLATE_FILE) -# create list of dependency versions present at link time -include(ListToString) +# ensure certain variables are cleared unset(DEPENCENCY_VERSIONS) unset(DEPENCENCY_VERSIONS_ARRAY) unset(LINK_LIBRARIES_LIST) unset(INTERFACE_LINK_LIBRARIES_LIST) unset(PROCESSED_DEPENDENCIES) unset(HAVE_OPENSSL) + +# get list of dependencies the main target links to if (NOT META_HEADER_ONLY_LIB) get_target_property(LINK_LIBRARIES_LIST "${META_TARGET_NAME}" LINK_LIBRARIES) endif() get_target_property(INTERFACE_LINK_LIBRARIES_LIST "${META_TARGET_NAME}" INTERFACE_LINK_LIBRARIES) + +# make list with link-time dependency versions and display names foreach (DEPENDENCY IN LISTS LINK_LIBRARIES_LIST INTERFACE_LINK_LIBRARIES_LIST) + # skip non-targets and already processed dependencies if (NOT TARGET "${DEPENDENCY}" OR "${DEPENDENCY}" IN_LIST PROCESSED_DEPENDENCIES) continue() endif() - unset(DEPENDENCY_DISPLAY_NAME) - unset(DEPENDENCY_VER) # find version and display name for target + unset(DEPENDENCY_VER) + unset(DEPENDENCY_DISPLAY_NAME) if (DEPENDENCY MATCHES "((Static)?Qt5)::([A-Za-z0-9]+)") # read meta-data of Qt module set(DEPENDENCY_MODULE_PREFIX "${CMAKE_MATCH_1}") @@ -52,18 +56,19 @@ foreach (DEPENDENCY IN LISTS LINK_LIBRARIES_LIST INTERFACE_LINK_LIBRARIES_LIST) endif () set(DEPENDENCY_VER "${${DEPENDENCY_VARNAME}_VERSION}") endif () - # FIXME: provide meta-data for other libs, too - if (DEPENDENCY_VER - AND NOT - "${DEPENDENCY_VER}" - STREQUAL - "DEPENDENCY_VER-NOTFOUND") - list(APPEND PROCESSED_DEPENDENCIES "${DEPENDENCY}") - list(APPEND DEPENCENCY_VERSIONS "${DEPENDENCY_DISPLAY_NAME}: ${DEPENDENCY_VER}") + # TODO: provide meta-data for other libs, too + + if (NOT DEPENDENCY_VER OR "${DEPENDENCY_VER}" STREQUAL "DEPENDENCY_VER-NOTFOUND") + continue() endif () + list(APPEND PROCESSED_DEPENDENCIES "${DEPENDENCY}") + list(APPEND DEPENCENCY_VERSIONS "${DEPENDENCY_DISPLAY_NAME}: ${DEPENDENCY_VER}") endforeach () + +# format "DEPENCENCY_VERSIONS_ARRAY" if (DEPENCENCY_VERSIONS) + include(ListToString) list_to_string("," " \\\n \"" "\"" "${DEPENCENCY_VERSIONS}" DEPENCENCY_VERSIONS_ARRAY) endif () diff --git a/cmake/modules/Doxygen.cmake b/cmake/modules/Doxygen.cmake index 76ff68e..588203c 100644 --- a/cmake/modules/Doxygen.cmake +++ b/cmake/modules/Doxygen.cmake @@ -26,7 +26,6 @@ if (DOT_BIN) else () set(HAVE_DOT "NO") endif () - if (NOT DOXYGEN_BIN) message( WARNING @@ -72,7 +71,7 @@ add_dependencies(apidoc "${META_TARGET_NAME}_apidoc") # add install target for API documentation if (NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS) install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/api-doc" - DESTINATION "share/${META_PROJECT_NAME}" + DESTINATION "${META_DATA_DIR}" COMPONENT api-doc OPTIONAL) if (NOT TARGET install-api-doc) diff --git a/cmake/modules/LibraryTarget.cmake b/cmake/modules/LibraryTarget.cmake index b552f2b..c59e313 100644 --- a/cmake/modules/LibraryTarget.cmake +++ b/cmake/modules/LibraryTarget.cmake @@ -18,17 +18,21 @@ if ((NOT "${META_PROJECT_TYPE}" STREQUAL "library") AND (NOT "${META_PROJECT_TYP ) endif () -# includes for configure_package_config_file, write_basic_package_version_file and find_template_file +# include packages for configure_package_config_file, write_basic_package_version_file and find_template_file include(CMakePackageConfigHelpers) include(TemplateFinder) # set install destination for the CMake modules, config files and header files -set(HEADER_INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/include") +set(INCLUDE_SUBDIR "include") +if (META_CONFIG_SUFFIX) + set(INCLUDE_SUBDIR "${INCLUDE_SUBDIR}/${META_PROJECT_NAME}${META_CONFIG_SUFFIX}") +endif () +set(HEADER_INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/${INCLUDE_SUBDIR}") set(BIN_INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") set(LIB_INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/lib${SELECTED_LIB_SUFFIX}") set(QT_PLUGIN_INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/lib${SELECTED_LIB_SUFFIX}/qt/plugins") -set(CMAKE_MODULE_INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/share/${META_PROJECT_NAME}/cmake/modules") -set(CMAKE_CONFIG_INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/share/${META_PROJECT_NAME}/cmake") +set(CMAKE_MODULE_INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/${META_DATA_DIR}/cmake/modules") +set(CMAKE_CONFIG_INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/${META_DATA_DIR}/cmake") # remove library prefix when building with mingw-w64 (just for consistency with qmake) if (MINGW) @@ -147,9 +151,17 @@ else () AUTOGEN_TARGET_DEPENDS "${AUTOGEN_DEPS}") endif () + +# populate META_PUBLIC_LIB_DEPENDS +foreach (DEPENDENCY ${PUBLIC_LIBRARIES}) + if (NOT "${DEPENDENCY}" IN_LIST META_PUBLIC_LIB_DEPENDS) + list(APPEND META_PUBLIC_LIB_DEPENDS ${DEPENDENCY}) + endif () +endforeach () +# populate META_PRIVATE_LIB_DEPENDS (only required when building static libraries) if (NOT BUILD_SHARED_LIBS) - foreach (DEPENDENCY ${PUBLIC_LIBRARIES} ${PRIVATE_LIBRARIES}) - if (NOT "${DEPENDENCY}" IN_LIST META_PUBLIC_LIB_DEPENDS) + foreach (DEPENDENCY ${PRIVATE_LIBRARIES}) + if (NOT "${DEPENDENCY}" IN_LIST META_PUBLIC_LIB_DEPENDS AND NOT "${DEPENDENCY}" IN_LIST META_PRIVATE_LIB_DEPENDS) list(APPEND META_PRIVATE_LIB_DEPENDS ${DEPENDENCY}) endif () endforeach () @@ -185,28 +197,35 @@ if (META_HEADER_ONLY_LIB) endif () # create the CMake package config file from template +list(REMOVE_ITEM INTERFACE_REQUIRED_PACKAGES "") +list(REMOVE_DUPLICATES INTERFACE_REQUIRED_PACKAGES) +set(CONFIG_TARGETS "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}${META_CONFIG_SUFFIX}Config.cmake") +if (META_CONFIG_SUFFIX) + list(APPEND CONFIG_TARGETS "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}Config.cmake") +endif () find_template_file("Config.cmake" CPP_UTILITIES CONFIG_TEMPLATE_FILE) -configure_package_config_file("${CONFIG_TEMPLATE_FILE}" - "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}Config.cmake" - INSTALL_DESTINATION - "${CMAKE_CONFIG_INSTALL_DESTINATION}" - PATH_VARS - CMAKE_MODULE_INSTALL_DESTINATION - CMAKE_CONFIG_INSTALL_DESTINATION - HEADER_INSTALL_DESTINATION - BIN_INSTALL_DESTINATION - LIB_INSTALL_DESTINATION) -list(APPEND CMAKE_CONFIG_FILES "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}Config.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}ConfigVersion.cmake") +foreach (CONFIG_TARGET ${CONFIG_TARGETS}) + configure_package_config_file("${CONFIG_TEMPLATE_FILE}" + "${CONFIG_TARGET}" + INSTALL_DESTINATION + "${CMAKE_CONFIG_INSTALL_DESTINATION}" + PATH_VARS + CMAKE_MODULE_INSTALL_DESTINATION + CMAKE_CONFIG_INSTALL_DESTINATION + HEADER_INSTALL_DESTINATION + BIN_INSTALL_DESTINATION + LIB_INSTALL_DESTINATION) +endforeach () +list(APPEND CMAKE_CONFIG_FILES "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}${META_CONFIG_SUFFIX}Config.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}${META_CONFIG_SUFFIX}ConfigVersion.cmake") # write the CMake version config file -write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}ConfigVersion.cmake +write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME}${META_CONFIG_SUFFIX}ConfigVersion.cmake VERSION "${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}" COMPATIBILITY SameMajorVersion) -# create pkg-config file from template -find_template_file("template.pc" CPP_UTILITIES PKGCONFIG_TEMPLATE_FILE) -macro (depends_for_pc DEPENDS OUTPUT_VAR_PKGS OUTPUT_VAR_LIBS) +# compute dependencies for pkg-config file +macro (compute_dependencies_for_package_config DEPENDS OUTPUT_VAR_PKGS OUTPUT_VAR_LIBS) unset(${OUTPUT_VAR_PKGS}) unset(${OUTPUT_VAR_LIBS}) foreach (DEPENDENCY ${${DEPENDS}}) @@ -222,15 +241,22 @@ macro (depends_for_pc DEPENDS OUTPUT_VAR_PKGS OUTPUT_VAR_LIBS) set(${OUTPUT_VAR_PKGS} "${${OUTPUT_VAR_PKGS}} ${PKG_CONFIG_${DEPENDENCY_VARNAME}}") elseif (TARGET "${DEPENDENCY}") # add library location of the target + get_target_property("${DEPENDENCY_VARNAME}_INTERFACE_LINK_LIBRARIES" "${DEPENDENCY}" "INTERFACE_LINK_LIBRARIES") + if (EXISTS "${${DEPENDENCY_VARNAME}_INTERFACE_LINK_LIBRARIES}") + set(${OUTPUT_VAR_LIBS} "${${OUTPUT_VAR_LIBS}} ${${DEPENDENCY_VARNAME}_INTERFACE_LINK_LIBRARIES}") + continue() + endif() if (META_CURRENT_CONFIGURATION) get_target_property("${DEPENDENCY_VARNAME}_IMPORTED_LOCATION_${META_CURRENT_CONFIGURATION}" "${DEPENDENCY}" "IMPORTED_LOCATION_${META_CURRENT_CONFIGURATION}") if (EXISTS "${${DEPENDENCY_VARNAME}_IMPORTED_LOCATION_${META_CURRENT_CONFIGURATION}}") set(${OUTPUT_VAR_LIBS} "${${OUTPUT_VAR_LIBS}} ${${DEPENDENCY_VARNAME}_IMPORTED_LOCATION_${META_CURRENT_CONFIGURATION}}") + continue() endif() endif() get_target_property("${DEPENDENCY_VARNAME}_IMPORTED_LOCATION" "${DEPENDENCY}" IMPORTED_LOCATION) if (EXISTS "${${DEPENDENCY_VARNAME}_IMPORTED_LOCATION}") set(${OUTPUT_VAR_LIBS} "${${OUTPUT_VAR_LIBS}} ${${DEPENDENCY_VARNAME}_IMPORTED_LOCATION}") + continue() endif() else () # add raw dependency @@ -238,13 +264,8 @@ macro (depends_for_pc DEPENDS OUTPUT_VAR_PKGS OUTPUT_VAR_LIBS) endif () endforeach () endmacro () -unset(PC_FILES) -set(META_PROJECT_NAME_FOR_PC "${META_TARGET_NAME}") -depends_for_pc(META_PUBLIC_LIB_DEPENDS META_PUBLIC_PC_PKGS META_PUBLIC_LIB_DEPENDS_FOR_PC) -depends_for_pc(META_PRIVATE_LIB_DEPENDS META_PRIVATE_PC_PKGS META_PRIVATE_LIB_DEPENDS_FOR_PC) -foreach (COMPILE_DEFINITION ${META_PUBLIC_LIB_COMPILE_DEFINITIONS}) - set(META_COMPILE_DEFINITIONS_FOR_PC "${META_COMPILE_DEFINITIONS_FOR_PC} -D${COMPILE_DEFINITION}") -endforeach () +compute_dependencies_for_package_config(META_PUBLIC_LIB_DEPENDS META_PUBLIC_PC_PKGS META_PUBLIC_LIB_DEPENDS_FOR_PC) +compute_dependencies_for_package_config(META_PRIVATE_LIB_DEPENDS META_PRIVATE_PC_PKGS META_PRIVATE_LIB_DEPENDS_FOR_PC) if (NOT META_HEADER_ONLY_LIB) set(META_PUBLIC_LIB_DEPENDS_FOR_PC " -l${META_TARGET_NAME}${META_PUBLIC_LIB_DEPENDS_FOR_PC}") @@ -252,12 +273,22 @@ endif () if (META_PUBLIC_LIB_DEPENDS_FOR_PC) set(META_PUBLIC_LIB_DEPENDS_FOR_PC " -L\${libdir}${META_PUBLIC_LIB_DEPENDS_FOR_PC}") endif () -configure_file("${PKGCONFIG_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME_FOR_PC}.pc" @ONLY) -list(APPEND PC_FILES "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME_FOR_PC}.pc") +# compute other values for pkg-config +set(META_PROJECT_NAME_FOR_PC "${META_PROJECT_NAME}${META_CONFIG_SUFFIX}") +foreach (COMPILE_DEFINITION ${META_PUBLIC_LIB_COMPILE_DEFINITIONS}) + set(META_COMPILE_DEFINITIONS_FOR_PC "${META_COMPILE_DEFINITIONS_FOR_PC} -D${COMPILE_DEFINITION}") +endforeach () + +# create pkg-config file from template using previously computed values +find_template_file("template.pc" CPP_UTILITIES PKGCONFIG_TEMPLATE_FILE) +configure_file("${PKGCONFIG_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME_FOR_PC}.pc" @ONLY) +set(PC_FILES "${CMAKE_CURRENT_BINARY_DIR}/${META_PROJECT_NAME_FOR_PC}.pc") + +# add install targets if (NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS) # add install target for the CMake config files - install(FILES ${CMAKE_CONFIG_FILES} DESTINATION "share/${META_PROJECT_NAME}/cmake" COMPONENT cmake-config) + install(FILES ${CMAKE_CONFIG_FILES} DESTINATION "${META_DATA_DIR}/cmake" COMPONENT cmake-config) if (NOT TARGET install-cmake-config) add_custom_target(install-cmake-config COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=cmake-config -P @@ -311,15 +342,15 @@ if (NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS) endif () # add install targets and export targets - install(TARGETS ${META_TARGET_NAME} - EXPORT ${META_PROJECT_NAME}Targets + install(TARGETS "${META_TARGET_NAME}" + EXPORT "${META_PROJECT_NAME}${META_CONFIG_SUFFIX}Targets" RUNTIME DESTINATION bin COMPONENT binary LIBRARY DESTINATION ${LIBRARY_DESTINATION} COMPONENT binary ARCHIVE DESTINATION ${LIBRARY_DESTINATION} COMPONENT binary) - add_dependencies(install-binary ${META_TARGET_NAME}) - add_dependencies(install-binary-strip ${META_TARGET_NAME}) - install(EXPORT ${META_PROJECT_NAME}Targets - DESTINATION "share/${META_PROJECT_NAME}/cmake" + add_dependencies(install-binary "${META_TARGET_NAME}") + add_dependencies(install-binary-strip "${META_TARGET_NAME}") + install(EXPORT ${META_PROJECT_NAME}${META_CONFIG_SUFFIX}Targets + DESTINATION "${META_DATA_DIR}/cmake" EXPORT_LINK_INTERFACE_LIBRARIES COMPONENT cmake-config) @@ -327,7 +358,7 @@ if (NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS) if (NOT META_IS_PLUGIN) foreach (HEADER_FILE ${HEADER_FILES} ${ADDITIONAL_HEADER_FILES}) get_filename_component(HEADER_DIR "${HEADER_FILE}" DIRECTORY) - install(FILES "${HEADER_FILE}" DESTINATION "include/${META_PROJECT_NAME}/${HEADER_DIR}" COMPONENT header) + install(FILES "${HEADER_FILE}" DESTINATION "${INCLUDE_SUBDIR}/${META_PROJECT_NAME}/${HEADER_DIR}" COMPONENT header) endforeach () if (NOT TARGET install-header) add_custom_target(install-header @@ -340,7 +371,7 @@ if (NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS) foreach (CMAKE_MODULE_FILE ${CMAKE_MODULE_FILES}) get_filename_component(CMAKE_MODULE_DIR ${CMAKE_MODULE_FILE} DIRECTORY) install(FILES ${CMAKE_MODULE_FILE} - DESTINATION share/${META_PROJECT_NAME}/${CMAKE_MODULE_DIR} + DESTINATION ${META_DATA_DIR}/${CMAKE_MODULE_DIR} COMPONENT cmake-modules) endforeach () if (NOT TARGET install-cmake-modules) @@ -353,7 +384,7 @@ if (NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS) foreach (CMAKE_TEMPLATE_FILE ${CMAKE_TEMPLATE_FILES}) get_filename_component(CMAKE_TEMPLATE_DIR ${CMAKE_TEMPLATE_FILE} DIRECTORY) install(FILES ${CMAKE_TEMPLATE_FILE} - DESTINATION share/${META_PROJECT_NAME}/${CMAKE_TEMPLATE_DIR} + DESTINATION ${META_DATA_DIR}/${CMAKE_TEMPLATE_DIR} COMPONENT cmake-templates) endforeach () if (NOT TARGET install-cmake-templates) diff --git a/cmake/modules/ShellCompletion.cmake b/cmake/modules/ShellCompletion.cmake index dfee796..33742dd 100644 --- a/cmake/modules/ShellCompletion.cmake +++ b/cmake/modules/ShellCompletion.cmake @@ -16,7 +16,7 @@ if (BASH_COMPLETION_ENABLED) # generate wrapper script for bash completion configure_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}${META_CONFIG_SUFFIX}" @ONLY) # add install target bash completion if (NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS) diff --git a/cmake/modules/TestTarget.cmake b/cmake/modules/TestTarget.cmake index eb6eaa2..1eabbf5 100644 --- a/cmake/modules/TestTarget.cmake +++ b/cmake/modules/TestTarget.cmake @@ -109,7 +109,7 @@ if (META_PROJECT_IS_APPLICATION) list(REMOVE_ITEM TESTLIB_FILES main.h main.cpp) add_library(${META_TARGET_NAME}_testlib SHARED ${TESTLIB_FILES}) target_link_libraries(${META_TARGET_NAME}_testlib - PUBLIC ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}" + PUBLIC ${META_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}" PRIVATE "${PRIVATE_LIBRARIES}") target_include_directories(${META_TARGET_NAME}_testlib PUBLIC $ @@ -148,7 +148,7 @@ endif () # configure test target target_link_libraries(${META_TARGET_NAME}_tests - PUBLIC ${ACTUAL_ADDITIONAL_LINK_FLAGS} "${PUBLIC_LIBRARIES}" + PUBLIC ${META_ADDITIONAL_LINK_FLAGS} ${META_ADDITIONAL_LINK_FLAGS_TEST_TARGET} "${PUBLIC_LIBRARIES}" PRIVATE "${TEST_LIBRARIES}" "${PRIVATE_LIBRARIES}") target_include_directories(${META_TARGET_NAME}_tests PUBLIC $ @@ -202,6 +202,7 @@ if (CLANG_SOURCE_BASED_COVERAGE_AVAILABLE) set(COVERAGE_HTML_REPORT_FILE "${CMAKE_CURRENT_BINARY_DIR}/${META_TARGET_NAME}_tests_coverage.html") set(COVERAGE_REPORT_FILES "${COVERAGE_REPORT_FILE}") + # specify where to store raw clang profiling data via environment variable if (NOT META_TEST_TARGET_IS_MANUAL) set_tests_properties( @@ -209,6 +210,8 @@ if (CLANG_SOURCE_BASED_COVERAGE_AVAILABLE) PROPERTIES ENVIRONMENT "LLVM_PROFILE_FILE=${LLVM_PROFILE_RAW_FILE};LLVM_PROFILE_LIST_FILE=${LLVM_PROFILE_RAW_LIST_FILE}") endif () + + # add command to execute tests generating raw profiling data add_custom_command( OUTPUT "${LLVM_PROFILE_RAW_FILE}" "${LLVM_PROFILE_RAW_LIST_FILE}" COMMAND "${CMAKE_COMMAND}" -E env "LLVM_PROFILE_FILE=${LLVM_PROFILE_RAW_FILE}" @@ -219,6 +222,8 @@ if (CLANG_SOURCE_BASED_COVERAGE_AVAILABLE) COMMENT "Executing ${META_TARGET_NAME}_tests to generate raw profiling data for source-based coverage report" DEPENDS "${META_TARGET_NAME}_tests") + + # add commands for processing raw profiling data find_program(LLVM_PROFDATA_BIN llvm-profdata) find_program(LLVM_COV_BIN llvm-cov) if (LLVM_PROFDATA_BIN AND LLVM_COV_BIN) @@ -228,6 +233,7 @@ if (CLANG_SOURCE_BASED_COVERAGE_AVAILABLE) "${LLVM_PROFILE_DATA_FILE}" -sparse "${LLVM_PROFILE_RAW_FILE}" COMMENT "Generating profiling data for source-based coverage report" DEPENDS "${LLVM_PROFILE_RAW_FILE}" "${LLVM_PROFILE_RAW_LIST_FILE}") + # determine llvm-cov version execute_process(COMMAND "${LLVM_COV_BIN}" -version OUTPUT_VARIABLE LLVM_COV_VERSION) string(REGEX MATCH @@ -241,6 +247,7 @@ if (CLANG_SOURCE_BASED_COVERAGE_AVAILABLE) FATAL_ERROR "Unable to determine version of llvm-cov. Output of ${LLVM_COV_BIN} -version:\n${LLVM_COV_VERSION}") endif () + # determine the target file for llvm-cov if (NOT META_HEADER_ONLY_LIB) set(LLVM_COV_TARGET_FILE $ @@ -248,6 +255,7 @@ if (CLANG_SOURCE_BASED_COVERAGE_AVAILABLE) else () set(LLVM_COV_TARGET_FILE $) endif () + # generate coverage report with statistics per function unset(LLVM_COV_ADDITIONAL_OPTIONS) if (LLVM_COV_VERSION GREATER_EQUAL 5.0.0) @@ -263,6 +271,7 @@ if (CLANG_SOURCE_BASED_COVERAGE_AVAILABLE) COMMENT "Generating coverage report (statistics per function)" DEPENDS "${LLVM_PROFILE_DATA_FILE}" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") + # generate coverage report with statistics per file (only possible with LLVM 5 if source files are specified) if (LLVM_COV_VERSION GREATER_EQUAL 5.0.0) add_custom_command(OUTPUT "${COVERAGE_PER_FILE_REPORT_FILE}" @@ -275,11 +284,15 @@ if (CLANG_SOURCE_BASED_COVERAGE_AVAILABLE) WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") list(APPEND COVERAGE_REPORT_FILES "${COVERAGE_PER_FILE_REPORT_FILE}") endif () + # add target for the coverage reports add_custom_target("${META_TARGET_NAME}_tests_coverage_summary" DEPENDS ${COVERAGE_REPORT_FILES}) - # generate coverage overall report (total region/line coverage) NOTE: added before release of LLVM 5 where coverage - # report with statistics per file could not be generated + + # NOTE: Those commands have been added before the release of LLVM 5 where coverage reports + # with statistics per file could not be generated. + + # generate coverage overall report (total region/line coverage) set(OVERALL_COVERAGE_AKW_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/tests/calculateoverallcoverage.awk") if (CPP_UTILITIES_SOURCE_DIR AND NOT EXISTS "${OVERALL_COVERAGE_AKW_SCRIPT}") set(OVERALL_COVERAGE_AKW_SCRIPT "${CPP_UTILITIES_SOURCE_DIR}/tests/calculateoverallcoverage.awk") @@ -294,6 +307,7 @@ if (CLANG_SOURCE_BASED_COVERAGE_AVAILABLE) DEPENDS "${OVERALL_COVERAGE_AKW_SCRIPT}" "${COVERAGE_REPORT_FILE}") add_custom_target("${META_TARGET_NAME}_tests_coverage_overall_summary" DEPENDS "${COVERAGE_OVERALL_REPORT_FILE}") + # generate HTML document showing covered/uncovered code add_custom_command(OUTPUT "${COVERAGE_HTML_REPORT_FILE}" COMMAND "${LLVM_COV_BIN}" show -project-title="${META_APP_NAME}" -format=html -instr-profile @@ -304,11 +318,13 @@ if (CLANG_SOURCE_BASED_COVERAGE_AVAILABLE) WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") add_custom_target("${META_TARGET_NAME}_tests_coverage_html" DEPENDS "${COVERAGE_HTML_REPORT_FILE}") + # create target for all coverage docs add_custom_target("${META_TARGET_NAME}_tests_coverage" DEPENDS ${COVERAGE_REPORT_FILES} DEPENDS "${COVERAGE_OVERALL_REPORT_FILE}" DEPENDS "${COVERAGE_HTML_REPORT_FILE}") + # add targets to global coverage target if (NOT TARGET coverage) add_custom_target(coverage) diff --git a/cmake/templates/Config.cmake.in b/cmake/templates/Config.cmake.in index fd76742..8398fc2 100644 --- a/cmake/templates/Config.cmake.in +++ b/cmake/templates/Config.cmake.in @@ -25,29 +25,56 @@ set(@META_PROJECT_VARNAME_UPPER@_PRIVATE_QT_MODULES "@QT_MODULES@") set(@META_PROJECT_VARNAME_UPPER@_PRIVATE_KF_MODULES "@KF_MODULES@") set(@META_PROJECT_VARNAME_UPPER@_PUBLIC_QT_MODULES "@META_PUBLIC_QT_MODULES@") set(@META_PROJECT_VARNAME_UPPER@_PUBLIC_KF_MODULES "@META_PUBLIC_KF_MODULES@") +set(@META_PROJECT_VARNAME_UPPER@_REQUIRED_PACKAGES "@INTERFACE_REQUIRED_PACKAGES@") set(@META_PROJECT_VARNAME_UPPER@_HAS_QT_TRANSLATION_FILES @APP_SPECIFIC_QT_TRANSLATIONS_AVAILABLE@) set(@META_PROJECT_VARNAME_UPPER@_QT_RESOURCES @QT_RESOURCES@) -# define library config +# define library config, add imported target +set(@META_PROJECT_VARNAME_UPPER@_PACKAGE "@META_PROJECT_NAME@@META_CONFIG_SUFFIX@") set(@META_PROJECT_VARNAME_UPPER@_LIB "@META_TARGET_NAME@") set(@META_PROJECT_VARNAME_UPPER@_LIB_IS_SHARED "@BUILD_SHARED_LIBS@") -set(PKG_CONFIG_@META_PROJECT_NAME@ "@META_PROJECT_NAME@") +set(@META_PROJECT_VARNAME_UPPER@_STATIC_LINKAGE "@STATIC_LINKAGE_CONFIGURED@") +set(PKG_CONFIG_@META_TARGET_NAME@ "@META_PROJECT_NAME@@META_CONFIG_SUFFIX@") if(NOT TARGET "${@META_PROJECT_VARNAME_UPPER@_LIB}") - include("${CMAKE_CURRENT_LIST_DIR}/@META_PROJECT_NAME@Targets.cmake") + include("${CMAKE_CURRENT_LIST_DIR}/@META_PROJECT_NAME@@META_CONFIG_SUFFIX@Targets.cmake") + + # find all required packages; prefer static libraries if project was configured this way during its build + if (@META_PROJECT_VARNAME_UPPER@_STATIC_LINKAGE) + set(@META_PROJECT_VARNAME_UPPER@_DEFAULT_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + if (WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES .a .lib) + else () + set(CMAKE_FIND_LIBRARY_SUFFIXES .a) + endif () + endif () + foreach (_REQUIRED_PACKAGE ${@META_PROJECT_VARNAME_UPPER@_REQUIRED_PACKAGES}) + string(REGEX MATCH _REQUIRED_PACKAGE_MATCH "(.*)-([^-]*)" "${_REQUIRED_PACKAGE}") + if (_REQUIRED_PACKAGE_MATCH) + find_package("${CMAKE_MATCH_1}" "${CMAKE_MATCH_2}" REQUIRED) + else () + find_package("${_REQUIRED_PACKAGE}" REQUIRED) + endif() + endforeach() + if (@META_PROJECT_VARNAME_UPPER@_STATIC_LINKAGE) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${@META_PROJECT_VARNAME_UPPER@_DEFAULT_CMAKE_FIND_LIBRARY_SUFFIXES}) + unset(@META_PROJECT_VARNAME_UPPER@_DEFAULT_CMAKE_FIND_LIBRARY_SUFFIXES) + endif () endif() # define function to ease use of library in projects following conventions of c++utilities' build script function(use_@META_PROJECT_VARNAME@) + # make CMake modules of the project available + list(APPEND CMAKE_MODULE_PATH "${@META_PROJECT_VARNAME_UPPER@_MODULE_DIRS}") + set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" PARENT_SCOPE) + # parse arguments include(3rdParty) parse_arguments_for_use_functions(${ARGN}) - # make CMake modules of the project available - set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${@META_PROJECT_VARNAME_UPPER@_MODULE_DIRS}" PARENT_SCOPE) - # link against library (also "link" against header-only libs to get compile defs and interface link libs) link_directories(${@META_PROJECT_VARNAME_UPPER@_LIB_DIR}) set("${ARGS_LIBRARIES_VARIABLE}" "${${ARGS_LIBRARIES_VARIABLE}};${@META_PROJECT_VARNAME_UPPER@_LIB}" PARENT_SCOPE) + set("${ARGS_PACKAGES_VARIABLE}" "${${ARGS_PACKAGES_VARIABLE}};${@META_PROJECT_VARNAME_UPPER@_PACKAGE}" PARENT_SCOPE) # add required Qt and KF modules set(IMPORTED_QT_MODULES diff --git a/cmake/templates/config.h.in b/cmake/templates/config.h.in index e0a6d6c..6383376 100644 --- a/cmake/templates/config.h.in +++ b/cmake/templates/config.h.in @@ -6,12 +6,15 @@ #define PROJECT_NAME "@META_PROJECT_NAME@" #define PROJECT_LICENSE "@META_PROJECT_LICENSE@" +#define PROJECT_CONFIG_NAME "@META_CONFIG_NAME@" +#define PROJECT_CONFIG_TARGET_SUFFIX "@TARGET_SUFFIX@" #define APP_NAME "@META_APP_NAME@" #define APP_VERSION "@META_APP_VERSION@" #define APP_AUTHOR "@META_APP_AUTHOR@" #define APP_URL "@META_APP_URL@" #define APP_DESCRIPTION "@META_APP_DESCRIPTION@" #define APP_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@" +#define APP_DATA_DIR "@META_DATA_DIR@" #define DEPENCENCY_VERSIONS {@DEPENCENCY_VERSIONS_ARRAY@} @META_CUSTOM_CONFIG@ #endif // @META_PROJECT_VARNAME_UPPER@_CONFIG