Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Ginkgo to Use the --prefix Option #1534

Merged
merged 5 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 1 addition & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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_$<CONFIG>.pc
INPUT ${Ginkgo_BINARY_DIR}/ginkgo.pc.in)

# WINDOWS NVCC has " inside the string, add escape character
# to avoid config problem.
Expand Down
45 changes: 22 additions & 23 deletions cmake/GinkgoConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -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@)
Expand Down Expand Up @@ -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
Expand Down
35 changes: 35 additions & 0 deletions cmake/generate_pkg.cmake.in
Original file line number Diff line number Diff line change
@@ -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_$<CONFIG>.pc")
configure_file(${GINKGO_SOURCE_DIR}/cmake/ginkgo.pc.in
${GINKGO_INSTALL_PKGCONFIG_DIR}/ginkgo_$<CONFIG>.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)
12 changes: 6 additions & 6 deletions cmake/ginkgo.pc.in
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
146 changes: 79 additions & 67 deletions cmake/information_helpers.cmake
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -22,99 +24,109 @@ 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}$<$<CONFIG:Debug>:${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}$<$<CONFIG:Debug>:${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 $<LINK_ONLY:>
list(TRANSFORM GINKGO_LIBS_INTERFACE_LIBS REPLACE "\\$<LINK_ONLY:(.*)>" "\\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 $<LINK_ONLY:>
list(TRANSFORM GINKGO_LIBS_INTERFACE_LIBS REPLACE "\\$<LINK_ONLY:(.*)>" "\\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$<$<CONFIG:Debug>:${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)
list(REMOVE_ITEM GINKGO_INTERFACE_CFLAGS_FOUND "")
# 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")
Expand Down
Loading
Loading