From 78246f89630bcd14ec10c550612a63e30e115d65 Mon Sep 17 00:00:00 2001 From: Terry Cojean Date: Mon, 6 May 2019 17:21:13 +0200 Subject: [PATCH] Make Ginkgo better abide to the `M12` policy. Support the `TPL` arguments for `GFLAGS, `GTEST` and `RAPIDJSON` as [explained in this document](http://dx.doi.org/10.6084/m9.figshare.4495133). + Move the `include` block of the extra CMake files to after the option declaration to ensure they are always set to the correct value. + Add a `ginkgo_add_tpl_target` to specifically add a target defined through the `TPL` arguments as an external library. + Modify `ginkgo_find_package` to support the `TPL` arguments. --- CMakeLists.txt | 19 ++++++------ INSTALL.md | 26 +++++++++++----- cmake/GinkgoConfig.cmake.in | 16 ++++++++++ cmake/package_helpers.cmake | 62 +++++++++++++++++++++++++++++++++---- 4 files changed, 100 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aa968b80817..96eb47d0083 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,12 +4,6 @@ project(Ginkgo LANGUAGES C CXX VERSION 1.0.0 DESCRIPTION "A numerical linear alg set(Ginkgo_VERSION_TAG "develop") set(PROJECT_VERSION_TAG ${Ginkgo_VERSION_TAG}) -# Load CMake helpers and modules -include(cmake/build_helpers.cmake) -include(cmake/create_test.cmake) -include(cmake/install_helpers.cmake) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") - # Ginkgo configuration options option(GINKGO_DEVEL_TOOLS "Add development tools to the build system" ON) option(GINKGO_BUILD_TESTS "Generate build files for unit tests" ON) @@ -71,7 +65,12 @@ if (GINKGO_WITH_IWYU) endif() +# Load CMake helpers and modules +include(cmake/build_helpers.cmake) include(cmake/build_type_helpers.cmake) +include(cmake/create_test.cmake) +include(cmake/install_helpers.cmake) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") # Find important header files, store the definitions in include/ginkgo/config.h.in @@ -91,12 +90,12 @@ configure_file(${Ginkgo_SOURCE_DIR}/include/ginkgo/config.hpp.in # Try to find the third party packages before using our subdirectories include(cmake/package_helpers.cmake) -ginkgo_find_package(GTest 1.8.1) -ginkgo_find_package(gflags 2.2.2) -ginkgo_find_package(RapidJSON 1.1.0) +ginkgo_find_package(GTest "GTest::GTest;GTest::Main" FALSE 1.8.1) +ginkgo_find_package(gflags gflags FALSE 2.2.2) +ginkgo_find_package(RapidJSON rapidjson TRUE 1.1.0) add_subdirectory(third_party) # Third-party tools and libraries -# Needs to be first in order for `CMAKE_CUDA_DEVICE_LINK_EXECUTABLE` to be +# Needs to be first in order for `CMAKE_CUDA_DEVICE_LINK_EXECUTABLE` to be # propagated to the other parts of Ginkgo in case of building as static libraries if(GINKGO_BUILD_CUDA) add_subdirectory(cuda) # High-performance kernels for NVIDIA GPUs diff --git a/INSTALL.md b/INSTALL.md index cfa0d4cc8e8..a7026e803f3 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -113,15 +113,27 @@ packages can be turned off by disabling the relevant options. By default, Ginkgo uses the internal version of each package. For each of the packages `GTEST`, `GFLAGS`, `RAPIDJSON` and `CAS`, it is possible to force -Ginkgo to try to use an external version of a package. For this, set the CMake -option `-DGINKGO_USE_EXTERNAL_=ON`. - -If the external packages were not installed to the default location, the -CMake option `-DCMAKE_PREFIX_PATH=` needs to be set to the semicolon -(`;`) separated list of install paths of these external packages. For more -Information, see the [CMake documentation for CMAKE_PREFIX_PATH](https://cmake.org/cmake/help/v3.9/variable/CMAKE_PREFIX_PATH.html) +Ginkgo to try to use an external version of a package. For this, Ginkgo provides +two ways to find packages. To rely on the CMake `find_package` command, use the +CMake option `-DGINKGO_USE_EXTERNAL_=ON`. Note that, if the external +packages were not installed to the default location, the CMake option +`-DCMAKE_PREFIX_PATH=` needs to be set to the semicolon (`;`) +separated list of install paths of these external packages. For more +Information, see the [CMake documentation for +CMAKE_PREFIX_PATH](https://cmake.org/cmake/help/v3.9/variable/CMAKE_PREFIX_PATH.html) for details. +To manually configure the paths Ginkgo relies on the [standard xSDK Installation +policies](https://xsdk.info/policies/) for all packages except `CAS` (as it is +neither a library nor a header, it cannot be expressed through the `TPL` +format): ++ `-DTPL_ENABLE_=ON` ++ `-DTPL__LIBRARIES=/path/to/libraries.{so|a}` ++ `-DTPL__INCLUDE_DIRS=/path/to/header/directory` + +When applicable (e.g. for `GTest` libraries), a `;` separated list can be given +to the `TPL__{LIBRARIES|INCLUDE_DIRS}` variables. + ### Installing Ginkgo To install Ginkgo into the specified folder, execute the following command in diff --git a/cmake/GinkgoConfig.cmake.in b/cmake/GinkgoConfig.cmake.in index 8a41d9227e2..1db5cbbffa4 100644 --- a/cmake/GinkgoConfig.cmake.in +++ b/cmake/GinkgoConfig.cmake.in @@ -61,6 +61,22 @@ set(GINKGO_JACOBI_FULL_OPTIMIZATIONS @GINKGO_JACOBI_FULL_OPTIMIZATIONS@) set(GINKGO_CUDA_ARCHITECTURES @GINKGO_CUDA_ARCHITECTURES@) set(GINKGO_CUDA_HOST_COMPILER @CMAKE_CUDA_HOST_COMPILER@) +# Ginkgo external package variables +set(GINKGO_USE_EXTERNAL_CAS "@GINKGO_USE_EXTERNAL_CAS@") +set(GINKGO_USE_EXTERNAL_GTEST "@GINKGO_USE_EXTERNAL_GTEST@") +set(GINKGO_USE_EXTERNAL_GFLAGS "@GINKGO_USE_EXTERNAL_GFLAGS@") +set(GINKGO_USE_EXTERNAL_RAPIDJSON "@GINKGO_USE_EXTERNAL_RAPIDJSON@") + +set(TPL_ENABLE_GTEST "@TPL_ENABLE_GTEST@") +set(TPL_GTEST_LIBRARIES "@TPL_GTEST_LIBRARIES@") +set(TPL_GTEST_INCLUDE_DIRS "@TPL_GTEST_INCLUDE_DIRS@") +set(TPL_ENABLE_GFLAGS "@TPL_ENABLE_GFLAGS@") +set(TPL_GFLAGS_LIBRARIES "@TPL_GFLAGS_LIBRARIES@") +set(TPL_GFLAGS_INCLUDE_DIRS "@TPL_GFLAGS_INCLUDE_DIRS@") +set(TPL_ENABLE_RAPIDJSON "@TPL_ENABLE_RAPIDJSON@") +set(TPL_RAPIDJSON_LIBRARIES "@TPL_RAPIDJSON_LIBRARIES@") +set(TPL_RAPIDJSON_INCLUDE_DIRS "@TPL_RAPIDJSON_INCLUDE_DIRS@") + # Ginkgo installation configuration set(GINKGO_CONFIG_FILE_PATH "${CMAKE_CURRENT_LIST_DIR}") string(REPLACE "@GINKGO_INSTALL_CONFIG_DIR@" "" GINKGO_INSTALL_PREFIX "${GINKGO_CONFIG_FILE_PATH}") diff --git a/cmake/package_helpers.cmake b/cmake/package_helpers.cmake index 342c15ece7b..7f0cab28548 100644 --- a/cmake/package_helpers.cmake +++ b/cmake/package_helpers.cmake @@ -25,6 +25,40 @@ function(ginkgo_load_git_package package_name package_url package_tag) endfunction() +# Add external target to external project. +# Create a new target and declare it as `IMPORTED` for libraries or `INTERFACE` +# for header only projects. +# +# \param new_target New target for the external project +# \param external_name Name of the external project +# \param includedir Path to include directory +# \param libdir Path to library directory +# \param header_only Boolean indicating if this should be a header only target +# +macro(ginkgo_add_tpl_target new_target external_name includedir libdir header_only) + # Declare include directories and library files + set(${external_name}_INCLUDE_DIR "${includedir}") + set(${external_name}_LIBRARY "${libdir}") + + # Create an IMPORTED external library available in the GLOBAL scope + if (${header_only}) + add_library(${new_target} INTERFACE) + else() + add_library(${new_target} UNKNOWN IMPORTED GLOBAL) + endif() + + # Set the target's properties, namely library file and include directory + if (NOT ${header_only}) + foreach (lib in LISTS ${${external_name}_LIBRARY}) + set_target_properties(${new_target} PROPERTIES IMPORTED_LOCATION ${lib}) + endforeach() + endif() + foreach (inc in LISTS ${${external_name}_INCLUDE_DIR}) + set_target_properties(${new_target} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${inc}) + endforeach() +endmacro(ginkgo_add_tpl_target) + + # Add external target to external project. # Create a new target and declare it as `IMPORTED` for libraries or `INTERFACE` # for header only projects. @@ -89,16 +123,32 @@ endmacro(ginkgo_add_subdirectory) # If the user does not specify otherwise, try to find the package. # # \param package_name Name of package to be found +# \param target_list For TPL packages, declare a new target for each library +# \param header_only For TPL packages, declare the tpl package as header only # \param ARGN Extra specifications for the package finder # -macro(ginkgo_find_package package_name) +macro(ginkgo_find_package package_name target_list header_only) string(TOUPPER ${package_name} _UPACKAGE_NAME) - if (GINKGO_USE_EXTERNAL_${_UPACKAGE_NAME}) - find_package(${package_name} QUIET ${ARGN}) - if (${package_name}_FOUND) - message(STATUS "Using external version of package ${package_name}. In case of problems, consider setting -DGINKGO_USE_EXTERNAL_${_UPACKAGE_NAME}=OFF.") + if (GINKGO_USE_EXTERNAL_${_UPACKAGE_NAME} OR TPL_ENABLE_${_UPACKAGE_NAME}) + if (TPL_${_UPACKAGE_NAME}_LIBRARIES AND TPL_${_UPACKAGE_NAME}_INCLUDE_DIRS) + set(${package_name}_FOUND "${TPL_${_UPACKAGE_NAME}_LIBRARIES};${TPL_${_UPACKAGE_NAME}_INCLUDE_DIRS}") + set(_target_list ${target_list}) # CMake weirdness: target_list is not a list anymore + # Count the number of elements in the list. Substract by one to iterate from 0 to the end. + list(LENGTH _target_list _GKO_len1) + math(EXPR _GKO_len2 "${_GKO_len1} - 1") + foreach(val RANGE ${_GKO_len2}) + list(GET _target_list ${val} target) # access element number "val" in _target_list + list(GET TPL_${_UPACKAGE_NAME}_LIBRARIES ${val} lib) + ginkgo_add_tpl_target("${target}" "${_UPACKAGE_NAME}" "${TPL_${_UPACKAGE_NAME}_INCLUDE_DIRS}" + "${lib}" ${header_only}) + endforeach() else() - message(STATUS "Ginkgo could not find ${package_name}. The internal version will be used. Consider setting `-DCMAKE_PREFIX_PATH` if the package was not system-installed.") + find_package(${package_name} QUIET ${ARGN}) + if (${package_name}_FOUND) + message(STATUS "Using external version of package ${package_name}. In case of problems, consider setting -DGINKGO_USE_EXTERNAL_${_UPACKAGE_NAME}=OFF.") + else() + message(STATUS "Ginkgo could not find ${package_name}. The internal version will be used. Consider setting `-DCMAKE_PREFIX_PATH` if the package was not system-installed.") + endif() endif() endif() endmacro(ginkgo_find_package)