Skip to content

Commit

Permalink
Merge Make ginkgo.pc libraries be found recursively
Browse files Browse the repository at this point in the history
Small improvement for packages relying on our `ginkgo.pc`

This makes the libraries be found recursively so that `-lhwloc` which is also a dependency of `ginkgo_device` is found automatically. The aim is that this would also adapt to any other library structure change. This solution is obviously not bulletproof, but it should work in most cases.

Related PR: #923
  • Loading branch information
tcojean authored Apr 13, 2022
2 parents fda151c + cbd70da commit 8619e77
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 11 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,9 @@ if(GINKGO_BUILD_DOC)
endif()

configure_file(${Ginkgo_SOURCE_DIR}/cmake/ginkgo.pc.in
${Ginkgo_BINARY_DIR}/ginkgo.pc @ONLY)
${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
6 changes: 3 additions & 3 deletions cmake/ginkgo.pc.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ prefix=@CMAKE_INSTALL_PREFIX@
libdir=${prefix}/@GINKGO_INSTALL_LIBRARY_DIR@
includedir=${prefix}/@GINKGO_INSTALL_INCLUDE_DIR@

Name: @Ginkgo_NAME@
Name: @CMAKE_PROJECT_NAME@
Description: @Ginkgo_DESCRIPTION@
Version: @Ginkgo_VERSION@
URL: https://ginkgo-project.github.io/

Requires:
Libs: @GINKGO_INTERFACE_LINK_FLAGS@
Cflags: @GINKGO_INTERFACE_CXX_FLAGS@
Libs: @GINKGO_INTERFACE_LINK_FLAGS@
Cflags: @GINKGO_INTERFACE_CXX_FLAGS@
114 changes: 109 additions & 5 deletions cmake/information_helpers.cmake
Original file line number Diff line number Diff line change
@@ -1,11 +1,115 @@
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.
string(REGEX REPLACE "[$<]+COMPILE.*>:.+[>]+(.+)" "\\1" TMP "${INPUT}")
# There can be at least two type of SHELL, one with generator $<> form, one
# without (v3.16.x). Sometimes, it also has extra arguments. We need to do
# at least a greedy regex also consuming the final `>` if present before
# doing a non greedy one for the leftovers.
string(REGEX REPLACE "[$<A-Z_:]+SHELL:(.+)>+" "\\1" TMP "${TMP}")
string(REGEX REPLACE "[$<A-Z_:]*SHELL:(.+)>*" "\\1" TMP "${TMP}")
string(REGEX REPLACE ".+INTERFACE:.+>" "" TMP "${TMP}")
string(REGEX REPLACE "\$<COMMA>" "," TMP "${TMP}")
# Ignore hwloc include if it is the internal one
string(REGEX REPLACE "${PROJECT_BINARY_DIR}.*hwloc/src/include.*" "" TMP "${TMP}")
set(${OUTPUT} "${TMP}" PARENT_SCOPE)
endfunction()

macro(ginkgo_interface_libraries_recursively INTERFACE_LIBS)
foreach(_libs ${INTERFACE_LIBS})
if (NOT "${_libs}" IN_LIST GINKGO_INTERFACE_LIBS_FOUND
AND NOT "-l${_libs}" IN_LIST GINKGO_INTERFACE_LIBS_FOUND)
if (TARGET ${_libs})
if (upper_CMAKE_BUILD_TYPE STREQUAL "DEBUG" AND "${_libs}" MATCHES "ginkgo.*")
set(GINKGO_INTERFACE_LIB_NAME "-l${_libs}${CMAKE_DEBUG_POSTFIX}")
elseif("${_libs}" MATCHES "ginkgo.*") # Ginkgo libs are appended in the form -l
set(GINKGO_INTERFACE_LIB_NAME "-l${_libs}")
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()
if (NOT "${GINKGO_INTERFACE_LIB_NAME}" IN_LIST GINKGO_INTERFACE_LIBS_FOUND)
list(APPEND GINKGO_INTERFACE_LIBS_FOUND "${GINKGO_INTERFACE_LIB_NAME}")
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}")
endif()
endforeach()

# 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()

# Keep recursing through the libraries
get_target_property(GINKGO_LIBS_INTERFACE_LIBS "${_libs}"
INTERFACE_LINK_LIBRARIES)
ginkgo_interface_libraries_recursively("${GINKGO_LIBS_INTERFACE_LIBS}")
elseif(EXISTS "${_libs}")
if ("${_libs}" MATCHES "${PROJECT_BINARY_DIR}.*hwloc.so")
list(APPEND GINKGO_INTERFACE_LIBS_FOUND "${CMAKE_INSTALL_PREFIX}/${GINKGO_INSTALL_LIBRARY_DIR}/libhwloc.so")
else()
list(APPEND GINKGO_INTERFACE_LIBS_FOUND "${_libs}")
endif()
endif()
endif()
endforeach()
endmacro()

