diff options
author | Craig Scott <craig.scott@crascit.com> | 2022-07-03 04:50:33 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2022-07-03 04:50:44 (GMT) |
commit | 2a336d855443d7db601bd79e80fce86726962cd2 (patch) | |
tree | 51a21089ba1810b9ad1f1d91570997fb942301ec | |
parent | 32014390465669fe4ead629a79447c9996c7dee5 (diff) | |
parent | d185f7c0a8cac19edaea8d54c2a12b51a622731b (diff) | |
download | CMake-2a336d855443d7db601bd79e80fce86726962cd2.zip CMake-2a336d855443d7db601bd79e80fce86726962cd2.tar.gz CMake-2a336d855443d7db601bd79e80fce86726962cd2.tar.bz2 |
Merge topic 'doc-LINK_LIBRARY_genex' into release-3.24
d185f7c0a8 Help: Rework $<LINK_LIBRARY>, $<LINK_GROUP> and related docs
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !7413
-rw-r--r-- | Help/manual/cmake-generator-expressions.7.rst | 288 | ||||
-rw-r--r-- | Help/prop_tgt/LINK_LIBRARY_OVERRIDE.rst | 69 | ||||
-rw-r--r-- | Help/prop_tgt/LINK_LIBRARY_OVERRIDE_LIBRARY.rst | 50 | ||||
-rw-r--r-- | Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE.rst | 27 | ||||
-rw-r--r-- | Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE_SUPPORTED.rst | 17 | ||||
-rw-r--r-- | Help/variable/CMAKE_LANG_LINK_LIBRARY_USING_FEATURE.rst | 27 | ||||
-rw-r--r-- | Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.rst | 35 | ||||
-rw-r--r-- | Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.txt | 66 | ||||
-rw-r--r-- | Help/variable/CMAKE_LINK_GROUP_USING_FEATURE_SUPPORTED.rst | 13 | ||||
-rw-r--r-- | Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.rst | 34 | ||||
-rw-r--r-- | Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.txt | 140 | ||||
-rw-r--r-- | Help/variable/LINK_GROUP_PREDEFINED_FEATURES.txt | 32 | ||||
-rw-r--r-- | Help/variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt | 158 |
13 files changed, 502 insertions, 454 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:...> diff --git a/Help/prop_tgt/LINK_LIBRARY_OVERRIDE.rst b/Help/prop_tgt/LINK_LIBRARY_OVERRIDE.rst index 81a2a4a..916a7c6 100644 --- a/Help/prop_tgt/LINK_LIBRARY_OVERRIDE.rst +++ b/Help/prop_tgt/LINK_LIBRARY_OVERRIDE.rst @@ -3,52 +3,63 @@ LINK_LIBRARY_OVERRIDE .. versionadded:: 3.24 -To resolve incompatible features introduced by :genex:`LINK_LIBRARY` generator -expression, this property offers the possibility to override, per ``link-item`` -(``CMake`` target or external library) involved in the link step, any defined -features with a new one. +Override the library features associated with libraries from +:genex:`LINK_LIBRARY` generator expressions. This can be used to resolve +incompatible library features that result from specifying different features +for the same library in different :genex:`LINK_LIBRARY` generator expressions. -This property takes a :ref:`;-list <CMake Language Lists>` of override -declarations which have the following format: - -:: +This property supports overriding multiple libraries and features. It expects +a :ref:`semicolon-separated list <CMake Language Lists>`, where each list item +has the following form:: feature[,link-item]* -For the list of ``link-item`` (``CMake`` target or external library) specified, -the feature ``feature`` will be used in place of any declared feature. For -example: +For each comma-separated ``link-item``, any existing library feature associated +with it will be ignored for the target this property is set on. The item +will instead be associated with the specified ``feature``. Each ``link-item`` +can be anything that would be accepted as part of a ``library-list`` in a +:genex:`LINK_LIBRARY` generator expression. .. code-block:: cmake add_library(lib1 ...) - target_link_libraries(lib1 PUBLIC "$<LINK_LIBRARY:feature1,external>") - add_library(lib2 ...) - target_link_libraries(lib2 PUBLIC "$<LINK_LIBRARY:feature2,lib1>") - add_library(lib3 ...) + + target_link_libraries(lib1 PUBLIC "$<LINK_LIBRARY:feature1,external>") + target_link_libraries(lib2 PUBLIC "$<LINK_LIBRARY:feature2,lib1>") target_link_libraries(lib3 PRIVATE lib1 lib2) - # Here, lib1 has two different features which prevents to link lib3 - # So, define LINK_LIBRARY_OVERRIDE property to ensure correct link + + # lib1 is associated with both feature2 and no feature. Without any override, + # this would result in a fatal error at generation time for lib3. + # Define an override to resolve the incompatible feature associations. set_property(TARGET lib3 PROPERTY LINK_LIBRARY_OVERRIDE "feature2,lib1,external") - # The lib1 and external will be used with FEATURE2 to link lib3 -It is also possible to override any feature with the pre-defined feature -``DEFAULT`` to get the standard behavior (i.e. no feature): + # lib1 and external will now be associated with feature2 instead when linking lib3 + +It is also possible to override any feature with the pre-defined ``DEFAULT`` +library feature. This effectively discards any feature for that link item, +for that target only (``lib3`` in this example): .. code-block:: cmake - set_property(TARGET lib3 PROPERTY LINK_LIBRARY_OVERRIDE "DEFAULT,lib1" - "feature2,external") - # The lib1 will be used without any feature and external will use feature2 to link lib3 + # When linking lib3, discard any library feature for lib1, and use feature2 for external + set_property(TARGET lib3 PROPERTY LINK_LIBRARY_OVERRIDE + "DEFAULT,lib1" + "feature2,external" + ) + +The above example also demonstrates how to specify different feature overrides +for different link items. See the :prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` +target property for an alternative way of overriding library features for +individual libraries, which may be simpler in some cases. If both properties +are defined and specify an override for the same link item, +:prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` takes precedence over +``LINK_LIBRARY_OVERRIDE``. Contents of ``LINK_LIBRARY_OVERRIDE`` may use :manual:`generator expressions <cmake-generator-expressions(7)>`. -See also :prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` target property for -a per linked target oriented approach to override features. - -For more information about features, see -:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>` -and :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` variables. +For more information about library features, see the +:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>` and +:variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` variables. diff --git a/Help/prop_tgt/LINK_LIBRARY_OVERRIDE_LIBRARY.rst b/Help/prop_tgt/LINK_LIBRARY_OVERRIDE_LIBRARY.rst index 112f614..4d3dd4f 100644 --- a/Help/prop_tgt/LINK_LIBRARY_OVERRIDE_LIBRARY.rst +++ b/Help/prop_tgt/LINK_LIBRARY_OVERRIDE_LIBRARY.rst @@ -3,43 +3,49 @@ LINK_LIBRARY_OVERRIDE_<LIBRARY> .. versionadded:: 3.24 -To resolve incompatible features introduced by :genex:`LINK_LIBRARY` generator -expression, this property offers the possibility to override, for a -``link-item`` (``CMake`` target or external library) involved in the link step, -any defined features with a new one. +Override the library feature associated with ``<LIBRARY>`` from +:genex:`LINK_LIBRARY` generator expressions. This can be used to resolve +incompatible library features that result from specifying different features +for ``<LIBRARY>`` in different :genex:`LINK_LIBRARY` generator expressions. -This property takes a ``feature`` name which will be applied to the -``link-item`` specified by ``<LIBRARY>`` suffix property. For example: +When set on a target, this property holds a single library feature name, which +will be applied to ``<LIBRARY>`` when linking that target. .. code-block:: cmake add_library(lib1 ...) - target_link_libraries(lib1 PUBLIC "$<LINK_LIBRARY:feature1,external>") - add_library(lib2 ...) - target_link_libraries(lib2 PUBLIC "$<LINK_LIBRARY:feature2,lib1>") - add_library(lib3 ...) + + target_link_libraries(lib1 PUBLIC "$<LINK_LIBRARY:feature1,external>") + target_link_libraries(lib2 PUBLIC "$<LINK_LIBRARY:feature2,lib1>") target_link_libraries(lib3 PRIVATE lib1 lib2) - # Here, lib1 has two different features which prevents to link lib3 - # So, define LINK_LIBRARY_OVERRIDE_lib1 property to ensure correct link + + # lib1 is associated with both feature2 and no feature. Without any override, + # this would result in a fatal error at generation time for lib3. + # Define an override to resolve the incompatible feature associations. set_property(TARGET lib3 PROPERTY LINK_LIBRARY_OVERRIDE_lib1 feature2) - # The lib1 will be used with feature2 to link lib3 -It is also possible to override any feature with the pre-defined feature -``DEFAULT`` to get the standard behavior (i.e. no feature): + # lib1 will now be associated with feature2 instead when linking lib3 + +It is also possible to override any feature with the pre-defined ``DEFAULT`` +library feature. This effectively discards any feature for that link item, +for that target only (``lib3`` in this example): .. code-block:: cmake + # When linking lib3, discard any library feature for lib1 set_property(TARGET lib3 PROPERTY LINK_LIBRARY_OVERRIDE_lib1 DEFAULT) - # The lib1 will be used without any feature to link lib3 + +See the :prop_tgt:`LINK_LIBRARY_OVERRIDE` target property for an alternative +way of overriding library features for multiple libraries at once. If both +properties are defined and specify an override for the same link item, +``LINK_LIBRARY_OVERRIDE_<LIBRARY>`` takes precedence over +:prop_tgt:`LINK_LIBRARY_OVERRIDE`. Contents of ``LINK_LIBRARY_OVERRIDE_<LIBRARY>`` may use :manual:`generator expressions <cmake-generator-expressions(7)>`. -This property takes precedence over :prop_tgt:`LINK_LIBRARY_OVERRIDE` -target property. - -For more information about features, see -:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>` -and :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` variables. +For more information about library features, see the +:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>` and +:variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` variables. diff --git a/Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE.rst b/Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE.rst index f2ef843..7c929d0 100644 --- a/Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE.rst +++ b/Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE.rst @@ -3,25 +3,14 @@ CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE> .. versionadded:: 3.24 -This variable defines, for the specified ``<FEATURE>`` and the linker language -``<LANG>``, the expression expected by the linker when libraries are specified -using :genex:`LINK_GROUP` generator expression. +This variable defines how to link a group of libraries for the specified +``<FEATURE>`` when a :genex:`LINK_GROUP` generator expression is used and +the link language for the target is ``<LANG>``. +For this variable to have any effect, the associated +:variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` variable +must be set to true. -.. note:: - - * Feature names can contain Latin letters, digits and undercores. - * Feature names defined in all uppercase are reserved to CMake. - -See also the associated variable -:variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` and -:variable:`CMAKE_LINK_GROUP_USING_<FEATURE>` variable for the definition of -features independent from the link language. +The :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>` variable should be defined +instead for features that are independent of the link language. .. include:: CMAKE_LINK_GROUP_USING_FEATURE.txt - -Predefined Features -^^^^^^^^^^^^^^^^^^^ - -CMake pre-defines some features of general interest: - -.. include:: LINK_GROUP_PREDEFINED_FEATURES.txt diff --git a/Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE_SUPPORTED.rst b/Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE_SUPPORTED.rst index 533eee7..b314c5a 100644 --- a/Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE_SUPPORTED.rst +++ b/Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE_SUPPORTED.rst @@ -3,11 +3,12 @@ CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED .. versionadded:: 3.24 -Set to ``TRUE`` if the ``<FEATURE>``, as defined by variable -:variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>`, is supported for the -linker language ``<LANG>``. - -.. note:: - - This variable is evaluated before the more generic variable - :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED`. +This variable specifies whether the ``<FEATURE>`` is supported for the link +language ``<LANG>``. If this variable is true, then the ``<FEATURE>`` must +be defined by :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>`, and the +more generic :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED` and +:variable:`CMAKE_LINK_GROUP_USING_<FEATURE>` variables are not used. + +If ``CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED`` is false or is not +set, then the :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED` variable +will determine whether ``<FEATURE>`` is deemed to be supported. diff --git a/Help/variable/CMAKE_LANG_LINK_LIBRARY_USING_FEATURE.rst b/Help/variable/CMAKE_LANG_LINK_LIBRARY_USING_FEATURE.rst index 220ae99..39fcff8 100644 --- a/Help/variable/CMAKE_LANG_LINK_LIBRARY_USING_FEATURE.rst +++ b/Help/variable/CMAKE_LANG_LINK_LIBRARY_USING_FEATURE.rst @@ -3,25 +3,14 @@ CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE> .. versionadded:: 3.24 -This variable defines, for the specified ``<FEATURE>`` and the linker language -``<LANG>``, the expression expected by the linker when libraries are specified -using :genex:`LINK_LIBRARY` generator expression. +This variable defines how to link a library or framework for the specified +``<FEATURE>`` when a :genex:`LINK_LIBRARY` generator expression is used and +the link language for the target is ``<LANG>``. +For this variable to have any effect, the associated +:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` variable +must be set to true. -.. note:: - - * Feature names can contain Latin letters, digits and undercores. - * Feature names defined in all uppercase are reserved to CMake. - -See also the associated variable -:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` and -:variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` variable for the definition of -features independent from the link language. +The :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` variable should be defined +instead for features that are independent of the link language. .. include:: CMAKE_LINK_LIBRARY_USING_FEATURE.txt - -Predefined Features -^^^^^^^^^^^^^^^^^^^ - -CMake pre-defines some features of general interest: - -.. include:: LINK_LIBRARY_PREDEFINED_FEATURES.txt diff --git a/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.rst b/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.rst index 692c099..90b7f8b 100644 --- a/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.rst +++ b/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.rst @@ -3,31 +3,20 @@ CMAKE_LINK_GROUP_USING_<FEATURE> .. versionadded:: 3.24 -This variable defines, for the specified ``<FEATURE>``, the expression expected -by the linker when libraries are specified using :genex:`LINK_GROUP` generator -expression. +This variable defines how to link a group of libraries for the specified +``<FEATURE>`` when a :genex:`LINK_GROUP` generator expression is used. +Both of the following conditions must be met for this variable to have any +effect: -.. note:: +* The associated :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED` + variable must be set to true. - * Feature names can contain Latin letters, digits and undercores. - * Feature names defined in all uppercase are reserved to CMake. +* There is no language-specific definition for the same ``<FEATURE>``. + This means :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` + cannot be true for the link language used by the target for which the + :genex:`LINK_GROUP` generator expression is evaluated. -See also the associated variable -:variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED` and -:variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>` variable for the definition -of features dependent from the link language. - -This variable will be used by :genex:`LINK_GROUP` generator expression if, -for the linker language, the variable -:variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` is not defined -and the variable :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED` is -``TRUE``.. +The :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>` variable should be +defined instead for features that are dependent on the link language. .. include:: CMAKE_LINK_GROUP_USING_FEATURE.txt - -Predefined Features -^^^^^^^^^^^^^^^^^^^ - -CMake pre-defines some features of general interest: - -.. include:: LINK_GROUP_PREDEFINED_FEATURES.txt diff --git a/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.txt b/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.txt index ecd9cb5..23ea157 100644 --- a/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.txt +++ b/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.txt @@ -1,17 +1,24 @@ +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 (see `Predefined Features`_ further below). -It must contain two elements. + +Feature Definitions +^^^^^^^^^^^^^^^^^^^ + +A group feature definition is a list that contains exactly two elements: :: <PREFIX> <SUFFIX> -``<PREFIX>`` and ``<SUFFIX>`` will be used to encapsulate the list of -libraries. +On the linker command line, ``<PREFIX>`` will precede the list of libraries +in the group and ``<SUFFIX>`` will follow after. -For the elements of this variable, the ``LINKER:`` prefix can be used: +For the elements of this variable, the ``LINKER:`` prefix can be used. - .. include:: ../command/LINK_OPTIONS_LINKER.txt - :start-line: 3 +.. include:: ../command/LINK_OPTIONS_LINKER.txt + :start-line: 3 Examples ^^^^^^^^ @@ -19,36 +26,53 @@ Examples Solving cross-references between two static libraries """"""""""""""""""""""""""""""""""""""""""""""""""""" -A common need is the capability to search repeatedly in a group of static -libraries until no new undefined references are created. This capability is -offered by different environments but with a specific syntax: +A project may define two or more static libraries which have circular +dependencies between them. In order for the linker to resolve all symbols +at link time, it may need to search repeatedly among the libraries until no +new undefined references are created. Different linkers use different syntax +for achieving this. The following example shows how this may be implemented +for some linkers. Note that this is for illustration purposes only. +Projects should use the built-in ``RESCAN`` group feature instead +(see `Predefined Features`_), which provides a more complete and more robust +implementation of this functionality. .. code-block:: cmake set(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED TRUE) - if(CMAKE_C_COMPILER_ID STREQUAL "GNU" - AND CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(CMAKE_C_LINK_GROUP_USING_cross_refs "LINKER:--start-group" - "LINKER:--end-group") - elseif(CMAKE_C_COMPILER_ID STREQUAL "SunPro" - AND CMAKE_SYSTEM_NAME STREQUAL "SunOS") - set(CMAKE_C_LINK_GROUP_USING_cross_refs "LINKER:-z,rescan-start" - "LINKER:-z,rescan-end") + if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(CMAKE_C_LINK_GROUP_USING_cross_refs + "LINKER:--start-group" + "LINKER:--end-group" + ) + elseif(CMAKE_C_COMPILER_ID STREQUAL "SunPro" AND CMAKE_SYSTEM_NAME STREQUAL "SunOS") + set(CMAKE_C_LINK_GROUP_USING_cross_refs + "LINKER:-z,rescan-start" + "LINKER:-z,rescan-end" + ) else() # feature not yet supported for the other environments set(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED FALSE) endif() add_library(lib1 STATIC ...) + add_library(lib2 SHARED ...) - add_library(lib3 SHARED ...) if(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED) - target_link_libraries(lib3 PRIVATE "$<LINK_GROUP:cross_refs,lib1,external>") + target_link_libraries(lib2 PRIVATE "$<LINK_GROUP:cross_refs,lib1,external>") else() - target_link_libraries(lib3 PRIVATE lib1 external) + target_link_libraries(lib2 PRIVATE lib1 external) endif() -CMake will generate the following link expressions: +CMake will generate the following linker command line fragments when linking +``lib2``: * ``GNU``: ``-Wl,--start-group /path/to/lib1.a -lexternal -Wl,--end-group`` * ``SunPro``: ``-Wl,-z,rescan-start /path/to/lib1.a -lexternal -Wl,-z,rescan-end`` + + +Predefined Features +^^^^^^^^^^^^^^^^^^^ + +The following built-in group features are pre-defined by CMake: + +.. include:: LINK_GROUP_PREDEFINED_FEATURES.txt diff --git a/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE_SUPPORTED.rst b/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE_SUPPORTED.rst index 318892f..8b4ee6e 100644 --- a/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE_SUPPORTED.rst +++ b/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE_SUPPORTED.rst @@ -3,11 +3,10 @@ CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED .. versionadded:: 3.24 -Set to ``TRUE`` if the ``<FEATURE>``, as defined by variable -:variable:`CMAKE_LINK_GROUP_USING_<FEATURE>`, is supported regardless the -linker language. +This variable specifies whether the ``<FEATURE>`` is supported regardless of +the link language. If this variable is true, then the ``<FEATURE>`` must +be defined by :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>`. -.. note:: - - This variable is evaluated if, and only if, the variable - :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` is not defined. +Note that this variable has no effect if +:variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` is true for +the link language of the target. diff --git a/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.rst b/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.rst index 9f1cede..c652733 100644 --- a/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.rst +++ b/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.rst @@ -3,31 +3,17 @@ CMAKE_LINK_LIBRARY_USING_<FEATURE> .. versionadded:: 3.24 -This variable defines, for the specified ``FEATURE``, the expression expected -by the linker, regardless the linker language, when libraries are specified -using :genex:`LINK_LIBRARY` generator expression. +This variable defines how to link a library or framework for the specified +``<FEATURE>`` when a :genex:`LINK_LIBRARY` generator expression is used. +Both of the following conditions must be met for this variable to have any +effect: -.. note:: +* The associated :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` + variable must be set to true. - * Feature names can contain Latin letters, digits and undercores. - * Feature names defined in all uppercase are reserved to CMake. - -See also the associated variable -:variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` and -:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>` variable for the -definition of features dependent from the link language. - -This variable will be used by :genex:`LINK_LIBRARY` generator expression if, -for the linker language, the variable -:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` is not defined -and the variable :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` is -``TRUE``. +* There is no language-specific definition for the same ``<FEATURE>``. + This means :variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` + cannot be true for the link language used by the target for which the + :genex:`LINK_LIBRARY` generator expression is evaluated. .. include:: CMAKE_LINK_LIBRARY_USING_FEATURE.txt - -Predefined Features -^^^^^^^^^^^^^^^^^^^ - -CMake pre-defines some features of general interest: - -.. include:: LINK_LIBRARY_PREDEFINED_FEATURES.txt diff --git a/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.txt b/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.txt index ec293d3..4b13b7c 100644 --- a/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.txt +++ b/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.txt @@ -1,39 +1,58 @@ +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 (see `Predefined Features`_ further below). -It can contain one or three elements. -:: - - [<PREFIX>] <LIBRARY_EXPRESSION> [<SUFFIX>] +Feature Definitions +^^^^^^^^^^^^^^^^^^^ -When ``<PREFIX>`` and/or ``<SUFFIX>`` are specified, they encapsulate the list -of libraries. +A library feature definition is a list that contains one or three elements: -.. note:: +:: - Even if ``<PREFIX>`` and ``<SUFFIX>`` are specified, there is not guarantee - that the list of specified libraries, as part of :genex:`LINK_LIBRARY` - generator expression, will be kept grouped. So, constructs like - ``start-group`` and ``end-group``, as supported by ``GNU ld``, cannot be - used. + [<PREFIX>] <LIBRARY_EXPRESSION> [<SUFFIX>] -``<LIBRARY_EXPRESSION>`` is used to specify the decoration for each -library. For that purpose, the patterns ``<LIBRARY>``, ``<LINK_ITEM>``, and -``<LIB_ITEM>`` are available: +When ``<PREFIX>`` and ``<SUFFIX>`` are specified, they precede and follow +respectively the whole list of libraries specified in the +:genex:`LINK_LIBRARY` expression, not each library item individually. +There is no guarantee that the list of specified libraries will be kept +grouped together though, so the ``<PREFIX>`` and ``<SUFFIX>`` may appear +more than once if the library list is reorganized by CMake to satisfy other +constraints. This means constructs like ``--start-group`` and ``--end-group``, +as supported by the GNU ``ld`` linker, cannot be used in this way. The +:genex:`LINK_GROUP` generator expression should be used instead for such +constructs. + +``<LIBRARY_EXPRESSION>`` is used to specify the pattern for constructing the +corresponding fragment on the linker command line for each library. +The following placeholders can be used in the expression: + +* ``<LIBRARY>`` is expanded to the full path to the library for CMake targets, + or to a platform-specific value based on the item otherwise (the same as + ``<LINK_ITEM>`` on Windows, or the library base name for other platforms). +* ``<LINK_ITEM>`` is expanded to how the library would normally be linked on + the linker command line. +* ``<LIB_ITEM>`` is expanded to the full path to the library for CMake targets, + or the item itself exactly as specified in the ``<LIBRARY_EXPRESSION>`` + otherwise. + +In addition to the above, it is possible to have one pattern for paths +(CMake targets and external libraries specified with file paths) and another +for other items specified by name only. The ``PATH{}`` and ``NAME{}`` wrappers +can be used to provide the expansion for those two cases, respectively. +When wrappers are used, both must be present. For example: -* ``<LIBRARY>`` is expanded to the library as computed by CMake. -* ``<LINK_ITEM>`` is expanded to the same expression as if the library was - specified in the standard way. -* ``<LIB_ITEM>`` is equivalent to ``<LIBRARY>`` for CMake targets and is - expanded to the item specified by the user for external libraries. +.. code-block:: cmake -Moreover, it is possible to have different decorations for paths (CMake targets -and external libraries specified with absolute paths) and other items specified -by name. For that purpose, ``PATH{}`` and ``NAME{}`` wrappers can be used. + set(CMAKE_LINK_LIBRARY_USING_weak_library + "PATH{-weak_library <LIBRARY>}NAME{LINKER:-weak-l<LIB_ITEM>}" + ) -For all three elements of this variable, the ``LINKER:`` prefix can be used: +For all three elements of this variable (``<PREFIX>``, ``<LIBRARY_EXPRESSION>``, +and ``<SUFFIX>``), the ``LINKER:`` prefix can be used. - .. include:: ../command/LINK_OPTIONS_LINKER.txt - :start-line: 3 +.. include:: ../command/LINK_OPTIONS_LINKER.txt + :start-line: 3 Examples ^^^^^^^^ @@ -41,19 +60,24 @@ Examples Loading a whole static library """""""""""""""""""""""""""""" -A common need is the capability to load a whole static library. This capability -is offered by various environments but with a specific syntax: +A common need is to prevent the linker from discarding any symbols from a +static library. Different linkers use different syntax for achieving this. +The following example shows how this may be implemented for some linkers. +Note that this is for illustration purposes only. Projects should use the +built-in ``WHOLE_ARCHIVE`` feature instead (see `Predefined Features`_), which +provides a more complete and more robust implementation of this functionality. .. code-block:: cmake set(CMAKE_C_LINK_LIBRARY_USING_load_archive_SUPPORTED TRUE) if(CMAKE_C_COMPILER_ID STREQUAL "AppleClang") set(CMAKE_C_LINK_LIBRARY_USING_load_archive "-force_load <LIB_ITEM>") - elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU" - AND CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(CMAKE_C_LINK_LIBRARY_USING_load_archive "LINKER:--push-state,--whole-archive" - "<LINK_ITEM>" - "LINKER:--pop-state") + elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(CMAKE_C_LINK_LIBRARY_USING_load_archive + "LINKER:--push-state,--whole-archive" + "<LINK_ITEM>" + "LINKER:--pop-state" + ) elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC") set(CMAKE_C_LINK_LIBRARY_USING_load_archive "/WHOLEARCHIVE:<LIBRARY>") else() @@ -62,41 +86,45 @@ is offered by various environments but with a specific syntax: endif() add_library(lib1 STATIC ...) - add_library(lib2 SHARED ...) + if(CMAKE_C_LINK_LIBRARY_USING_load_archive_SUPPORTED) + # The -force_load Apple linker option requires a file name + set(external_lib + "$<IF:$<LINK_LANG_AND_ID:C,AppleClang>,libexternal.a,external>" + ) target_link_libraries(lib2 PRIVATE - "$<LINK_LIBRARY:load_archive,lib1,$<IF:$<LINK_LANG_AND_ID:C,Clang>,libexternal.a,external>>") + "$<LINK_LIBRARY:load_archive,lib1,${external_lib}>" + ) else() target_link_libraries(lib2 PRIVATE lib1 external) endif() CMake will generate the following link expressions: -* ``Clang``: ``-force_load /path/to/lib1.a -force_load libexternal.a`` -* ``GNU``: ``-Wl,--whole-archive /path/to/lib1.a -lexternal -Wl,--no-whole-archive`` +* ``AppleClang``: ``-force_load /path/to/lib1.a -force_load libexternal.a`` +* ``GNU``: ``-Wl,--push-state,--whole-archive /path/to/lib1.a -lexternal -Wl,--pop-state`` * ``MSVC``: ``/WHOLEARCHIVE:/path/to/lib1.lib /WHOLEARCHIVE:external.lib`` -CMake will ensure, when possible, that ``<PREFIX>`` and ``<SUFFIX>`` are -not repeated for each library. - -In case of ``Clang``, the pattern ``<LIB_ITEM>`` is used because we need to -specify the library as defined by the user, not the name computed by CMake -(in that case ``external``). - Linking a library as weak """"""""""""""""""""""""" -On MacOS, it is possible to link a library in weak mode (the library and all -references are marked as weak imports), but different flags must be used for a -library specified by path and by name. This constraint by be solved by using -``PATH{}`` and ``NAME{}`` wrappers: +On macOS, it is possible to link a library in weak mode (the library and all +references are marked as weak imports). Different flags must be used for a +library specified by file path compared to one specified by name. +This constraint can be solved using ``PATH{}`` and ``NAME{}`` wrappers. +Again, the following example shows how this may be implemented for some +linkers, but it is for illustration purposes only. Projects should use the +built-in ``WEAK_FRAMEWORK`` or ``WEAK_LIBRARY`` features instead (see +`Predefined Features`_), which provide more complete and more robust +implementations of this functionality. .. code-block:: cmake if (CMAKE_C_COMPILER_ID STREQUAL "AppleClang") set(CMAKE_LINK_LIBRARY_USING_weak_library - "PATH{-weak_library <LIBRARY>}NAME{LINKER:-weak-l<LIB_ITEM>}") + "PATH{-weak_library <LIBRARY>}NAME{LINKER:-weak-l<LIB_ITEM>}" + ) set(CMAKE_LINK_LIBRARY_USING_weak_library_SUPPORTED TRUE) endif() @@ -108,5 +136,15 @@ library specified by path and by name. This constraint by be solved by using target_link_libraries(main PRIVATE lib external) endif() -CMake will generate the following link expression: -``-weak_library /path/to/lib -Xlinker -weak-lexternal`` +CMake will generate the following linker command line fragment when linking +``main`` using the ``AppleClang`` toolchain: + +``-weak_library /path/to/lib -Xlinker -weak-lexternal``. + + +Predefined Features +^^^^^^^^^^^^^^^^^^^ + +The following built-in library features are pre-defined by CMake: + +.. include:: LINK_LIBRARY_PREDEFINED_FEATURES.txt diff --git a/Help/variable/LINK_GROUP_PREDEFINED_FEATURES.txt b/Help/variable/LINK_GROUP_PREDEFINED_FEATURES.txt index 5f1a11b..557886e 100644 --- a/Help/variable/LINK_GROUP_PREDEFINED_FEATURES.txt +++ b/Help/variable/LINK_GROUP_PREDEFINED_FEATURES.txt @@ -1,22 +1,22 @@ -**Circular references with static libraries** - -Some linkers are one-pass only so to handle circular references between -static libraries, the following feature can be used: - ``RESCAN`` - The specified static libraries are searched repeatedly until no - new undefined references are created. Normally, an static library is searched - only once in the order that it is specified on the command line. If a symbol - in that library is needed to resolve an undefined symbol referred to by an - object in an library that appears later on the command line, the linker would - not be able to resolve that reference. By grouping the static libraries, they - all be searched repeatedly until all possible references are resolved (use - linker options ``--start-group`` and ``--end-group`` or, on ``SunOS``, - ``-z rescan-start`` and ``-z rescan-end``). + Some linkers are single-pass only. For such linkers, circular references + between libraries typically result in unresolved symbols. This feature + instructs the linker to search the specified static libraries repeatedly + until no new undefined references are created. + + Normally, a static library is searched only once in the order that it is + specified on the command line. If a symbol in that library is needed to + resolve an undefined symbol referred to by an object in a library that + appears later on the command line, the linker would not be able to resolve + that reference. By grouping the static libraries with the ``RESCAN`` + feature, they will all be searched repeatedly until all possible references + are resolved. This will use linker options like ``--start-group`` and + ``--end-group``, or on SunOS, ``-z rescan-start`` and ``-z rescan-end``. Using this feature has a significant performance cost. It is best to use it only when there are unavoidable circular references between two or more static libraries. - This feature is available on ``Linux``, ``BSD``, and ``SunOS`` target - platforms as well as ``Windows`` when ``GNU`` toolchain is used. + This feature is available when using toolchains that target Linux, BSD, and + SunOS. It can also be used when targeting Windows platforms if the GNU + toolchain is used. diff --git a/Help/variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt b/Help/variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt index e4fa0ed8..8ae6c57 100644 --- a/Help/variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt +++ b/Help/variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt @@ -1,88 +1,96 @@ -**Features available in all environments** - ``DEFAULT`` - This feature enables default link expression. This is mainly - useful with :prop_tgt:`LINK_LIBRARY_OVERRIDE` and + This feature corresponds to standard linking, essentially equivalent to + using no feature at all. It is typically only used with the + :prop_tgt:`LINK_LIBRARY_OVERRIDE` and :prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` target properties. -**Features available for a subset of environments** - ``WHOLE_ARCHIVE`` - Force load of all members in a static library. - - Target platforms supported: all ``Apple`` variants, ``Linux``, all ``BSD`` - variants, ``SunOS``, ``Windows``, ``CYGWIN``, and ``MSYS``. - - Platform-specific notes: - - * On Apple platforms, the library must be specified as a CMake target name, a - library file name (such as ``libfoo.a``), or a library file path (such as - ``/path/to/libfoo.a``). It cannot be specified as a plain library name - (such as ``foo``, where ``foo`` is not CMake target), due to a limitation - in the Apple linker. - * On Windows platforms, for ``MSVC`` or MSVC-like toolchains, the version - must be greater than ``1900``. - -**Features available in Apple environments** - -It is assumed that the linker used is the one provided by `XCode` or is -compatible with it. - -Framework support + Force inclusion of all members of a static library. This feature is only + supported for the following platforms, with limitations as noted: + + * Linux. + * All BSD variants. + * SunOS. + * All Apple variants. The library must be specified as a CMake target name, + a library file name (such as ``libfoo.a``), or a library file path (such as + ``/path/to/libfoo.a``). Due to a limitation of the Apple linker, it + cannot be specified as a plain library name like ``foo``, where ``foo`` + is not a CMake target. + * Windows. When using a MSVC or MSVC-like toolchain, the MSVC version must + be greater than 1900. + * Cygwin. + * MSYS. ``FRAMEWORK`` - This option tells the linker to search for the specified - framework (use linker option ``-framework``). -``NEEDED_FRAMEWORK`` - This is the same as the ``FRAMEWORK`` feature but means - to really link with the framework even if no symbols are used from it (use - linker option ``-needed_framework``). -``REEXPORT_FRAMEWORK`` - This is the same as the ``FRAMEWORK`` feature but - also specifies that all symbols in that framework should be available to - clients linking to the library being created (use linker option - ``-reexport_framework``). -``WEAK_FRAMEWORK`` - This is the same as the ``FRAMEWORK`` feature but forces - the framework and all references to it to be marked as weak imports (use - linker option ``-weak_framework``). + This option tells the linker to search for the specified framework using + the ``-framework`` linker option. It can only be used on Apple platforms, + and only with a linker that understands the option used (i.e. the linker + provided with Xcode, or one compatible with it). + + The framework can be specified as a CMake framework target, a bare framework + name, or a file path. If a target is given, that target must have the + :prop_tgt:`FRAMEWORK` target property set to true. For a file path, if it + contains a directory part, that directory will be added as a framework + search path. + + .. code-block:: cmake + + add_library(lib SHARED ...) + target_link_libraries(lib PRIVATE "$<LINK_LIBRARY:FRAMEWORK,/path/to/my_framework>") + + # The constructed linker command line will contain: + # -F/path/to -framework my_framework + + File paths must conform to one of the following patterns (``*`` is a + wildcard, and optional parts are shown as ``[...]``): + + * ``[/path/to/]FwName[.framework]`` + * ``[/path/to/]FwName.framework/FwName`` + * ``[/path/to/]FwName.framework/Versions/*/FwName`` + + Note that CMake recognizes and automatically handles framework targets, + even without using the ``$<LINK_LIBRARY:FRAMEWORK,...>`` expression. + The generator expression can still be used with a CMake target if the + project wants to be explicit about it, but it is not required to do so. + The linker command line may have some differences between using the + generator expression or not, but the final result should be the same. + On the other hand, if a file path is given, CMake will recognize some paths + automatically, but not all cases. The project may want to use + ``$<LINK_LIBRARY:FRAMEWORK,...>`` for file paths so that the expected + behavior is clear. -Features for framework linking have a special handling in CMake: the -framework can be specified as a CMake framework target or file path. In the -first case, the target must have the :prop_tgt:`FRAMEWORK` target property set -as ``TRUE`` to enable framework handling. In the later case, if the path -includes a directory part, this one will be specified as framework search path -at link step. - -.. code-block:: cmake - - add_library(lib SHARED ...) - target_link_libraries(lib PRIVATE "$<LINK_LIBRARY:NEEDED_FRAMEWORK,/path/to/my_framework>") - - # at link step we will have: - # -F/path/to -needed_framework my_framework - -.. note:: - - The expected formats for the file path, with optional parts specified as - ``()?``, are: +``NEEDED_FRAMEWORK`` + This is similar to the ``FRAMEWORK`` feature, except it forces the linker + to link with the framework even if no symbols are used from it. It uses + the ``-needed_framework`` option and has the same linker constraints as + ``FRAMEWORK``. - * (/path/to/)?FwName(.framework)? - * (/path/to/)?FwName.framework/FwName - * (/path/to/)?FwName.framework/Versions/\*/FwName +``REEXPORT_FRAMEWORK`` + This is similar to the ``FRAMEWORK`` feature, except it tells the linker + that the framework should be available to clients linking to the library + being created. It uses the ``-reexport_framework`` option and has the + same linker constraints as ``FRAMEWORK``. -Library support +``WEAK_FRAMEWORK`` + This is similar to the ``FRAMEWORK`` feature, except it forces the linker + to mark the framework and all references to it as weak imports. It uses + the ``-weak_framework`` option and has the same linker constraints as + ``FRAMEWORK``. ``NEEDED_LIBRARY`` - This is the same as specifying a link item (target or - library) but means to really link with the item even if no symbols are used - from it (use linker option ``-needed_library`` or ``-needed-l``). + This is similar to the ``NEEDED_FRAMEWORK`` feature, except it is for use + with non-framework targets or libraries (Apple platforms only). + It uses the ``-needed_library`` or ``-needed-l`` option as appropriate, + and has the same linker constraints as ``NEEDED_FRAMEWORK``. + ``REEXPORT_LIBRARY`` - This is the same as specifying a link item (target or - library) but also specifies that all symbols in that item should be available - to clients linking to the library being created (use linker option - ``-reexport_library`` or ``-reexport-l``). + This is similar to the ``REEXPORT_FRAMEWORK`` feature, except it is for use + with non-framework targets or libraries (Apple platforms only). + It uses the ``-reexport_library`` or ``-reexport-l`` option as appropriate, + and has the same linker constraints as ``REEXPORT_FRAMEWORK``. + ``WEAK_LIBRARY`` - This is the same as specifying a link item (target or - library) but forces the item and all references to it to be marked as weak - imports (use linker option ``-weak_library`` or ``-weak-l``). + This is similar to the ``WEAK_FRAMEWORK`` feature, except it is for use + with non-framework targets or libraries (Apple platforms only). + It uses the ``-weak_library`` or ``-weak-l`` option as appropriate, + and has the same linker constraints as ``WEAK_FRAMEWORK``. |