diff --git a/CMakeLists.txt b/CMakeLists.txt index 572b5e3a54f..4b89f2dbf05 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -398,7 +398,7 @@ unset(BASH CACHE) # Installation include(cmake/information_helpers.cmake) -ginkgo_interface_information() +ginkgo_pkg_information() ginkgo_git_information() include(cmake/get_info.cmake) @@ -408,18 +408,6 @@ if(GINKGO_BUILD_DOC) endif() -# add escape character '\' for space -string(REPLACE " " "\ " PKG_CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") -# add escape character '\' for space in regex mode -list(TRANSFORM GINKGO_INTERFACE_LINK_FLAGS REPLACE " " "\\\\ ") -list(TRANSFORM GINKGO_INTERFACE_CXX_FLAGS REPLACE " " "\\\\ ") -# convert the list to string -string(REPLACE ";" " " GINKGO_INTERFACE_CXX_FLAGS "${GINKGO_INTERFACE_CXX_FLAGS}") -string(REPLACE ";" " " GINKGO_INTERFACE_LINK_FLAGS "${GINKGO_INTERFACE_LINK_FLAGS}") -configure_file(${Ginkgo_SOURCE_DIR}/cmake/ginkgo.pc.in - ${Ginkgo_BINARY_DIR}/ginkgo.pc.in @ONLY) -file(GENERATE OUTPUT ${Ginkgo_BINARY_DIR}/ginkgo_$.pc - INPUT ${Ginkgo_BINARY_DIR}/ginkgo.pc.in) # WINDOWS NVCC has " inside the string, add escape character # to avoid config problem. diff --git a/cmake/GinkgoConfig.cmake.in b/cmake/GinkgoConfig.cmake.in index 04352d11c2b..0776801aa99 100644 --- a/cmake/GinkgoConfig.cmake.in +++ b/cmake/GinkgoConfig.cmake.in @@ -100,8 +100,8 @@ set(GINKGO_CUDA_HOST_COMPILER_SHORT "") # dummy value to stay consistent set(GINKGO_EXPORT_BINARY_DIR "@GINKGO_EXPORT_BINARY_DIR@") if(NOT GINKGO_EXPORT_BINARY_DIR) set_and_check(GINKGO_INSTALL_PREFIX "@PACKAGE_CMAKE_INSTALL_PREFIX@") - set_and_check(GINKGO_INSTALL_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_FULL_INCLUDEDIR@") - set_and_check(GINKGO_INSTALL_LIBRARY_DIR "@PACKAGE_CMAKE_INSTALL_FULL_LIBDIR@") + set_and_check(GINKGO_INSTALL_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@") + set_and_check(GINKGO_INSTALL_LIBRARY_DIR "@PACKAGE_CMAKE_INSTALL_LIBDIR@") set(GINKGO_INSTALL_RPATH_FOR_HIP "-Wl,-rpath,${GINKGO_INSTALL_LIBRARY_DIR}") set(GINKGO_INSTALL_RPATH @GINKGO_INSTALL_RPATH@) set(GINKGO_INSTALL_RPATH_USE_ORIGIN @GINKGO_INSTALL_RPATH_USE_ORIGIN@) @@ -147,60 +147,59 @@ set(THREADS_PREFER_PTHREAD_FLAG ON) # NOTE: we do not export benchmarks, examples, tests or devel tools # so `third_party` libraries are currently unneeded. +include(CMakeFindDependencyMacro) if(GINKGO_HAVE_PAPI_SDE) - find_package(PAPI REQUIRED COMPONENTS sde) + find_dependency(PAPI 7.0.1.0 COMPONENTS sde) endif() if(GINKGO_HAVE_HWLOC) - find_package(HWLOC REQUIRED) + find_dependency(HWLOC) endif() # Check for MPI if it is enabled if(GINKGO_BUILD_MPI) - find_package(MPI 3.1 COMPONENTS CXX REQUIRED) + find_dependency(MPI 3.1 COMPONENTS CXX) endif() # HIP and OpenMP depend on Threads::Threads in some circumstances, but don't find it if (GINKGO_BUILD_HIP OR GINKGO_BUILD_OMP) - find_package(Threads REQUIRED) + find_dependency(Threads) endif() # Needed because of a known issue with CUDA while linking statically. # For details, see https://gitlab.kitware.com/cmake/cmake/issues/18614 if((NOT GINKGO_BUILD_SHARED_LIBS) AND GINKGO_BUILD_CUDA) enable_language(CUDA) - find_package(CUDAToolkit REQUIRED) - find_package(NVTX REQUIRED) + find_dependency(CUDAToolkit) + find_dependency(NVTX) endif() if((NOT GINKGO_BUILD_SHARED_LIBS) AND GINKGO_BUILD_HIP) - find_package(HIP REQUIRED) - find_package(hipblas REQUIRED) - find_package(hipfft) # optional - find_package(hiprand REQUIRED) - find_package(hipsparse REQUIRED) - find_package(rocrand REQUIRED) - set(ROCTRACER_PATH "@ROCTRACER_PATH@") - if(GINKGO_HAVE_ROCTX) - find_package(ROCTX REQUIRED) - endif() + find_dependency(HIP) + find_dependency(hipblas) + find_dependency(hipfft) + find_dependency(hiprand) + find_dependency(hipsparse) + find_dependency(rocrand) + set_and_check(ROCTRACER_PATH "@ROCTRACER_PATH@") + find_dependency(ROCTX) endif() if((NOT GINKGO_BUILD_SHARED_LIBS) AND GINKGO_BUILD_SYCL) - find_package(MKL CONFIG REQUIRED HINTS "${GINKGO_MKL_ROOT}") - find_package(oneDPL REQUIRED HINTS "${GINKGO_DPL_ROOT}") + find_dependency(MKL CONFIG HINTS "${GINKGO_MKL_ROOT}") + find_dependency(oneDPL HINTS "${GINKGO_DPL_ROOT}") endif() if(GINKGO_HAVE_VTUNE) - find_package(VTune REQUIRED) + find_dependency(VTune) endif() if((NOT GINKGO_BUILD_SHARED_LIBS) AND GINKGO_HAVE_METIS) - find_package(METIS REQUIRED) + find_dependency(METIS) endif() if((NOT GINKGO_BUILD_SHARED_LIBS) AND GINKGO_HAVE_TAU) - find_package(PerfStubs REQUIRED) + find_dependency(PerfStubs) endif() # Check that the same compilers as for Ginkgo are used diff --git a/cmake/generate_pkg.cmake.in b/cmake/generate_pkg.cmake.in new file mode 100644 index 00000000000..c03dee1d00b --- /dev/null +++ b/cmake/generate_pkg.cmake.in @@ -0,0 +1,35 @@ +# This is run as a standalone script. Thus no cmake variables related to Ginkgo are +# available through the ${...} syntax. Instead, the file containing the actual values +# of the necessary variables is generated through `configure_file`. But this leaves +# generator expressions unresolved, so another pass through `file(GENERATE ...)` is +# necessary. That call can't be put into this file, since the script is used as part +# of `install(SCRIPT ...)` which doesn't support generator expressions in the script +# content + +# add escape character '\' for space +string(REPLACE " " "\ " GINKGO_PKG_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") +# add escape character '\' for space in regex mode +string(REPLACE ";" "\ " GINKGO_INTERFACE_LINK_FLAGS "@GINKGO_INTERFACE_LINK_FLAGS@") +string(REPLACE ";" "\ " GINKGO_INTERFACE_CXX_FLAGS "@GINKGO_INTERFACE_CXX_FLAGS@") + +set(GINKGO_INSTALL_LIBDIR "@CMAKE_INSTALL_LIBDIR@") +set(GINKGO_INSTALL_INCLUDEDIR "@CMAKE_INSTALL_INCLUDEDIR@") +set(GINKGO_PROJECT_NAME "@CMAKE_PROJECT_NAME@") +set(GINKGO_DESCRIPTION "@Ginkgo_DESCRIPTION@") +set(GINKGO_VERSION "@Ginkgo_VERSION@") + +set(GINKGO_INSTALL_PKGCONFIG_DIR "${GINKGO_PKG_INSTALL_PREFIX}/${GINKGO_INSTALL_LIBDIR}/pkgconfig") + +set(GINKGO_SOURCE_DIR "@Ginkgo_SOURCE_DIR@") +set(GINKGO_BINARY_DIR "@Ginkgo_BINARY_DIR@") + + +message(STATUS "Installing: ${GINKGO_INSTALL_PKGCONFIG_DIR}/ginkgo_$.pc") +configure_file(${GINKGO_SOURCE_DIR}/cmake/ginkgo.pc.in + ${GINKGO_INSTALL_PKGCONFIG_DIR}/ginkgo_$.pc + @ONLY) + +message(STATUS "Installing: ${GINKGO_INSTALL_PKGCONFIG_DIR}/ginkgo.pc") +configure_file(${GINKGO_SOURCE_DIR}/cmake/ginkgo.pc.in + ${GINKGO_INSTALL_PKGCONFIG_DIR}/ginkgo.pc + @ONLY) diff --git a/cmake/ginkgo.pc.in b/cmake/ginkgo.pc.in index bfbd0897291..cbcd89cb274 100644 --- a/cmake/ginkgo.pc.in +++ b/cmake/ginkgo.pc.in @@ -1,10 +1,10 @@ -prefix=@PKG_CMAKE_INSTALL_PREFIX@ -libdir=@CMAKE_INSTALL_FULL_LIBDIR@ -includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ +prefix=@GINKGO_PKG_INSTALL_PREFIX@ +libdir=${prefix}/@GINKGO_INSTALL_LIBDIR@ +includedir=${prefix}/@GINKGO_INSTALL_INCLUDEDIR@ -Name: @CMAKE_PROJECT_NAME@ -Description: @Ginkgo_DESCRIPTION@ -Version: @Ginkgo_VERSION@ +Name: @GINKGO_PROJECT_NAME@ +Description: @GINKGO_DESCRIPTION@ +Version: @GINKGO_VERSION@ URL: https://ginkgo-project.github.io/ Requires: diff --git a/cmake/information_helpers.cmake b/cmake/information_helpers.cmake index 7ac7fdfeda5..04687dfae5b 100644 --- a/cmake/information_helpers.cmake +++ b/cmake/information_helpers.cmake @@ -1,5 +1,7 @@ -# TODO: we may use file(GENERATE ... TARGET ...) to generate config file based on the target property -# when we bump the CMake minimum version to 3.15/3.19 +include(GNUInstallDirs) + +# This can't be replaced by `file(GENERATE ... TARGET ...)`, since the generator expressions +# might contain `COMPILE_LANG_AND_ID` which is not allowed in `file(GENERATE ...)` function(filter_generator_expressions INPUT OUTPUT) # See https://gitlab.kitware.com/cmake/cmake/-/blob/v3.22.2/Modules/FindMPI.cmake#L1218 # and other versions of this file for what we are removing here. @@ -22,91 +24,101 @@ endfunction() macro(ginkgo_interface_libraries_recursively INTERFACE_LIBS) # always add the interface to the list to keep the order information # Currently, it does not support the circular dependence and MSVC. - foreach(_libs ${INTERFACE_LIBS}) - if (TARGET ${_libs}) - if("${_libs}" MATCHES "ginkgo.*") - set(GINKGO_INTERFACE_LIB_NAME "-l${_libs}$<$:${CMAKE_DEBUG_POSTFIX}>") - list(APPEND GINKGO_INTERFACE_LIBS_FOUND "${GINKGO_INTERFACE_LIB_NAME}") - endif() - # Get the link flags and treat them - get_target_property(GINKGO_INTERFACE_LIBS_LINK_FLAGS "${_libs}" - INTERFACE_LINK_OPTIONS) - if (GINKGO_INTERFACE_LIBS_LINK_FLAGS) - filter_generator_expressions("${GINKGO_INTERFACE_LIBS_LINK_FLAGS}" - GINKGO_INTERFACE_LIB_NAME) - endif() - # Get the imported library - get_target_property(_libs_type "${_libs}" TYPE) - get_target_property(_libs_imported "${_libs}" IMPORTED) - if (_libs_imported AND NOT ${_libs_type} STREQUAL "INTERFACE_LIBRARY") - get_target_property(GINKGO_LIBS_IMPORTED_LIBS "${_libs}" IMPORTED_LOCATION_RELEASE) - if (NOT GINKGO_LIBS_IMPORTED_LIBS) - get_target_property(GINKGO_LIBS_IMPORTED_LIBS "${_libs}" IMPORTED_LOCATION) + foreach(_lib ${INTERFACE_LIBS}) + # hash library, so we don't get any duplicates, based on + # https://gitlab.kitware.com/cmake/cmake/-/blob/v3.28.1/Modules/CMakeFindDependencyMacro.cmake#L57 + string(SHA256 _gko_interface_lib_hash "${_lib}") + if(_GKO_${_gko_interface_lib_hash}_FOUND) + unset(_gko_interface_lib_hash) + else() + set("_GKO_${_gko_interface_lib_hash}_FOUND" ON) + if(TARGET ${_lib}) + if("${_lib}" MATCHES "ginkgo.*") + set(GINKGO_INTERFACE_LIB_NAME "-l${_lib}$<$:${CMAKE_DEBUG_POSTFIX}>") + list(APPEND GINKGO_INTERFACE_LIBS_FOUND "${GINKGO_INTERFACE_LIB_NAME}") endif() - if (GINKGO_LIBS_IMPORTED_LIBS) - list(APPEND GINKGO_INTERFACE_LIBS_FOUND "${GINKGO_LIBS_IMPORTED_LIBS}") + # Get the link flags and treat them + get_target_property(GINKGO_INTERFACE_LIBS_LINK_FLAGS "${_lib}" INTERFACE_LINK_OPTIONS) + if (GINKGO_INTERFACE_LIBS_LINK_FLAGS) + filter_generator_expressions("${GINKGO_INTERFACE_LIBS_LINK_FLAGS}" + GINKGO_INTERFACE_LIB_NAME) endif() - endif() - # Populate the include directories - get_target_property(GINKGO_LIBS_INTERFACE_INCS "${_libs}" - INTERFACE_INCLUDE_DIRECTORIES) - foreach(_incs ${GINKGO_LIBS_INTERFACE_INCS}) - filter_generator_expressions("${_incs}" GINKGO_INTERFACE_INC_FILTERED) - if (GINKGO_INTERFACE_INC_FILTERED AND NOT - "-I${GINKGO_INTERFACE_INC_FILTERED}" IN_LIST GINKGO_INTERFACE_CFLAGS_FOUND) - list(APPEND GINKGO_INTERFACE_CFLAGS_FOUND "-I${GINKGO_INTERFACE_INC_FILTERED}") + unset(GINKGO_INTERFACE_LIBS_LINK_FLAGS) + + # Get the imported library + get_target_property(_lib_type "${_lib}" TYPE) + get_target_property(_lib_imported "${_lib}" IMPORTED) + if (_lib_imported AND NOT ${_lib_type} STREQUAL "INTERFACE_LIBRARY") + get_target_property(GINKGO_LIBS_IMPORTED_LIBS "${_lib}" IMPORTED_LOCATION_RELEASE) + if (NOT GINKGO_LIBS_IMPORTED_LIBS) + get_target_property(GINKGO_LIBS_IMPORTED_LIBS "${_lib}" IMPORTED_LOCATION) + endif() + if (GINKGO_LIBS_IMPORTED_LIBS) + list(APPEND GINKGO_INTERFACE_LIBS_FOUND "${GINKGO_LIBS_IMPORTED_LIBS}") + endif() + unset(GINKGO_LIBS_IMPORTED_LIBS) endif() - endforeach() + unset(_lib_type) + unset(_lib_imported) - # Populate the compiler options and definitions if needed - get_target_property(GINKGO_LIBS_INTERFACE_DEFS "${_libs}" - INTERFACE_COMPILE_DEFINITIONS) - if (GINKGO_LIBS_INTERFACE_DEFS) - list(APPEND GINKGO_INTERFACE_CFLAGS_FOUND "${GINKGO_LIBS_INTERFACE_DEFS}") - endif() - get_target_property(GINKGO_LIBS_INTERFACE_OPTS "${_libs}" - INTERFACE_COMPILE_OPTIONS) - filter_generator_expressions("${GINKGO_LIBS_INTERFACE_OPTS}" GINKGO_LIBS_INTERFACE_OPTS_FILTERED) - if (GINKGO_LIBS_INTERFACE_OPTS) - list(APPEND GINKGO_INTERFACE_CFLAGS_FOUND "${GINKGO_LIBS_INTERFACE_OPTS_FILTERED}") - endif() + # Populate the include directories + get_target_property(GINKGO_LIBS_INTERFACE_INCS "${_lib}" INTERFACE_INCLUDE_DIRECTORIES) + foreach(_incs ${GINKGO_LIBS_INTERFACE_INCS}) + filter_generator_expressions("${_incs}" GINKGO_INTERFACE_INC_FILTERED) + if (GINKGO_INTERFACE_INC_FILTERED AND NOT + "-I${GINKGO_INTERFACE_INC_FILTERED}" IN_LIST GINKGO_INTERFACE_CFLAGS_FOUND) + list(APPEND GINKGO_INTERFACE_CFLAGS_FOUND "-I${GINKGO_INTERFACE_INC_FILTERED}") + endif() + unset(GINKGO_INTERFACE_INC_FILTERED) + endforeach() + unset(GINKGO_LIBS_INTERFACE_INCS) + + # Populate the compiler options and definitions if needed + get_target_property(GINKGO_LIBS_INTERFACE_DEFS "${_lib}" INTERFACE_COMPILE_DEFINITIONS) + if (GINKGO_LIBS_INTERFACE_DEFS) + list(APPEND GINKGO_INTERFACE_CFLAGS_FOUND "${GINKGO_LIBS_INTERFACE_DEFS}") + endif() + unset(GINKGO_LIBS_INTERFACE_DEFS) - # Keep recursing through the libraries - get_target_property(GINKGO_LIBS_INTERFACE_LIBS "${_libs}" - INTERFACE_LINK_LIBRARIES) - # removing $ - list(TRANSFORM GINKGO_LIBS_INTERFACE_LIBS REPLACE "\\$" "\\1") - ginkgo_interface_libraries_recursively("${GINKGO_LIBS_INTERFACE_LIBS}") - elseif(EXISTS "${_libs}") - list(APPEND GINKGO_INTERFACE_LIBS_FOUND "${_libs}") - elseif("${_libs}" STREQUAL "${CMAKE_DL_LIBS}") - list(APPEND GINKGO_INTERFACE_LIBS_FOUND "-l${_libs}") + get_target_property(GINKGO_LIBS_INTERFACE_OPTS "${_lib}" INTERFACE_COMPILE_OPTIONS) + filter_generator_expressions("${GINKGO_LIBS_INTERFACE_OPTS}" GINKGO_LIBS_INTERFACE_OPTS_FILTERED) + if (GINKGO_LIBS_INTERFACE_OPTS) + list(APPEND GINKGO_INTERFACE_CFLAGS_FOUND "${GINKGO_LIBS_INTERFACE_OPTS_FILTERED}") + endif() + unset(GINKGO_LIBS_INTERFACE_OPTS) + + # Keep recursing through the libraries + get_target_property(GINKGO_LIBS_INTERFACE_LIBS "${_lib}" INTERFACE_LINK_LIBRARIES) + # removing $ + list(TRANSFORM GINKGO_LIBS_INTERFACE_LIBS REPLACE "\\$" "\\1") + ginkgo_interface_libraries_recursively("${GINKGO_LIBS_INTERFACE_LIBS}") + unset(GINKGO_LIBS_INTERFACE_LIBS) + elseif(EXISTS "${_lib}") + list(APPEND GINKGO_INTERFACE_LIBS_FOUND "${_lib}") + elseif("${_lib}" STREQUAL "${CMAKE_DL_LIBS}") + list(APPEND GINKGO_INTERFACE_LIBS_FOUND "-l${_lib}") + endif() endif() + unset(_lib) endforeach() endmacro() -macro(ginkgo_interface_information) - set(GINKGO_INTERFACE_LINK_FLAGS "-L${CMAKE_INSTALL_FULL_LIBDIR}") +macro(ginkgo_pkg_information) + set(GINKGO_INTERFACE_LINK_FLAGS "-L\\\${prefix}/${CMAKE_INSTALL_LIBDIR}") unset(GINKGO_INTERFACE_LIBS_FOUND) unset(GINKGO_INTERFACE_CFLAGS_FOUND) # Prepare recursively populated library list list(APPEND GINKGO_INTERFACE_LIBS_FOUND "-lginkgo$<$:${CMAKE_DEBUG_POSTFIX}>") # Prepare recursively populated include directory list - list(APPEND GINKGO_INTERFACE_CFLAGS_FOUND - "-I${CMAKE_INSTALL_FULL_INCLUDEDIR}") + list(APPEND GINKGO_INTERFACE_CFLAGS_FOUND "-I\\\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") # Call the recursive interface libraries macro get_target_property(GINKGO_INTERFACE_LINK_LIBRARIES ginkgo INTERFACE_LINK_LIBRARIES) ginkgo_interface_libraries_recursively("${GINKGO_INTERFACE_LINK_LIBRARIES}") # Format and store the interface libraries found - # remove duplicates on the reversed list to keep the dependency in the end of list. - list(REVERSE GINKGO_INTERFACE_LIBS_FOUND) - list(REMOVE_DUPLICATES GINKGO_INTERFACE_LIBS_FOUND) - list(REVERSE GINKGO_INTERFACE_LIBS_FOUND) list(REMOVE_ITEM GINKGO_INTERFACE_LIBS_FOUND "") # keep it as list - set(GINKGO_INTERFACE_LINK_FLAGS - ${GINKGO_INTERFACE_LINK_FLAGS} ${GINKGO_INTERFACE_LIBS_FOUND}) + set(GINKGO_INTERFACE_LINK_FLAGS ${GINKGO_INTERFACE_LINK_FLAGS} ${GINKGO_INTERFACE_LIBS_FOUND}) unset(GINKGO_INTERFACE_LIBS_FOUND) # Format and store the interface cflags found list(REMOVE_DUPLICATES GINKGO_INTERFACE_CFLAGS_FOUND) @@ -114,7 +126,7 @@ macro(ginkgo_interface_information) # Keep it as list set(GINKGO_INTERFACE_CXX_FLAGS ${GINKGO_INTERFACE_CFLAGS_FOUND}) unset(GINKGO_INTERFACE_CFLAGS_FOUND) -endmacro(ginkgo_interface_information) +endmacro(ginkgo_pkg_information) macro(ginkgo_git_information) if(EXISTS "${Ginkgo_SOURCE_DIR}/.git") diff --git a/cmake/install_helpers.cmake b/cmake/install_helpers.cmake index e3c26017ca9..1e48c991e8a 100644 --- a/cmake/install_helpers.cmake +++ b/cmake/install_helpers.cmake @@ -2,9 +2,8 @@ include(CMakePackageConfigHelpers) include(GNUInstallDirs) -set(GINKGO_INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig") -set(GINKGO_INSTALL_CONFIG_DIR "${CMAKE_INSTALL_FULL_LIBDIR}/cmake/Ginkgo") -set(GINKGO_INSTALL_MODULE_DIR "${CMAKE_INSTALL_FULL_LIBDIR}/cmake/Ginkgo/Modules") +set(GINKGO_INSTALL_CONFIG_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/Ginkgo") +set(GINKGO_INSTALL_MODULE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/Ginkgo/Modules") # This function adds the correct RPATH properties to a Ginkgo target. # @@ -47,33 +46,41 @@ function(ginkgo_install_library name) install(TARGETS "${name}" EXPORT Ginkgo LIBRARY - DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}" + DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT Ginkgo_Runtime NAMELINK_COMPONENT Ginkgo_Development RUNTIME - DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" + DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT Ginkgo_Runtime ARCHIVE - DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}" + DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT Ginkgo_Development ) endfunction() function(ginkgo_install) - # pkg-config file - install(FILES ${Ginkgo_BINARY_DIR}/ginkgo_$.pc - DESTINATION "${GINKGO_INSTALL_PKGCONFIG_DIR}" - RENAME ginkgo.pc + # generate pkg-config file, a three-step process is necessary to include the correct install prefix + # Step 1: substitute project variables in the generation script + configure_file("${Ginkgo_SOURCE_DIR}/cmake/generate_pkg.cmake.in" + "${Ginkgo_BINARY_DIR}/cmake/generate_pkg.cmake" + @ONLY) + # Step 2: substitute generator expressions + file(GENERATE OUTPUT ${Ginkgo_BINARY_DIR}/cmake/generate_pkg_$.cmake + INPUT ${Ginkgo_BINARY_DIR}/cmake/generate_pkg.cmake) + # Step 3: at install time, call the generation script which has all variables + # except the install prefix already replaced. Use the install prefix + # that is specified at install time + install(SCRIPT "${Ginkgo_BINARY_DIR}/cmake/generate_pkg_$.cmake" COMPONENT Ginkgo_Development) # install the public header files install(DIRECTORY "${Ginkgo_SOURCE_DIR}/include/" - DESTINATION "${CMAKE_INSTALL_FULL_INCLUDEDIR}" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" COMPONENT Ginkgo_Development FILES_MATCHING PATTERN "*.hpp" ) install(FILES "${Ginkgo_BINARY_DIR}/include/ginkgo/config.hpp" - DESTINATION "${CMAKE_INSTALL_FULL_INCLUDEDIR}/ginkgo" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/ginkgo" COMPONENT Ginkgo_Development ) @@ -81,16 +88,16 @@ function(ginkgo_install) get_filename_component(HWLOC_LIB_PATH ${HWLOC_LIBRARIES} DIRECTORY) file(GLOB HWLOC_LIBS "${HWLOC_LIB_PATH}/libhwloc*") install(FILES ${HWLOC_LIBS} - DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}" + DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT Ginkgo_Runtime ) # We only use hwloc and not netloc install(DIRECTORY "${HWLOC_INCLUDE_DIRS}/hwloc" - DESTINATION "${CMAKE_INSTALL_FULL_INCLUDEDIR}" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" COMPONENT Ginkgo_Development ) install(FILES "${HWLOC_INCLUDE_DIRS}/hwloc.h" - DESTINATION "${CMAKE_INSTALL_FULL_INCLUDEDIR}" + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" COMPONENT Ginkgo_Development ) endif() @@ -114,7 +121,7 @@ function(ginkgo_install) "${Ginkgo_SOURCE_DIR}/cmake/GinkgoConfig.cmake.in" "${Ginkgo_BINARY_DIR}/cmake/GinkgoConfig.cmake" INSTALL_DESTINATION "${GINKGO_INSTALL_CONFIG_DIR}" - PATH_VARS CMAKE_INSTALL_FULL_INCLUDEDIR CMAKE_INSTALL_FULL_LIBDIR CMAKE_INSTALL_PREFIX GINKGO_INSTALL_MODULE_DIR + PATH_VARS CMAKE_INSTALL_INCLUDEDIR CMAKE_INSTALL_LIBDIR CMAKE_INSTALL_PREFIX GINKGO_INSTALL_MODULE_DIR ) install(FILES "${Ginkgo_BINARY_DIR}/cmake/GinkgoConfig.cmake" @@ -130,7 +137,7 @@ function(ginkgo_install) if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND BUILD_SHARED_LIBS) install(FILES "${Ginkgo_SOURCE_DIR}/dev_tools/scripts/gdb-ginkgo.py" - DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}" + DESTINATION "${CMAKE_INSTALL_LIBDIR}" RENAME "$-gdb.py" COMPONENT Ginkgo_Development) endif()