macro(ginkgo_interface_information)
set(GINKGO_INTERFACE_LINK_FLAGS "-L${CMAKE_INSTALL_PREFIX}/${GINKGO_INSTALL_LIBRARY_DIR}")
unset(GINKGO_INTERFACE_LIBS_FOUND)
unset(GINKGO_INTERFACE_CFLAGS_FOUND)
# Prepare recursively populated library list
string(TOUPPER "${CMAKE_BUILD_TYPE}" upper_CMAKE_BUILD_TYPE)
if (upper_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
list(APPEND GINKGO_INTERFACE_LIBS_FOUND "-lginkgo${CMAKE_DEBUG_POSTFIX}")
else()
list(APPEND GINKGO_INTERFACE_LIBS_FOUND "-lginkgo")
endif()
# Prepare recursively populated include directory list
list(APPEND GINKGO_INTERFACE_CFLAGS_FOUND
"-I${CMAKE_INSTALL_PREFIX}/${GINKGO_INSTALL_INCLUDE_DIR}")

# Call the recursive interface libraries macro
get_target_property(GINKGO_INTERFACE_LINK_LIBRARIES ginkgo INTERFACE_LINK_LIBRARIES)
set(GINKGO_INTERFACE_LINK_FLAGS "-L${CMAKE_INSTALL_PREFIX}/${GINKGO_INSTALL_LIBRARY_DIR} -lginkgo")
set(GINKGO_INTERFACE_CXX_FLAGS "-I${CMAKE_INSTALL_PREFIX}/${GINKGO_INSTALL_INCLUDE_DIR}")
ginkgo_interface_libraries_recursively("${GINKGO_INTERFACE_LINK_LIBRARIES}")

foreach(_libs IN LISTS GINKGO_INTERFACE_LINK_LIBRARIES)
set(GINKGO_INTERFACE_LINK_FLAGS "${GINKGO_INTERFACE_LINK_FLAGS} -l${_libs}")
endforeach()
# Format and store the interface libraries found
list(REMOVE_DUPLICATES GINKGO_INTERFACE_LIBS_FOUND)
list(REMOVE_ITEM GINKGO_INTERFACE_LIBS_FOUND "")
string(REPLACE ";" " "
GINKGO_FORMATTED_INTERFACE_LIBS_FOUND "${GINKGO_INTERFACE_LIBS_FOUND}")
set(GINKGO_INTERFACE_LINK_FLAGS
"${GINKGO_INTERFACE_LINK_FLAGS} ${GINKGO_FORMATTED_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 "")
string(REPLACE ";" " "
GINKGO_FORMATTED_INTERFACE_CFLAGS_FOUND "${GINKGO_INTERFACE_CFLAGS_FOUND}")
set(GINKGO_INTERFACE_CXX_FLAGS "${GINKGO_FORMATTED_INTERFACE_CFLAGS_FOUND}")
unset(GINKGO_INTERFACE_CFLAGS_FOUND)
endmacro(ginkgo_interface_information)

macro(ginkgo_git_information)
Expand Down
4 changes: 3 additions & 1 deletion cmake/install_helpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ endfunction()

function(ginkgo_install)
# pkg-config file
install(FILES "${Ginkgo_BINARY_DIR}/ginkgo.pc" DESTINATION "${GINKGO_INSTALL_PKGCONFIG_DIR}")
install(FILES ${Ginkgo_BINARY_DIR}/ginkgo_$<CONFIG>.pc
DESTINATION "${GINKGO_INSTALL_PKGCONFIG_DIR}"
RENAME ginkgo.pc)

# install the public header files
install(DIRECTORY "${Ginkgo_SOURCE_DIR}/include/"
Expand Down
4 changes: 3 additions & 1 deletion third_party/hwloc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ ginkgo_load_and_configure_package(hwloc_external "https://download.open-mpi.org/
)

add_library(hwloc SHARED IMPORTED GLOBAL)
add_dependencies(hwloc hwloc_external )
add_dependencies(hwloc hwloc_external)
file(MAKE_DIRECTORY ${TPL_HWLOC_PATH}/lib/)
file(GLOB HWLOC_LIBS "${TPL_HWLOC_PATH}/build/hwloc/.libs/libhwloc.so*")
configure_file("${TPL_HWLOC_PATH}/build/include/hwloc/autogen/config.h" "${TPL_HWLOC_PATH}/src/include/hwloc/autogen/config.h" COPYONLY)
foreach(lib ${HWLOC_LIBS})
get_filename_component(lib_name ${lib} NAME)
configure_file("${lib}" "${TPL_HWLOC_PATH}/lib/${lib_name}" COPYONLY)
endforeach()
# NOTE: if changing this (e.g. to `.a`), please update the special case in
# `cmake/information_helpers.cmake`
set(HWLOC_LIBRARIES "${TPL_HWLOC_PATH}/lib/libhwloc.so" CACHE FILEPATH "The path to HWLOC library libhwloc.so" FORCE)
set(HWLOC_INCLUDE_DIRS "${TPL_HWLOC_PATH}/src/include" CACHE PATH "The directory containing the hwloc header, hwloc.h" FORCE)
set_target_properties(hwloc PROPERTIES IMPORTED_LOCATION ${HWLOC_LIBRARIES})
Expand Down

0 comments on commit 8619e77

Please sign in to comment.