From b39fdf52076c4f5f754ebb996f5edf8407c9a443 Mon Sep 17 00:00:00 2001 From: Bryan Tan Date: Tue, 19 Dec 2023 00:41:18 -0800 Subject: [PATCH] Improvements to make SPARTA easier to use as a dependency Summary: This PR includes some improvements to the CMake configuration that makes SPARTA easier to use as a dependency (or at least I've found these useful for a project I'm working on). Specifically: * Generate a `sparta-config.cmake` file that is created in both the build folder and for the install target. This enables the library to be used with `find_package`. * (Breaking change) Install the `sparta_target.cmake` to `$LIBDIR/cmake/sparta` instead of `$PREFIX/cmake` to support \*nix systems as well as `find_package`. While this is a breaking change, it's unlikely that anyone used the installed file due to the bugs observed in https://github.com/facebook/SPARTA/issues/23. * (Breaking change) Use `sparta::` as the target namespace when exporting the `sparta` target. Projects that previously included the `sparta_target.cmake` will need to be updated to use `sparta::sparta` instead of `sparta` when specifying it as a dependency. * Update the README with additional tips on how to use SPARTA in CMake projects. This PR is stacked on top of https://github.com/facebook/SPARTA/issues/23, and I'll rebase after it is merged. X-link: https://github.com/facebook/SPARTA/pull/24 Reviewed By: arnaudvenet Differential Revision: D52238117 Pulled By: arthaud fbshipit-source-id: abfad1312d5357a5adc64335d7a51e80935cf111 --- sparta/CMakeLists.txt | 27 ++++++++++++++++--- sparta/README.md | 29 +++++++++++++++++++++ sparta/cmake_modules/Commons.cmake | 8 +++--- sparta/cmake_modules/gtest.cmake.in | 4 +-- sparta/cmake_modules/sparta-config.cmake.in | 11 ++++++++ 5 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 sparta/cmake_modules/sparta-config.cmake.in diff --git a/sparta/CMakeLists.txt b/sparta/CMakeLists.txt index f549e395e7..1676d8ff74 100644 --- a/sparta/CMakeLists.txt +++ b/sparta/CMakeLists.txt @@ -7,7 +7,7 @@ cmake_minimum_required(VERSION 3.0.2) project("sparta") include(CTest) -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH}) +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH}) include(Commons) if (NOT CMAKE_BUILD_TYPE) @@ -31,6 +31,8 @@ target_include_directories(sparta INTERFACE target_link_libraries(sparta INTERFACE ${Boost_LIBRARIES}) +add_library(sparta::sparta ALIAS sparta) + ################################################### # install and export ################################################### @@ -46,10 +48,29 @@ install(TARGETS sparta EXPORT sparta_target ) install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) -install(EXPORT sparta_target DESTINATION cmake) +install(EXPORT sparta_target + FILE sparta_target.cmake + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/sparta" + NAMESPACE sparta:: +) # This makes the project importable from the build directory -export(TARGETS sparta FILE sparta_target.cmake) +export(TARGETS sparta + FILE sparta_target.cmake + NAMESPACE sparta:: +) + +# Generate CMake config file that can be used in other projects +include(CMakePackageConfigHelpers) +configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules/sparta-config.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/sparta-config.cmake" + INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/sparta" +) +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/sparta-config.cmake" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/sparta" +) ################################################### # test diff --git a/sparta/README.md b/sparta/README.md index 4d73c7a1d0..011dae90cb 100644 --- a/sparta/README.md +++ b/sparta/README.md @@ -88,6 +88,35 @@ To copy the header files into `/usr/local/include/sparta` and set up a cmake lib sudo make install ``` +### CMake Setup + +If you are using CMake for your project, you can also use SPARTA in the following ways: + +* A system-wide installation of SPARTA will contain a CMake configuration file that exports the library as `sparta::sparta`. This enables the use of `find_package` to locate SPARTA. For example: + + ```cmake + find_package(Boost REQUIRED COMPONENTS thread) # required by SPARTA + find_package(sparta REQUIRED) + add_library(MyAnalysisLibrary) + target_link_libraries(MyAnalysisLibrary PUBLIC sparta::sparta) + ``` + +* If you have cloned and "built" SPARTA locally, you can use a `find_package` call (such as the one above) and run CMake with the `-Dsparta_DIR=` to load the library: + + ```sh + # Assuming you are at the top-level of your project that uses SPARTA + mkdir build && cd build + cmake .. -Dsparta_DIR=path/to/your/sparta/build + ``` + +* SPARTA can be added as a subdirectory in your project: + + ```cmake + # assuming you have cloned SPARTA into a folder named sparta + add_subdirectory(sparta) + add_library(MyAnalysisLibrary) + target_link_libraries(MyAnalysisLibrary PUBLIC sparta::sparta) + ``` ## Issues diff --git a/sparta/cmake_modules/Commons.cmake b/sparta/cmake_modules/Commons.cmake index 97b39c156d..d9433b8cd6 100644 --- a/sparta/cmake_modules/Commons.cmake +++ b/sparta/cmake_modules/Commons.cmake @@ -44,14 +44,14 @@ macro(add_dependent_packages_for_sparta) configure_file(cmake_modules/gtest.cmake.in googletest-download/CMakeLists.txt) execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . RESULT_VARIABLE result - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download ) if(result) message(FATAL_ERROR "CMake step for googletest failed: ${result}") endif() execute_process(COMMAND ${CMAKE_COMMAND} --build . RESULT_VARIABLE result - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download ) if(result) message(FATAL_ERROR "Build step for googletest failed: ${result}") @@ -64,8 +64,8 @@ macro(add_dependent_packages_for_sparta) # Add googletest directly to our build. This defines # the gtest and gtest_main targets. add_subdirectory( - ${CMAKE_BINARY_DIR}/googletest-src - ${CMAKE_BINARY_DIR}/googletest-build + ${CMAKE_CURRENT_BINARY_DIR}/googletest-src + ${CMAKE_CURRENT_BINARY_DIR}/googletest-build EXCLUDE_FROM_ALL ) diff --git a/sparta/cmake_modules/gtest.cmake.in b/sparta/cmake_modules/gtest.cmake.in index b66ee3c2aa..0a92d2d556 100644 --- a/sparta/cmake_modules/gtest.cmake.in +++ b/sparta/cmake_modules/gtest.cmake.in @@ -10,8 +10,8 @@ include(ExternalProject) ExternalProject_Add(googletest GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG release-1.8.1 - SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src" - BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build" + SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src" + BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" diff --git a/sparta/cmake_modules/sparta-config.cmake.in b/sparta/cmake_modules/sparta-config.cmake.in new file mode 100644 index 0000000000..05b64327fd --- /dev/null +++ b/sparta/cmake_modules/sparta-config.cmake.in @@ -0,0 +1,11 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) +find_dependency(Boost COMPONENTS thread) + +include("${CMAKE_CURRENT_LIST_DIR}/sparta_target.cmake")