Jelajahi Sumber

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 packages
031d894f Help: Place relocatable package notes in their own subsections
6e331ce9 Help: Fix typo in cmake-packages(7) manual
ba9b9d79 Help: Fix syntax in non-relocatable usage requirements example
Brad King 10 tahun lalu
induk
melakukan
b6b77bb750

+ 3 - 0
Help/command/target_include_directories.rst

@@ -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

+ 6 - 3
Help/command/target_link_libraries.rst

@@ -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

+ 13 - 25
Help/include/INTERFACE_INCLUDE_DIRECTORIES_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.

+ 6 - 19
Help/include/INTERFACE_LINK_LIBRARIES_WARNING.txt

@@ -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.

+ 5 - 0
Help/manual/cmake-buildsystem.7.rst

@@ -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
 -----------------
 

+ 108 - 70
Help/manual/cmake-packages.7.rst

@@ -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

+ 3 - 0
Help/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES.rst

@@ -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

+ 3 - 0
Help/prop_tgt/INTERFACE_LINK_LIBRARIES.rst

@@ -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

+ 3 - 0
Help/prop_tgt/LINK_INTERFACE_LIBRARIES.rst

@@ -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

+ 3 - 0
Help/prop_tgt/LINK_INTERFACE_LIBRARIES_CONFIG.rst

@@ -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