summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/manual/cmake-packages.7.rst66
1 files changed, 46 insertions, 20 deletions
diff --git a/Help/manual/cmake-packages.7.rst b/Help/manual/cmake-packages.7.rst
index 28c0798..b9073a5 100644
--- a/Help/manual/cmake-packages.7.rst
+++ b/Help/manual/cmake-packages.7.rst
@@ -475,6 +475,10 @@ without installation. Consumers of the build tree can simply ensure that the
Creating Relocatable Packages
-----------------------------
+A relocatable package must not reference absolute paths of files on
+the machine where the package is built that will not exist on the
+machines where the package may be installed.
+
Packages created by :command:`install(EXPORT)` are designed to be relocatable,
using paths relative to the location of the package itself. When defining
the interface of a target for ``EXPORT``, keep in mind that the include
@@ -509,34 +513,56 @@ This also applies to paths referencing external dependencies.
It is not advisable to populate any properties which may contain
paths, such as :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` and
:prop_tgt:`INTERFACE_LINK_LIBRARIES`, with paths relevant to dependencies.
-That would hard-code into installed packages the include directory or library
-paths for dependencies **as found on the machine the package was made on**.
-
-That is, code like this is incorrect for targets which will be used to
-generate config file packages:
+For example, this code may not work well for a relocatable package:
.. code-block:: cmake
target_link_libraries(ClimbingStats INTERFACE
- ${Boost_LIBRARIES} ${OtherDep_LIBRARIES}
+ ${Foo_LIBRARIES} ${Bar_LIBRARIES}
)
target_include_directories(ClimbingStats INTERFACE
- "$<INSTALL_INTERFACE:${Boost_INCLUDE_DIRS};${OtherDep_INCLUDE_DIRS}>"
+ "$<INSTALL_INTERFACE:${Foo_INCLUDE_DIRS};${Bar_INCLUDE_DIRS}>"
)
-Dependencies must provide their own :ref:`IMPORTED targets <Imported Targets>`
-which have their own :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` and
-:prop_tgt:`IMPORTED_LOCATION` populated appropriately. Those
-:ref:`IMPORTED targets <Imported Targets>` may then be
-used with the :command:`target_link_libraries` command for ``ClimbingStats``.
-
-That way, when a consumer uses the installed package, the
-consumer will run the appropriate :command:`find_package` command (via the
-find_dependency macro described below) to find
-the dependencies on their own machine and populate the
-:ref:`IMPORTED targets <Imported Targets>` with appropriate paths. Note that
-many modules currently shipped with CMake do not currently provide
-:ref:`IMPORTED targets <Imported Targets>`.
+The referenced variables may contain the absolute paths to libraries
+and include directories **as found on the machine the package was made on**.
+This would create a package with hard-coded paths to dependencies and not
+suitable for relocation.
+
+Ideally such dependencies should be used through their own
+:ref:`IMPORTED targets <Imported Targets>` that have their own
+:prop_tgt:`IMPORTED_LOCATION` and usage requirement properties
+such as :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` populated
+appropriately. Those imported targets may then be used with
+the :command:`target_link_libraries` command for ``ClimbingStats``:
+
+.. code-block:: cmake
+
+ target_link_libraries(ClimbingStats INTERFACE Foo::Foo Bar::Bar)
+
+With this approach the package references its external dependencies
+only through the names of :ref:`IMPORTED targets <Imported Targets>`.
+When a consumer uses the installed package, the consumer will run the
+appropriate :command:`find_package` commands (via the ``find_dependency``
+macro described above) to find the dependencies and populate the
+imported targets with appropriate paths on their own machine.
+
+Unfortunately many :manual:`modules <cmake-modules(7)>` shipped with
+CMake do not yet provide :ref:`IMPORTED targets <Imported Targets>`
+because their development pre-dated this approach. This may improve
+incrementally over time. Workarounds to create relocatable packages
+using such modules include:
+
+* When building the package, specify each ``Foo_LIBRARY`` cache
+ entry as just a library name, e.g. ``-DFoo_LIBRARY=foo``. This
+ tells the corresponding find module to populate the ``Foo_LIBRARIES``
+ with just ``foo`` to ask the linker to search for the library
+ instead of hard-coding a path.
+
+* Or, after installing the package content but before creating the
+ package installation binary for redistribution, manually replace
+ the absolute paths with placeholders for substitution by the
+ installation tool when the package is installed.
.. _`Package Registry`: