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:45 (GMT) |
commit | 51dd0d758d738eec0b7739f2978f0250417a97a4 (patch) | |
tree | f78a6768e085981bd6449c17728e70534f6f3ec3 /Help/variable | |
parent | 1392102e8853844005c272768cce0c91bbb22408 (diff) | |
parent | d185f7c0a8cac19edaea8d54c2a12b51a622731b (diff) | |
download | CMake-51dd0d758d738eec0b7739f2978f0250417a97a4.zip CMake-51dd0d758d738eec0b7739f2978f0250417a97a4.tar.gz CMake-51dd0d758d738eec0b7739f2978f0250417a97a4.tar.bz2 |
Merge topic 'doc-LINK_LIBRARY_genex'
d185f7c0a8 Help: Rework $<LINK_LIBRARY>, $<LINK_GROUP> and related docs
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !7413
Diffstat (limited to 'Help/variable')
-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 |
10 files changed, 286 insertions, 263 deletions
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``. |