diff options
Diffstat (limited to 'Help/manual/cmake-generator-expressions.7.rst')
-rw-r--r-- | Help/manual/cmake-generator-expressions.7.rst | 288 |
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:...> |