3bd6d64642ba84f6a2b711e5768d984b21b58e85
[platform/upstream/cmake.git] / Help / guide / tutorial / Adding Export Configuration.rst
1 Step 11: Adding Export Configuration
2 ====================================
3
4 During :guide:`tutorial/Installing and Testing` of the tutorial we added the
5 ability for CMake to install the library and headers of the project. During
6 :guide:`tutorial/Packaging an Installer` we added the ability to package up
7 this information so it could be distributed to other people.
8
9 The next step is to add the necessary information so that other CMake projects
10 can use our project, be it from a build directory, a local install or when
11 packaged.
12
13 The first step is to update our :command:`install(TARGETS)` commands to not
14 only specify a ``DESTINATION`` but also an ``EXPORT``. The ``EXPORT`` keyword
15 generates a CMake file containing code to import all targets listed in the
16 install command from the installation tree. So let's go ahead and explicitly
17 ``EXPORT`` the ``MathFunctions`` library by updating the ``install`` command
18 in ``MathFunctions/CMakeLists.txt`` to look like:
19
20 .. literalinclude:: Complete/MathFunctions/CMakeLists.txt
21   :caption: MathFunctions/CMakeLists.txt
22   :name: MathFunctions/CMakeLists.txt-install-TARGETS-EXPORT
23   :language: cmake
24   :start-after: # install rules
25
26 Now that we have ``MathFunctions`` being exported, we also need to explicitly
27 install the generated ``MathFunctionsTargets.cmake`` file. This is done by
28 adding the following to the bottom of the top-level ``CMakeLists.txt``:
29
30 .. literalinclude:: Complete/CMakeLists.txt
31   :caption: CMakeLists.txt
32   :name: CMakeLists.txt-install-EXPORT
33   :language: cmake
34   :start-after: # install the configuration targets
35   :end-before: include(CMakePackageConfigHelpers)
36
37 At this point you should try and run CMake. If everything is setup properly
38 you will see that CMake will generate an error that looks like:
39
40 .. code-block:: console
41
42   Target "MathFunctions" INTERFACE_INCLUDE_DIRECTORIES property contains
43   path:
44
45     "/Users/robert/Documents/CMakeClass/Tutorial/Step11/MathFunctions"
46
47   which is prefixed in the source directory.
48
49 What CMake is trying to say is that during generating the export information
50 it will export a path that is intrinsically tied to the current machine and
51 will not be valid on other machines. The solution to this is to update the
52 ``MathFunctions`` :command:`target_include_directories` to understand that it
53 needs different ``INTERFACE`` locations when being used from within the build
54 directory and from an install / package. This means converting the
55 :command:`target_include_directories` call for ``MathFunctions`` to look like:
56
57 .. literalinclude:: Step12/MathFunctions/CMakeLists.txt
58   :caption: MathFunctions/CMakeLists.txt
59   :name: MathFunctions/CMakeLists.txt-target_include_directories
60   :language: cmake
61   :start-after: # to find MathFunctions.h, while we don't.
62   :end-before: # should we use our own math functions
63
64 Once this has been updated, we can re-run CMake and verify that it doesn't
65 warn anymore.
66
67 At this point, we have CMake properly packaging the target information that is
68 required but we will still need to generate a ``MathFunctionsConfig.cmake`` so
69 that the CMake :command:`find_package` command can find our project. So let's go
70 ahead and add a new file to the top-level of the project called
71 ``Config.cmake.in`` with the following contents:
72
73 .. literalinclude:: Step12/Config.cmake.in
74   :caption: Config.cmake.in
75   :name: Config.cmake.in
76
77 Then, to properly configure and install that file, add the following to the
78 bottom of the top-level ``CMakeLists.txt``:
79
80 .. literalinclude:: Step12/CMakeLists.txt
81   :caption: CMakeLists.txt
82   :name: CMakeLists.txt-install-Config.cmake
83   :language: cmake
84   :start-after: # install the configuration targets
85   :end-before: # generate the config file
86
87
88 Next, we execute the :command:`configure_package_config_file`.  This command
89 will configure a provided file but with a few specific differences from the
90 standard :command:`configure_file` way.
91 To properly utilize this function, the input file should have a single line
92 with the text ``@PACKAGE_INIT@`` in addition to the content that is desired.
93 That variable will be replaced with a block of code which turns set values into
94 relative paths.  These values which are new can be referenced by the same name
95 but prepended with a ``PACKAGE_`` prefix.
96
97 .. literalinclude:: Step12/CMakeLists.txt
98   :caption: CMakeLists.txt
99   :name: CMakeLists.txt-configure-package-config.cmake
100   :language: cmake
101   :start-after: # install the configuration targets
102   :end-before: # generate the version file
103
104 The :command:`write_basic_package_version_file` is next.  This command writes
105 a file which is used by the "find_package" document the version and
106 compatibility of the desired package.  Here, we use the ``Tutorial_VERSION_*``
107 variables and say that it is compatible with ``AnyNewerVersion``, which
108 denotes that this version or any higher one are compatible with the requested
109 version.
110
111 .. literalinclude:: Step12/CMakeLists.txt
112   :caption: CMakeLists.txt
113   :name: CMakeLists.txt-basic-version-file.cmake
114   :language: cmake
115   :start-after: # generate the version file
116   :end-before: # install the generated configuration files
117
118 Finally, set both generated files to be installed:
119
120 .. literalinclude:: Step12/CMakeLists.txt
121   :caption: CMakeLists.txt
122   :name: CMakeLists.txt-install-configured-files.cmake
123   :language: cmake
124   :start-after: # install the generated configuration files
125   :end-before: # generate the export
126
127 At this point, we have generated a relocatable CMake Configuration for our
128 project that can be used after the project has been installed or packaged. If
129 we want our project to also be used from a build directory we only have to add
130 the following to the bottom of the top level ``CMakeLists.txt``:
131
132 .. literalinclude:: Step12/CMakeLists.txt
133   :caption: CMakeLists.txt
134   :name: CMakeLists.txt-export
135   :language: cmake
136   :start-after: # needs to be after the install(TARGETS ) command
137
138 With this export call we now generate a ``Targets.cmake``, allowing the
139 configured ``MathFunctionsConfig.cmake`` in the build directory to be used by
140 other projects, without needing it to be installed.