Merge topic 'doc-relocatable-usage-requirements'
3af13782
Help: Update discussion of relocable packages in cmake-packages(7)227992c3
Help: Reorganize and refine discussion of relocatable packages031d894f
Help: Place relocatable package notes in their own subsections6e331ce9
Help: Fix typo in cmake-packages(7) manualba9b9d79
Help: Fix syntax in non-relocatable usage requirements example
This commit is contained in:
commit
b6b77bb750
|
@ -55,5 +55,8 @@ installation prefix. For example:
|
|||
$<INSTALL_INTERFACE:include/mylib> # <prefix>/include/mylib
|
||||
)
|
||||
|
||||
Creating Relocatable Packages
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. |INTERFACE_PROPERTY_LINK| replace:: :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`
|
||||
.. include:: /include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt
|
||||
|
|
|
@ -49,9 +49,6 @@ CMake will also propagate :ref:`usage requirements <Target Usage Requirements>`
|
|||
from linked library targets. Usage requirements of dependencies affect
|
||||
compilation of sources in the ``<target>``.
|
||||
|
||||
.. |INTERFACE_PROPERTY_LINK| replace:: :prop_tgt:`INTERFACE_LINK_LIBRARIES`
|
||||
.. include:: /include/INTERFACE_LINK_LIBRARIES_WARNING.txt
|
||||
|
||||
If an ``<item>`` is a library in a Mac OX framework, the ``Headers``
|
||||
directory of the framework will also be processed as a
|
||||
:ref:`usage requirement <Target Usage Requirements>`. This has the same
|
||||
|
@ -153,3 +150,9 @@ will not be used in OLD handling of :policy:`CMP0003` or :policy:`CMP0004`.
|
|||
See the :manual:`cmake-generator-expressions(7)` manual for available
|
||||
expressions. See the :manual:`cmake-buildsystem(7)` manual for more on
|
||||
defining buildsystem properties.
|
||||
|
||||
Creating Relocatable Packages
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. |INTERFACE_PROPERTY_LINK| replace:: :prop_tgt:`INTERFACE_LINK_LIBRARIES`
|
||||
.. include:: /include/INTERFACE_LINK_LIBRARIES_WARNING.txt
|
||||
|
|
|
@ -1,30 +1,18 @@
|
|||
|
||||
Note that it is not advisable to populate the ``INSTALL_INTERFACE`` of the
|
||||
|INTERFACE_PROPERTY_LINK| of a target with paths for dependencies.
|
||||
That would hard-code into installed packages the include directory paths
|
||||
for dependencies **as found on the machine the package was made on**.
|
||||
|INTERFACE_PROPERTY_LINK| of a target with absolute paths to the include
|
||||
directories of dependencies. That would hard-code into installed packages
|
||||
the include directory paths for dependencies
|
||||
**as found on the machine the package was made on**.
|
||||
|
||||
The ``INSTALL_INTERFACE`` of the |INTERFACE_PROPERTY_LINK| is only
|
||||
suitable for specifying the required include directories of the target itself,
|
||||
not its dependencies.
|
||||
suitable for specifying the required include directories for headers
|
||||
provided with the target itself, not those provided by the transitive
|
||||
dependencies listed in its :prop_tgt:`INTERFACE_LINK_LIBRARIES` target
|
||||
property. Those dependencies should themselves be targets that specify
|
||||
their own header locations in |INTERFACE_PROPERTY_LINK|.
|
||||
|
||||
That is, code like this is incorrect for targets which will be used to
|
||||
generate :manual:`cmake-packages(7)`:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
target_include_directories(mylib INTERFACE
|
||||
$<INSTALL_INTERFACE:${Boost_INCLUDE_DIRS};${OtherDep_INCLUDE_DIRS}>
|
||||
)
|
||||
|
||||
Dependencies must provide their own :ref:`IMPORTED targets <Imported Targets>`
|
||||
which have their own |INTERFACE_PROPERTY_LINK| populated
|
||||
appropriately. Those :ref:`IMPORTED targets <Imported Targets>` may then be
|
||||
used with the :command:`target_link_libraries` command for ``mylib``.
|
||||
|
||||
That way, when a consumer uses the installed package, the
|
||||
consumer will run the appropriate :command:`find_package` command to find
|
||||
the dependencies on their own machine and populate the
|
||||
:ref:`IMPORTED targets <Imported Targets>` with appropriate paths. See
|
||||
:ref:`Creating Packages` for more. Note that many modules currently shipped
|
||||
with CMake do not currently provide :ref:`IMPORTED targets <Imported Targets>`.
|
||||
See the :ref:`Creating Relocatable Packages` section of the
|
||||
:manual:`cmake-packages(7)` manual for discussion of additional care
|
||||
that must be taken when specifying usage requirements while creating
|
||||
packages for redistribution.
|
||||
|
|
|
@ -1,23 +1,10 @@
|
|||
|
||||
Note that it is not advisable to populate the
|
||||
|INTERFACE_PROPERTY_LINK| of a target with paths for dependencies.
|
||||
That would hard-code into installed packages the include directory paths
|
||||
|INTERFACE_PROPERTY_LINK| of a target with absolute paths to dependencies.
|
||||
That would hard-code into installed packages the library file 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 :manual:`cmake-packages(7)`:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
target_link_libraries(mylib INTERFACE
|
||||
${Boost_LIBRARIES};${OtherDep_LIBRARIES}
|
||||
)
|
||||
|
||||
Dependencies must provide their own :ref:`IMPORTED targets <Imported Targets>`
|
||||
which have their own :prop_tgt:`IMPORTED_LOCATION` populated
|
||||
appropriately. That way, when a consumer uses the installed package, the
|
||||
consumer will run the appropriate :command:`find_package` command to find
|
||||
the dependencies on their own machine and populate the
|
||||
:ref:`IMPORTED targets <Imported Targets>` with appropriate paths. See
|
||||
:ref:`Creating Packages` for more. Note that many modules currently shipped
|
||||
with CMake do not currently provide :ref:`IMPORTED targets <Imported Targets>`.
|
||||
See the :ref:`Creating Relocatable Packages` section of the
|
||||
:manual:`cmake-packages(7)` manual for discussion of additional care
|
||||
that must be taken when specifying usage requirements while creating
|
||||
packages for redistribution.
|
||||
|
|
|
@ -143,6 +143,11 @@ use particular :prop_tgt:`COMPILE_OPTIONS` or
|
|||
the properties must be **requirements**, not merely recommendations or
|
||||
convenience.
|
||||
|
||||
See the :ref:`Creating Relocatable Packages` section of the
|
||||
:manual:`cmake-packages(7)` manual for discussion of additional care
|
||||
that must be taken when specifying usage requirements while creating
|
||||
packages for redistribution.
|
||||
|
||||
Target Properties
|
||||
-----------------
|
||||
|
||||
|
|
|
@ -373,38 +373,6 @@ attempt to use version 3 together with version 4. Packages can choose to
|
|||
employ such a pattern if different major versions of the package are designed
|
||||
to be incompatible.
|
||||
|
||||
Note that 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 relevnt 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:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
target_link_libraries(ClimbingStats INTERFACE
|
||||
${Boost_LIBRARIES};${OtherDep_LIBRARIES}>
|
||||
)
|
||||
target_include_directories(ClimbingStats INTERFACE
|
||||
$<INSTALL_INTERFACE:${Boost_INCLUDE_DIRS};${OtherDep_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>`.
|
||||
|
||||
A ``NAMESPACE`` with double-colons is specified when exporting the targets
|
||||
for installation. This convention of double-colons gives CMake a hint that
|
||||
the name is an :prop_tgt:`IMPORTED` target when it is used by downstreams
|
||||
|
@ -418,6 +386,9 @@ directory in the :variable:`CMAKE_INSTALL_PREFIX`. When the ``IMPORTED``
|
|||
target is used by downsteam, it automatically consumes the entries from
|
||||
that property.
|
||||
|
||||
Creating a Package Configuration File
|
||||
-------------------------------------
|
||||
|
||||
In this case, the ``ClimbingStatsConfig.cmake`` file could be as simple as:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
@ -429,44 +400,6 @@ should be provided by the ``ClimbingStats`` package, they should
|
|||
be in a separate file which is installed to the same location as the
|
||||
``ClimbingStatsConfig.cmake`` file, and included from there.
|
||||
|
||||
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
|
||||
directories should be specified as relative paths which are relative to the
|
||||
:variable:`CMAKE_INSTALL_PREFIX`:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
target_include_directories(tgt INTERFACE
|
||||
# Wrong, not relocatable:
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include/TgtName>
|
||||
)
|
||||
|
||||
target_include_directories(tgt INTERFACE
|
||||
# Ok, relocatable:
|
||||
$<INSTALL_INTERFACE:include/TgtName>
|
||||
)
|
||||
|
||||
The ``$<INSTALL_PREFIX>``
|
||||
:manual:`generator expression <cmake-generator-expressions(7)>` may be used as
|
||||
a placeholder for the install prefix without resulting in a non-relocatable
|
||||
package. This is necessary if complex generator expressions are used:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
target_include_directories(tgt INTERFACE
|
||||
# Ok, relocatable:
|
||||
$<INSTALL_INTERFACE:$<$<CONFIG:Debug>:$<INSTALL_PREFIX>/include/TgtName>>
|
||||
)
|
||||
|
||||
The :command:`export(EXPORT)` command creates an :prop_tgt:`IMPORTED` targets
|
||||
definition file which is specific to the build-tree, and is not relocatable.
|
||||
This can similiarly be used with a suitable package configuration file and
|
||||
package version file to define a package for the build tree which may be used
|
||||
without installation. Consumers of the build tree can simply ensure that the
|
||||
:variable:`CMAKE_PREFIX_PATH` contains the build directory, or set the
|
||||
``ClimbingStats_DIR`` to ``<build_dir>/ClimbingStats`` in the cache.
|
||||
|
||||
This can also be extended to cover dependencies:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
@ -526,6 +459,111 @@ could not be found because an invalid component was specified. This message
|
|||
variable can be set for any case where the ``_FOUND`` variable is set to ``False``,
|
||||
and will be displayed to the user.
|
||||
|
||||
Creating a Package Configuration File for the Build Tree
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The :command:`export(EXPORT)` command creates an :prop_tgt:`IMPORTED` targets
|
||||
definition file which is specific to the build-tree, and is not relocatable.
|
||||
This can similiarly be used with a suitable package configuration file and
|
||||
package version file to define a package for the build tree which may be used
|
||||
without installation. Consumers of the build tree can simply ensure that the
|
||||
:variable:`CMAKE_PREFIX_PATH` contains the build directory, or set the
|
||||
``ClimbingStats_DIR`` to ``<build_dir>/ClimbingStats`` in the cache.
|
||||
|
||||
.. _`Creating Relocatable Packages`:
|
||||
|
||||
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
|
||||
directories should be specified as relative paths which are relative to the
|
||||
:variable:`CMAKE_INSTALL_PREFIX`:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
target_include_directories(tgt INTERFACE
|
||||
# Wrong, not relocatable:
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include/TgtName>
|
||||
)
|
||||
|
||||
target_include_directories(tgt INTERFACE
|
||||
# Ok, relocatable:
|
||||
$<INSTALL_INTERFACE:include/TgtName>
|
||||
)
|
||||
|
||||
The ``$<INSTALL_PREFIX>``
|
||||
:manual:`generator expression <cmake-generator-expressions(7)>` may be used as
|
||||
a placeholder for the install prefix without resulting in a non-relocatable
|
||||
package. This is necessary if complex generator expressions are used:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
target_include_directories(tgt INTERFACE
|
||||
# Ok, relocatable:
|
||||
$<INSTALL_INTERFACE:$<$<CONFIG:Debug>:$<INSTALL_PREFIX>/include/TgtName>>
|
||||
)
|
||||
|
||||
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.
|
||||
For example, this code may not work well for a relocatable package:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
target_link_libraries(ClimbingStats INTERFACE
|
||||
${Foo_LIBRARIES} ${Bar_LIBRARIES}
|
||||
)
|
||||
target_include_directories(ClimbingStats INTERFACE
|
||||
"$<INSTALL_INTERFACE:${Foo_INCLUDE_DIRS};${Bar_INCLUDE_DIRS}>"
|
||||
)
|
||||
|
||||
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`:
|
||||
|
||||
Package Registry
|
||||
|
|
|
@ -22,5 +22,8 @@ installation prefix. For example:
|
|||
$<INSTALL_INTERFACE:include/mylib> # <prefix>/include/mylib
|
||||
)
|
||||
|
||||
Creating Relocatable Packages
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. |INTERFACE_PROPERTY_LINK| replace:: ``INTERFACE_INCLUDE_DIRECTORIES``
|
||||
.. include:: /include/INTERFACE_INCLUDE_DIRECTORIES_WARNING.txt
|
||||
|
|
|
@ -17,5 +17,8 @@ with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
|
|||
manual for available expressions. See the :manual:`cmake-buildsystem(7)`
|
||||
manual for more on defining buildsystem properties.
|
||||
|
||||
Creating Relocatable Packages
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. |INTERFACE_PROPERTY_LINK| replace:: ``INTERFACE_LINK_LIBRARIES``
|
||||
.. include:: /include/INTERFACE_LINK_LIBRARIES_WARNING.txt
|
||||
|
|
|
@ -24,5 +24,8 @@ property if policy :policy:`CMP0022` is ``NEW``.
|
|||
This property is deprecated. Use :prop_tgt:`INTERFACE_LINK_LIBRARIES`
|
||||
instead.
|
||||
|
||||
Creating Relocatable Packages
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. |INTERFACE_PROPERTY_LINK| replace:: ``LINK_INTERFACE_LIBRARIES``
|
||||
.. include:: /include/INTERFACE_LINK_LIBRARIES_WARNING.txt
|
||||
|
|
|
@ -13,5 +13,8 @@ property if policy :policy:`CMP0022` is ``NEW``.
|
|||
This property is deprecated. Use :prop_tgt:`INTERFACE_LINK_LIBRARIES`
|
||||
instead.
|
||||
|
||||
Creating Relocatable Packages
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. |INTERFACE_PROPERTY_LINK| replace:: ``LINK_INTERFACE_LIBRARIES_<CONFIG>``
|
||||
.. include:: /include/INTERFACE_LINK_LIBRARIES_WARNING.txt
|
||||
|
|
Loading…
Reference in New Issue