| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 | Step 11: Adding Export Configuration====================================During :guide:`tutorial/Installing and Testing` of the tutorial we added theability for CMake to install the library and headers of the project. During:guide:`tutorial/Packaging an Installer` we added the ability to package upthis information so it could be distributed to other people.The next step is to add the necessary information so that other CMake projectscan use our project, be it from a build directory, a local install or whenpackaged.The first step is to update our :command:`install(TARGETS)` commands to notonly specify a ``DESTINATION`` but also an ``EXPORT``. The ``EXPORT`` keywordgenerates a CMake file containing code to import all targets listed in theinstall command from the installation tree. So let's go ahead and explicitly``EXPORT`` the ``MathFunctions`` library by updating the ``install`` commandin ``MathFunctions/CMakeLists.txt`` to look like:.. literalinclude:: Complete/MathFunctions/CMakeLists.txt  :caption: MathFunctions/CMakeLists.txt  :name: MathFunctions/CMakeLists.txt-install-TARGETS-EXPORT  :language: cmake  :start-after: # install rulesNow that we have ``MathFunctions`` being exported, we also need to explicitlyinstall the generated ``MathFunctionsTargets.cmake`` file. This is done byadding the following to the bottom of the top-level ``CMakeLists.txt``:.. literalinclude:: Complete/CMakeLists.txt  :caption: CMakeLists.txt  :name: CMakeLists.txt-install-EXPORT  :language: cmake  :start-after: # install the configuration targets  :end-before: include(CMakePackageConfigHelpers)At this point you should try and run CMake. If everything is setup properlyyou will see that CMake will generate an error that looks like:.. code-block:: console  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 informationit will export a path that is intrinsically tied to the current machine andwill not be valid on other machines. The solution to this is to update the``MathFunctions`` :command:`target_include_directories` to understand that itneeds different ``INTERFACE`` locations when being used from within the builddirectory and from an install / package. This means converting the:command:`target_include_directories` call for ``MathFunctions`` to look like:.. literalinclude:: Step12/MathFunctions/CMakeLists.txt  :caption: MathFunctions/CMakeLists.txt  :name: MathFunctions/CMakeLists.txt-target_include_directories  :language: cmake  :start-after: # to find MathFunctions.h, while we don't.  :end-before: # should we use our own math functionsOnce this has been updated, we can re-run CMake and verify that it doesn'twarn anymore.At this point, we have CMake properly packaging the target information that isrequired but we will still need to generate a ``MathFunctionsConfig.cmake`` sothat the CMake :command:`find_package` command can find our project. So let's goahead and add a new file to the top-level of the project called``Config.cmake.in`` with the following contents:.. literalinclude:: Step12/Config.cmake.in  :caption: Config.cmake.in  :name: Config.cmake.inThen, to properly configure and install that file, add the following to thebottom of the top-level ``CMakeLists.txt``:.. literalinclude:: Step12/CMakeLists.txt  :caption: CMakeLists.txt  :name: CMakeLists.txt-install-Config.cmake  :language: cmake  :start-after: # install the configuration targets  :end-before: # generate the config fileNext, we execute the :command:`configure_package_config_file`.  This commandwill configure a provided file but with a few specific differences from thestandard :command:`configure_file` way.To properly utilize this function, the input file should have a single linewith the text ``@PACKAGE_INIT@`` in addition to the content that is desired.That variable will be replaced with a block of code which turns set values intorelative paths.  These values which are new can be referenced by the same namebut prepended with a ``PACKAGE_`` prefix... literalinclude:: Step12/CMakeLists.txt  :caption: CMakeLists.txt  :name: CMakeLists.txt-configure-package-config.cmake  :language: cmake  :start-after: # install the configuration targets  :end-before: # generate the version fileThe :command:`write_basic_package_version_file` is next.  This command writesa file which is used by the "find_package" document the version andcompatibility of the desired package.  Here, we use the ``Tutorial_VERSION_*``variables and say that it is compatible with ``AnyNewerVersion``, whichdenotes that this version or any higher one are compatible with the requestedversion... literalinclude:: Step12/CMakeLists.txt  :caption: CMakeLists.txt  :name: CMakeLists.txt-basic-version-file.cmake  :language: cmake  :start-after: # generate the version file  :end-before: # install the generated configuration filesFinally, set both generated files to be installed:.. literalinclude:: Step12/CMakeLists.txt  :caption: CMakeLists.txt  :name: CMakeLists.txt-install-configured-files.cmake  :language: cmake  :start-after: # install the generated configuration files  :end-before: # generate the exportAt this point, we have generated a relocatable CMake Configuration for ourproject that can be used after the project has been installed or packaged. Ifwe want our project to also be used from a build directory we only have to addthe following to the bottom of the top level ``CMakeLists.txt``:.. literalinclude:: Step12/CMakeLists.txt  :caption: CMakeLists.txt  :name: CMakeLists.txt-export  :language: cmake  :start-after: # needs to be after the install(TARGETS ) commandWith this export call we now generate a ``Targets.cmake``, allowing theconfigured ``MathFunctionsConfig.cmake`` in the build directory to be used byother projects, without needing it to be installed.
 |