summaryrefslogtreecommitdiffstats
path: root/Help/manual/cmake-generator-expressions.7.rst
diff options
context:
space:
mode:
authorCraig Scott <craig.scott@crascit.com>2022-06-27 10:36:58 (GMT)
committerCraig Scott <craig.scott@crascit.com>2022-07-03 04:34:41 (GMT)
commitd185f7c0a8cac19edaea8d54c2a12b51a622731b (patch)
tree96ab4b102d1d8a94536b0e09915d2911d3c505d5 /Help/manual/cmake-generator-expressions.7.rst
parent8c562ece28b7a13ddb734b8c51710ebafe9ac570 (diff)
downloadCMake-d185f7c0a8cac19edaea8d54c2a12b51a622731b.zip
CMake-d185f7c0a8cac19edaea8d54c2a12b51a622731b.tar.gz
CMake-d185f7c0a8cac19edaea8d54c2a12b51a622731b.tar.bz2
Help: Rework $<LINK_LIBRARY>, $<LINK_GROUP> and related docs
These changes restructure the docs to improve readability and flow, correct grammar and typos, and fix errors and inconsistencies in some of the examples. Fixes: #23684
Diffstat (limited to 'Help/manual/cmake-generator-expressions.7.rst')
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst288
1 files changed, 148 insertions, 140 deletions
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index c871b1b..0a54c1d 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -1370,229 +1370,237 @@ Output-Related Expressions
.. versionadded:: 3.24
- Manage how libraries are specified during the link step.
- This expression may be used to specify how to link libraries in a target.
- For example:
+ Specify a set of libraries to link to a target, along with a ``feature``
+ which provides details about *how* they should be linked. For example:
.. code-block:: cmake
add_library(lib1 STATIC ...)
add_library(lib2 ...)
- target_link_libraries(lib2 PRIVATE "$<LINK_LIBRARY:load_archive,lib1>")
-
- This specify to use the ``lib1`` target with feature ``load_archive`` for
- linking target ``lib2``. The feature must have be defined by
- :variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>` variable or, if
- :variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` is false,
- by :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` variable.
-
- .. note::
-
- The evaluation of this generator expression will use, for the following
- variables, the values defined at the level of the creation of the target:
-
- * :variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED`
- * :variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>`
- * :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED`
- * :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>`
-
- This expression can only be used to specify link libraries (i.e. part of
- :command:`link_libraries` or :command:`target_link_libraries` commands and
- :prop_tgt:`LINK_LIBRARIES` or :prop_tgt:`INTERFACE_LINK_LIBRARIES` target
- properties).
+ target_link_libraries(lib2 PRIVATE "$<LINK_LIBRARY:WHOLE_ARCHIVE,lib1>")
- .. note::
-
- If this expression appears in the :prop_tgt:`INTERFACE_LINK_LIBRARIES`
- property of a target, it will be included in the imported target generated
- by :command:`install(EXPORT)` command. It is the responsibility of the
- environment consuming this import to define the link feature used by this
- expression.
+ This specifies that ``lib2`` should link to ``lib1`` and use the
+ ``WHOLE_ARCHIVE`` feature when doing so.
- The ``library-list`` argument can hold CMake targets or external libraries.
- Any CMake target of type :ref:`OBJECT <Object Libraries>` or
- :ref:`INTERFACE <Interface Libraries>` will be ignored by this expression and
- will be handled in the standard way.
+ Feature names are case-sensitive and may only contain letters, numbers and
+ underscores. Feature names defined in all uppercase are reserved for CMake's
+ own built-in features. The pre-defined built-in library features are:
- Each target or external library involved in the link step must have only one
- kind of feature (the absence of feature is also incompatible with any
- feature). For example:
-
- .. code-block:: cmake
-
- add_library(lib1 ...)
+ .. include:: ../variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt
- add_library(lib2 ...)
- target_link_libraries(lib2 PUBLIC "$<LINK_LIBRARY:feature1,lib1>")
+ Built-in and custom library features are defined in terms of the following
+ variables:
+
+ * :variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED`
+ * :variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>`
+ * :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED`
+ * :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>`
+
+ The value used for each of these variables is the value as set at the end of
+ the directory scope in which the target was created. The usage is as follows:
+
+ 1. If the language-specific
+ :variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` variable
+ is true, the ``feature`` must be defined by the corresponding
+ :variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>` variable.
+ 2. If no language-specific ``feature`` is supported, then the
+ :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` variable must be
+ true and the ``feature`` must be defined by the corresponding
+ :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` variable.
+
+ The following limitations should be noted:
+
+ * The ``library-list`` can specify CMake targets or libraries.
+ Any CMake target of type :ref:`OBJECT <Object Libraries>`
+ or :ref:`INTERFACE <Interface Libraries>` will ignore the feature aspect
+ of the expression and instead be linked in the standard way.
+
+ * The ``$<LINK_LIBRARY:...>`` generator expression can only be used to
+ specify link libraries. In practice, this means it can appear in the
+ :prop_tgt:`LINK_LIBRARIES` and :prop_tgt:`INTERFACE_LINK_LIBRARIES`
+ target properties, and be specified in :command:`target_link_libraries`
+ and :command:`link_libraries` commands.
+
+ * If a ``$<LINK_LIBRARY:...>`` generator expression appears in the
+ :prop_tgt:`INTERFACE_LINK_LIBRARIES` property of a target, it will be
+ included in the imported target generated by a :command:`install(EXPORT)`
+ command. It is the responsibility of the environment consuming this
+ import to define the link feature used by this expression.
+
+ * Each target or library involved in the link step must have at most only
+ one kind of library feature. The absence of a feature is also incompatible
+ with all other features. For example:
- add_library(lib3 ...)
- target_link_libraries(lib3 PRIVATE lib1 lib2)
- # an error will be raised here because lib1 has two different features
+ .. code-block:: cmake
- To resolve such incompatibilities, the :prop_tgt:`LINK_LIBRARY_OVERRIDE`
- and :prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` target properties can be
- used.
+ add_library(lib1 ...)
+ add_library(lib2 ...)
+ add_library(lib3 ...)
- .. note::
+ # lib1 will be associated with feature1
+ target_link_libraries(lib2 PUBLIC "$<LINK_LIBRARY:feature1,lib1>")
- This expression does not guarantee that the list of specified libraries
- will be kept grouped. So, to manage constructs like ``start-group`` and
- ``end-group``, as supported by ``GNU ld``, the :genex:`LINK_GROUP`
- generator expression can be used.
+ # lib1 is being linked with no feature here. This conflicts with the
+ # use of feature1 in the line above and would result in an error.
+ target_link_libraries(lib3 PRIVATE lib1 lib2)
- CMake pre-defines some features of general interest:
+ Where it isn't possible to use the same feature throughout a build for a
+ given target or library, the :prop_tgt:`LINK_LIBRARY_OVERRIDE` and
+ :prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` target properties can be
+ used to resolve such incompatibilities.
- .. include:: ../variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt
+ * The ``$<LINK_LIBRARY:...>`` generator expression does not guarantee
+ that the list of specified targets and libraries will be kept grouped
+ together. To manage constructs like ``--start-group`` and ``--end-group``,
+ as supported by the GNU ``ld`` linker, use the :genex:`LINK_GROUP`
+ generator expression instead.
.. genex:: $<LINK_GROUP:feature,library-list>
.. versionadded:: 3.24
- Manage the grouping of libraries during the link step.
- This expression may be used to specify how to keep groups of libraries during
- the link of a target.
- For example:
+ Specify a group of libraries to link to a target, along with a ``feature``
+ which defines how that group should be linked. For example:
.. code-block:: cmake
add_library(lib1 STATIC ...)
add_library(lib2 ...)
- target_link_libraries(lib2 PRIVATE "$<LINK_GROUP:cross_refs,lib1,external>")
-
- This specify to use the ``lib1`` target and ``external`` library with the
- group feature ``cross_refs`` for linking target ``lib2``. The feature must
- have be defined by :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>`
- variable or, if :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED`
- is false, by :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>` variable.
+ target_link_libraries(lib2 PRIVATE "$<LINK_GROUP:RESCAN,lib1,external>")
- .. note::
+ This specifies that ``lib2`` should link to ``lib1`` and ``external``, and
+ that both of those two libraries should be included on the linker command
+ line according to the definition of the ``RESCAN`` feature.
- The evaluation of this generator expression will use, for the following
- variables, the values defined at the level of the creation of the target:
+ Feature names are case-sensitive and may only contain letters, numbers and
+ underscores. Feature names defined in all uppercase are reserved for CMake's
+ own built-in features. Currently, there is only one pre-defined built-in
+ group feature:
- * :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED`
- * :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>`
- * :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED`
- * :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>`
+ .. include:: ../variable/LINK_GROUP_PREDEFINED_FEATURES.txt
- This expression can only be used to specify link libraries (i.e. part of
- :command:`link_libraries` or :command:`target_link_libraries` commands and
- :prop_tgt:`LINK_LIBRARIES` or :prop_tgt:`INTERFACE_LINK_LIBRARIES` target
- properties).
+ Built-in and custom group features are defined in terms of the following
+ variables:
- .. note::
+ * :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED`
+ * :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>`
+ * :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED`
+ * :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>`
- If this expression appears in the :prop_tgt:`INTERFACE_LINK_LIBRARIES`
- property of a target, it will be included in the imported target generated
- by :command:`install(EXPORT)` command. It is the responsibility of the
- environment consuming this import to define the link feature used by this
- expression.
+ The value used for each of these variables is the value as set at the end of
+ the directory scope in which the target was created. The usage is as follows:
- The ``library-list`` argument can hold CMake targets or external libraries.
- Any CMake target of type :ref:`OBJECT <Object Libraries>` or
- :ref:`INTERFACE <Interface Libraries>` will be ignored by this expression and
- will be handled in the standard way.
+ 1. If the language-specific
+ :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` variable
+ is true, the ``feature`` must be defined by the corresponding
+ :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>` variable.
+ 2. If no language-specific ``feature`` is supported, then the
+ :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED` variable must be
+ true and the ``feature`` must be defined by the corresponding
+ :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>` variable.
- .. note::
+ The ``LINK_GROUP`` generator expression is compatible with the
+ :genex:`LINK_LIBRARY` generator expression. The libraries involved in a
+ group can be specified using the :genex:`LINK_LIBRARY` generator expression.
- This expression is compatible with the :genex:`LINK_LIBRARY` generator
- expression. The libraries involved in a group can be specified using the
- :genex:`LINK_LIBRARY` generator expression.
-
- Each target or external library involved in the link step can be part of
- different groups as far as these groups use the same feature, so mixing
- different group features for the same target or library is forbidden. The
- different groups will be part of the link step.
+ Each target or external library involved in the link step is allowed to be
+ part of multiple groups, but only if all the groups involved specify the
+ same ``feature``. Such groups will not be merged on the linker command line,
+ the individual groups will still be preserved. Mixing different group
+ features for the same target or library is forbidden.
.. code-block:: cmake
add_library(lib1 ...)
add_library(lib2 ...)
-
add_library(lib3 ...)
- target_link_libraries(lib3 PUBLIC "$<LINK_GROUP:feature1,lib1,lib2>")
-
add_library(lib4 ...)
+ add_library(lib5 ...)
+
+ target_link_libraries(lib3 PUBLIC "$<LINK_GROUP:feature1,lib1,lib2>")
target_link_libraries(lib4 PRIVATE "$<LINK_GROUP:feature1,lib1,lib3>")
- # lib4 will be linked with the groups {lib1,lib2} and {lib1,lib3}
+ # lib4 will be linked with the groups {lib1,lib2} and {lib1,lib3}.
+ # Both groups specify the same feature, so this is fine.
- add_library(lib5 ...)
target_link_libraries(lib5 PRIVATE "$<LINK_GROUP:feature2,lib1,lib3>")
- # an error will be raised here because lib1 is part of two groups with
- # different features
+ # An error will be raised here because both lib1 and lib3 are part of two
+ # groups with different features.
When a target or an external library is involved in the link step as part of
- a group and also as standalone, any occurrence of the standalone link item
- will be replaced by the group or groups it belong to.
+ a group and also as not part of any group, any occurrence of the non-group
+ link item will be replaced by the groups it belongs to.
.. code-block:: cmake
add_library(lib1 ...)
add_library(lib2 ...)
-
add_library(lib3 ...)
+ add_library(lib4 ...)
+
target_link_libraries(lib3 PUBLIC lib1)
- add_library(lib4 ...)
target_link_libraries(lib4 PRIVATE lib3 "$<LINK_GROUP:feature1,lib1,lib2>")
# lib4 will only be linked with lib3 and the group {lib1,lib2}
- This example will be "re-written" by CMake in the following form:
+ Because ``lib1`` is part of the group defined for ``lib4``, that group then
+ gets applied back to the use of ``lib1`` for ``lib3``. The end result will
+ be as though the linking relationship for ``lib3`` had been specified as:
.. code-block:: cmake
- add_library(lib1 ...)
- add_library(lib2 ...)
-
- add_library(lib3 ...)
target_link_libraries(lib3 PUBLIC "$<LINK_GROUP:feature1,lib1,lib2>")
- add_library(lib4 ...)
- target_link_libraries(lib4 PRIVATE lib3 "$<LINK_GROUP:feature1,lib1,lib2>")
- # lib4 will only be linked with lib3 and the group {lib1,lib2}
-
- Be aware that the precedence of the group over the standalone link item can
- result in some circular dependency between groups, which will raise an
- error because circular dependencies are not allowed for groups.
+ Be aware that the precedence of the group over the non-group link item can
+ result in circular dependencies between groups. If this occurs, a fatal
+ error is raised because circular dependencies are not allowed for groups.
.. code-block:: cmake
add_library(lib1A ...)
add_library(lib1B ...)
-
add_library(lib2A ...)
add_library(lib2B ...)
+ add_library(lib3 ...)
+ # Non-group linking relationships, these are non-circular so far
target_link_libraries(lib1A PUBLIC lib2A)
target_link_libraries(lib2B PUBLIC lib1B)
- add_library(lib ...)
- target_link_libraries(lib3 PRIVATE "$<LINK_GROUP:feat,lib1A,lib1B>"
- "$<LINK_GROUP:feat,lib2A,lib2B>")
+ # The addition of these groups creates circular dependencies
+ target_link_libraries(lib3 PRIVATE
+ "$<LINK_GROUP:feat,lib1A,lib1B>"
+ "$<LINK_GROUP:feat,lib2A,lib2B>"
+ )
- This example will be "re-written" by CMake in the following form:
+ Because of the groups defined for ``lib3``, the linking relationships for
+ ``lib1A`` and ``lib2B`` effectively get expanded to the equivalent of:
.. code-block:: cmake
- add_library(lib1A ...)
- add_library(lib1B ...)
-
- add_library(lib2A ...)
- add_library(lib2B ...)
-
target_link_libraries(lib1A PUBLIC "$<LINK_GROUP:feat,lib2A,lib2B>")
target_link_libraries(lib2B PUBLIC "$<LINK_GROUP:feat,lib1A,lib1B>")
- add_library(lib ...)
- target_link_libraries(lib3 PRIVATE "$<LINK_GROUP:feat,lib1A,lib1B>"
- "$<LINK_GROUP:feat,lib2A,lib2B>")
+ This creates a circular dependency between groups:
+ ``lib1A --> lib2B --> lib1A``.
- So, we have a circular dependency between groups ``{lib1A,lib1B}`` and
- ``{lib2A,lib2B}``.
+ The following limitations should also be noted:
- CMake pre-defines some features of general interest:
+ * The ``library-list`` can specify CMake targets or libraries.
+ Any CMake target of type :ref:`OBJECT <Object Libraries>`
+ or :ref:`INTERFACE <Interface Libraries>` will ignore the feature aspect
+ of the expression and instead be linked in the standard way.
- .. include:: ../variable/LINK_GROUP_PREDEFINED_FEATURES.txt
+ * The ``$<LINK_GROUP:...>`` generator expression can only be used to
+ specify link libraries. In practice, this means it can appear in the
+ :prop_tgt:`LINK_LIBRARIES` and :prop_tgt:`INTERFACE_LINK_LIBRARIES`
+ target properties, and be specified in :command:`target_link_libraries`
+ and :command:`link_libraries` commands.
+
+ * If a ``$<LINK_GROUP:...>`` generator expression appears in the
+ :prop_tgt:`INTERFACE_LINK_LIBRARIES` property of a target, it will be
+ included in the imported target generated by a :command:`install(EXPORT)`
+ command. It is the responsibility of the environment consuming this
+ import to define the link feature used by this expression.
.. genex:: $<INSTALL_INTERFACE:...>