| # Adding Export Configuration # |
| |
| During Step 4 of the tutorial we added the ability for CMake to install the |
| library and headers of the project. During Step 7 we added the ability |
| to package up this information so it could be distributed to other people. |
| |
| The next step is to add the necessary information so that other CMake projects |
| can use our project, be it from a build directory, a local install or when |
| packaged. |
| |
| The first step is to update our install(TARGETS) commands to not only specify |
| a DESTINATION but also an EXPORT. The EXPORT keyword generates and installs a |
| CMake file containing code to import all targets listed in the install command |
| from the installation tree. So let's go ahead and explicitly EXPORT the |
| MathFunctions library by updating the install command in |
| MathFunctions/CMakeLists.txt to look like: |
| |
| install(TARGETS MathFunctions DESTINATION lib EXPORT MathFunctionsTargets) |
| |
| Now that we have MathFunctions being exported, we also need to explicitly install |
| the generated MathFunctionsTargets.cmake file. This is done by adding |
| the following to the bottom of the top-level CMakeLists.txt: |
| |
| # install the configuration targets |
| install(EXPORT MathFunctionsTargets |
| FILE MathFunctionsTargets.cmake |
| DESTINATION lib/cmake/MathFunctions |
| ) |
| |
| At this point you should try and run CMake. If everything is setup properly |
| you will see that CMake will generate an error that looks like: |
| |
| Target "MathFunctions" INTERFACE_INCLUDE_DIRECTORIES property contains |
| path: |
| |
| "/Users/robert/Documents/CMakeClass/Tutorial/Step11/MathFunctions" |
| |
| which is prefixed in the source directory. |
| |
| What CMake is trying to say is that during generating the export information |
| it will export a path that is intrinsically tied to the current machine and |
| will not be valid on other machines. The solution to this is to update the |
| MathFunctions target_include_directories to understand that it needs different |
| INTERFACE locations when being used from within the build directory and from an |
| install / package. This means converting the target_include_directories |
| call for MathFunctions to look like: |
| |
| target_include_directories(MathFunctions |
| INTERFACE |
| $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> |
| $<INSTALL_INTERFACE:include> |
| ) |
| |
| Once this has been updated, we can re-run CMake and see verify that it doesn't |
| warn anymore. |
| |
| At this point, we have CMake properly packaging the target information that is |
| required but we will still need to generate a MathFunctionsConfig.cmake, so |
| that the CMake find_package command can find our project. So let's go ahead and |
| add a new file to the top-level of the project called Config.cmake.in with the |
| following contents: |
| |
| @PACKAGE_INIT@ |
| |
| include ( "${CMAKE_CURRENT_LIST_DIR}/MathFunctionsTargets.cmake" ) |
| |
| Then, to properly configure and install that file, add the following to the |
| bottom of the top-level CMakeLists: |
| |
| include(CMakePackageConfigHelpers) |
| # generate the config file that is includes the exports |
| configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in |
| "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake" |
| INSTALL_DESTINATION "lib/cmake/example" |
| NO_SET_AND_CHECK_MACRO |
| NO_CHECK_REQUIRED_COMPONENTS_MACRO |
| ) |
| # generate the version file for the config file |
| write_basic_package_version_file( |
| "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake" |
| VERSION "${Tutorial_VERSION_MAJOR}.${Tutorial_VERSION_MINOR}" |
| COMPATIBILITY AnyNewerVersion |
| ) |
| |
| # install the configuration file |
| install(FILES |
| ${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake |
| DESTINATION lib/cmake/MathFunctions |
| ) |
| |
| At this point, we have generated a relocatable CMake Configuration for our project |
| that can be used after the project has been installed or packaged. If we want |
| our project to also be used from a build directory we only have to add |
| the following to the bottom of the top level CMakeLists: |
| |
| # generate the export targets for the build tree |
| # needs to be after the install(TARGETS ) command |
| export(EXPORT MathFunctionsTargets |
| FILE "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsTargets.cmake" |
| ) |
| |
| With this export call we now generate a Targets.cmake, allowing the configured |
| MathFunctionsConfig.cmake in the build directory to be used by other projects, |
| without needing it to be installed. |