Help: Rework $<LINK_LIBRARY>, $<LINK_GROUP> and related docs
These changes restructure the docs to improve readability and flow, correct grammar and typos, and fix errors and inconsistencies in some of the examples. Fixes: #23684
This commit is contained in:
parent
8c562ece28
commit
d185f7c0a8
@ -1370,229 +1370,237 @@ Output-Related Expressions
|
|||||||
|
|
||||||
.. versionadded:: 3.24
|
.. versionadded:: 3.24
|
||||||
|
|
||||||
Manage how libraries are specified during the link step.
|
Specify a set of libraries to link to a target, along with a ``feature``
|
||||||
This expression may be used to specify how to link libraries in a target.
|
which provides details about *how* they should be linked. For example:
|
||||||
For example:
|
|
||||||
|
|
||||||
.. code-block:: cmake
|
.. code-block:: cmake
|
||||||
|
|
||||||
add_library(lib1 STATIC ...)
|
add_library(lib1 STATIC ...)
|
||||||
add_library(lib2 ...)
|
add_library(lib2 ...)
|
||||||
target_link_libraries(lib2 PRIVATE "$<LINK_LIBRARY:load_archive,lib1>")
|
target_link_libraries(lib2 PRIVATE "$<LINK_LIBRARY:WHOLE_ARCHIVE,lib1>")
|
||||||
|
|
||||||
This specify to use the ``lib1`` target with feature ``load_archive`` for
|
This specifies that ``lib2`` should link to ``lib1`` and use the
|
||||||
linking target ``lib2``. The feature must have be defined by
|
``WHOLE_ARCHIVE`` feature when doing so.
|
||||||
: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::
|
Feature names are case-sensitive and may only contain letters, numbers and
|
||||||
|
underscores. Feature names defined in all uppercase are reserved for CMake's
|
||||||
The evaluation of this generator expression will use, for the following
|
own built-in features. The pre-defined built-in library features are:
|
||||||
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).
|
|
||||||
|
|
||||||
.. 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.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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 ...)
|
|
||||||
|
|
||||||
add_library(lib2 ...)
|
|
||||||
target_link_libraries(lib2 PUBLIC "$<LINK_LIBRARY:feature1,lib1>")
|
|
||||||
|
|
||||||
add_library(lib3 ...)
|
|
||||||
target_link_libraries(lib3 PRIVATE lib1 lib2)
|
|
||||||
# an error will be raised here because lib1 has two different features
|
|
||||||
|
|
||||||
To resolve such incompatibilities, the :prop_tgt:`LINK_LIBRARY_OVERRIDE`
|
|
||||||
and :prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` target properties can be
|
|
||||||
used.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
CMake pre-defines some features of general interest:
|
|
||||||
|
|
||||||
.. include:: ../variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt
|
.. include:: ../variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
add_library(lib1 ...)
|
||||||
|
add_library(lib2 ...)
|
||||||
|
add_library(lib3 ...)
|
||||||
|
|
||||||
|
# lib1 will be associated with feature1
|
||||||
|
target_link_libraries(lib2 PUBLIC "$<LINK_LIBRARY:feature1,lib1>")
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
* 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>
|
.. genex:: $<LINK_GROUP:feature,library-list>
|
||||||
|
|
||||||
.. versionadded:: 3.24
|
.. versionadded:: 3.24
|
||||||
|
|
||||||
Manage the grouping of libraries during the link step.
|
Specify a group of libraries to link to a target, along with a ``feature``
|
||||||
This expression may be used to specify how to keep groups of libraries during
|
which defines how that group should be linked. For example:
|
||||||
the link of a target.
|
|
||||||
For example:
|
|
||||||
|
|
||||||
.. code-block:: cmake
|
.. code-block:: cmake
|
||||||
|
|
||||||
add_library(lib1 STATIC ...)
|
add_library(lib1 STATIC ...)
|
||||||
add_library(lib2 ...)
|
add_library(lib2 ...)
|
||||||
target_link_libraries(lib2 PRIVATE "$<LINK_GROUP:cross_refs,lib1,external>")
|
target_link_libraries(lib2 PRIVATE "$<LINK_GROUP:RESCAN,lib1,external>")
|
||||||
|
|
||||||
This specify to use the ``lib1`` target and ``external`` library with the
|
This specifies that ``lib2`` should link to ``lib1`` and ``external``, and
|
||||||
group feature ``cross_refs`` for linking target ``lib2``. The feature must
|
that both of those two libraries should be included on the linker command
|
||||||
have be defined by :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>`
|
line according to the definition of the ``RESCAN`` feature.
|
||||||
variable or, if :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED`
|
|
||||||
is false, by :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>` variable.
|
|
||||||
|
|
||||||
.. note::
|
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:
|
||||||
|
|
||||||
The evaluation of this generator expression will use, for the following
|
.. include:: ../variable/LINK_GROUP_PREDEFINED_FEATURES.txt
|
||||||
variables, the values defined at the level of the creation of the target:
|
|
||||||
|
|
||||||
* :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED`
|
Built-in and custom group features are defined in terms of the following
|
||||||
* :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>`
|
variables:
|
||||||
* :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED`
|
|
||||||
* :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>`
|
|
||||||
|
|
||||||
This expression can only be used to specify link libraries (i.e. part of
|
* :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED`
|
||||||
:command:`link_libraries` or :command:`target_link_libraries` commands and
|
* :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>`
|
||||||
:prop_tgt:`LINK_LIBRARIES` or :prop_tgt:`INTERFACE_LINK_LIBRARIES` target
|
* :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED`
|
||||||
properties).
|
* :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>`
|
||||||
|
|
||||||
.. note::
|
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:
|
||||||
|
|
||||||
If this expression appears in the :prop_tgt:`INTERFACE_LINK_LIBRARIES`
|
1. If the language-specific
|
||||||
property of a target, it will be included in the imported target generated
|
:variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` variable
|
||||||
by :command:`install(EXPORT)` command. It is the responsibility of the
|
is true, the ``feature`` must be defined by the corresponding
|
||||||
environment consuming this import to define the link feature used by this
|
:variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>` variable.
|
||||||
expression.
|
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.
|
||||||
|
|
||||||
The ``library-list`` argument can hold CMake targets or external libraries.
|
The ``LINK_GROUP`` generator expression is compatible with the
|
||||||
Any CMake target of type :ref:`OBJECT <Object Libraries>` or
|
:genex:`LINK_LIBRARY` generator expression. The libraries involved in a
|
||||||
:ref:`INTERFACE <Interface Libraries>` will be ignored by this expression and
|
group can be specified using the :genex:`LINK_LIBRARY` generator expression.
|
||||||
will be handled in the standard way.
|
|
||||||
|
|
||||||
.. note::
|
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
|
||||||
This expression is compatible with the :genex:`LINK_LIBRARY` generator
|
same ``feature``. Such groups will not be merged on the linker command line,
|
||||||
expression. The libraries involved in a group can be specified using the
|
the individual groups will still be preserved. Mixing different group
|
||||||
:genex:`LINK_LIBRARY` generator expression.
|
features for the same target or library is forbidden.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
.. code-block:: cmake
|
.. code-block:: cmake
|
||||||
|
|
||||||
add_library(lib1 ...)
|
add_library(lib1 ...)
|
||||||
add_library(lib2 ...)
|
add_library(lib2 ...)
|
||||||
|
|
||||||
add_library(lib3 ...)
|
add_library(lib3 ...)
|
||||||
target_link_libraries(lib3 PUBLIC "$<LINK_GROUP:feature1,lib1,lib2>")
|
|
||||||
|
|
||||||
add_library(lib4 ...)
|
add_library(lib4 ...)
|
||||||
target_link_libraries(lib4 PRIVATE "$<LINK_GROUP:feature1,lib1,lib3>")
|
|
||||||
# lib4 will be linked with the groups {lib1,lib2} and {lib1,lib3}
|
|
||||||
|
|
||||||
add_library(lib5 ...)
|
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}.
|
||||||
|
# Both groups specify the same feature, so this is fine.
|
||||||
|
|
||||||
target_link_libraries(lib5 PRIVATE "$<LINK_GROUP:feature2,lib1,lib3>")
|
target_link_libraries(lib5 PRIVATE "$<LINK_GROUP:feature2,lib1,lib3>")
|
||||||
# an error will be raised here because lib1 is part of two groups with
|
# An error will be raised here because both lib1 and lib3 are part of two
|
||||||
# different features
|
# groups with different features.
|
||||||
|
|
||||||
When a target or an external library is involved in the link step as part of
|
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
|
a group and also as not part of any group, any occurrence of the non-group
|
||||||
will be replaced by the group or groups it belong to.
|
link item will be replaced by the groups it belongs to.
|
||||||
|
|
||||||
.. code-block:: cmake
|
.. code-block:: cmake
|
||||||
|
|
||||||
add_library(lib1 ...)
|
add_library(lib1 ...)
|
||||||
add_library(lib2 ...)
|
add_library(lib2 ...)
|
||||||
|
|
||||||
add_library(lib3 ...)
|
add_library(lib3 ...)
|
||||||
|
add_library(lib4 ...)
|
||||||
|
|
||||||
target_link_libraries(lib3 PUBLIC lib1)
|
target_link_libraries(lib3 PUBLIC lib1)
|
||||||
|
|
||||||
add_library(lib4 ...)
|
|
||||||
target_link_libraries(lib4 PRIVATE lib3 "$<LINK_GROUP:feature1,lib1,lib2>")
|
target_link_libraries(lib4 PRIVATE lib3 "$<LINK_GROUP:feature1,lib1,lib2>")
|
||||||
# lib4 will only be linked with lib3 and the group {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
|
.. code-block:: cmake
|
||||||
|
|
||||||
add_library(lib1 ...)
|
|
||||||
add_library(lib2 ...)
|
|
||||||
|
|
||||||
add_library(lib3 ...)
|
|
||||||
target_link_libraries(lib3 PUBLIC "$<LINK_GROUP:feature1,lib1,lib2>")
|
target_link_libraries(lib3 PUBLIC "$<LINK_GROUP:feature1,lib1,lib2>")
|
||||||
|
|
||||||
add_library(lib4 ...)
|
Be aware that the precedence of the group over the non-group link item can
|
||||||
target_link_libraries(lib4 PRIVATE lib3 "$<LINK_GROUP:feature1,lib1,lib2>")
|
result in circular dependencies between groups. If this occurs, a fatal
|
||||||
# lib4 will only be linked with lib3 and the group {lib1,lib2}
|
error is raised because circular dependencies are not allowed for groups.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
.. code-block:: cmake
|
.. code-block:: cmake
|
||||||
|
|
||||||
add_library(lib1A ...)
|
add_library(lib1A ...)
|
||||||
add_library(lib1B ...)
|
add_library(lib1B ...)
|
||||||
|
|
||||||
add_library(lib2A ...)
|
add_library(lib2A ...)
|
||||||
add_library(lib2B ...)
|
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(lib1A PUBLIC lib2A)
|
||||||
target_link_libraries(lib2B PUBLIC lib1B)
|
target_link_libraries(lib2B PUBLIC lib1B)
|
||||||
|
|
||||||
add_library(lib ...)
|
# The addition of these groups creates circular dependencies
|
||||||
target_link_libraries(lib3 PRIVATE "$<LINK_GROUP:feat,lib1A,lib1B>"
|
target_link_libraries(lib3 PRIVATE
|
||||||
"$<LINK_GROUP:feat,lib2A,lib2B>")
|
"$<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
|
.. 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(lib1A PUBLIC "$<LINK_GROUP:feat,lib2A,lib2B>")
|
||||||
target_link_libraries(lib2B PUBLIC "$<LINK_GROUP:feat,lib1A,lib1B>")
|
target_link_libraries(lib2B PUBLIC "$<LINK_GROUP:feat,lib1A,lib1B>")
|
||||||
|
|
||||||
add_library(lib ...)
|
This creates a circular dependency between groups:
|
||||||
target_link_libraries(lib3 PRIVATE "$<LINK_GROUP:feat,lib1A,lib1B>"
|
``lib1A --> lib2B --> lib1A``.
|
||||||
"$<LINK_GROUP:feat,lib2A,lib2B>")
|
|
||||||
|
|
||||||
So, we have a circular dependency between groups ``{lib1A,lib1B}`` and
|
The following limitations should also be noted:
|
||||||
``{lib2A,lib2B}``.
|
|
||||||
|
|
||||||
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:...>
|
.. genex:: $<INSTALL_INTERFACE:...>
|
||||||
|
|
||||||
|
@ -3,52 +3,63 @@ LINK_LIBRARY_OVERRIDE
|
|||||||
|
|
||||||
.. versionadded:: 3.24
|
.. versionadded:: 3.24
|
||||||
|
|
||||||
To resolve incompatible features introduced by :genex:`LINK_LIBRARY` generator
|
Override the library features associated with libraries from
|
||||||
expression, this property offers the possibility to override, per ``link-item``
|
:genex:`LINK_LIBRARY` generator expressions. This can be used to resolve
|
||||||
(``CMake`` target or external library) involved in the link step, any defined
|
incompatible library features that result from specifying different features
|
||||||
features with a new one.
|
for the same library in different :genex:`LINK_LIBRARY` generator expressions.
|
||||||
|
|
||||||
This property takes a :ref:`;-list <CMake Language Lists>` of override
|
This property supports overriding multiple libraries and features. It expects
|
||||||
declarations which have the following format:
|
a :ref:`semicolon-separated list <CMake Language Lists>`, where each list item
|
||||||
|
has the following form::
|
||||||
::
|
|
||||||
|
|
||||||
feature[,link-item]*
|
feature[,link-item]*
|
||||||
|
|
||||||
For the list of ``link-item`` (``CMake`` target or external library) specified,
|
For each comma-separated ``link-item``, any existing library feature associated
|
||||||
the feature ``feature`` will be used in place of any declared feature. For
|
with it will be ignored for the target this property is set on. The item
|
||||||
example:
|
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
|
.. code-block:: cmake
|
||||||
|
|
||||||
add_library(lib1 ...)
|
add_library(lib1 ...)
|
||||||
target_link_libraries(lib1 PUBLIC "$<LINK_LIBRARY:feature1,external>")
|
|
||||||
|
|
||||||
add_library(lib2 ...)
|
add_library(lib2 ...)
|
||||||
target_link_libraries(lib2 PUBLIC "$<LINK_LIBRARY:feature2,lib1>")
|
|
||||||
|
|
||||||
add_library(lib3 ...)
|
add_library(lib3 ...)
|
||||||
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
|
|
||||||
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
|
target_link_libraries(lib1 PUBLIC "$<LINK_LIBRARY:feature1,external>")
|
||||||
``DEFAULT`` to get the standard behavior (i.e. no feature):
|
target_link_libraries(lib2 PUBLIC "$<LINK_LIBRARY:feature2,lib1>")
|
||||||
|
target_link_libraries(lib3 PRIVATE lib1 lib2)
|
||||||
|
|
||||||
|
# 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")
|
||||||
|
|
||||||
|
# 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
|
.. code-block:: cmake
|
||||||
|
|
||||||
set_property(TARGET lib3 PROPERTY LINK_LIBRARY_OVERRIDE "DEFAULT,lib1"
|
# When linking lib3, discard any library feature for lib1, and use feature2 for external
|
||||||
"feature2,external")
|
set_property(TARGET lib3 PROPERTY LINK_LIBRARY_OVERRIDE
|
||||||
# The lib1 will be used without any feature and external will use feature2 to link lib3
|
"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
|
Contents of ``LINK_LIBRARY_OVERRIDE`` may use
|
||||||
:manual:`generator expressions <cmake-generator-expressions(7)>`.
|
:manual:`generator expressions <cmake-generator-expressions(7)>`.
|
||||||
|
|
||||||
See also :prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` target property for
|
For more information about library features, see the
|
||||||
a per linked target oriented approach to override features.
|
:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>` and
|
||||||
|
:variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` variables.
|
||||||
For more information about features, see
|
|
||||||
:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>`
|
|
||||||
and :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` variables.
|
|
||||||
|
@ -3,43 +3,49 @@ LINK_LIBRARY_OVERRIDE_<LIBRARY>
|
|||||||
|
|
||||||
.. versionadded:: 3.24
|
.. versionadded:: 3.24
|
||||||
|
|
||||||
To resolve incompatible features introduced by :genex:`LINK_LIBRARY` generator
|
Override the library feature associated with ``<LIBRARY>`` from
|
||||||
expression, this property offers the possibility to override, for a
|
:genex:`LINK_LIBRARY` generator expressions. This can be used to resolve
|
||||||
``link-item`` (``CMake`` target or external library) involved in the link step,
|
incompatible library features that result from specifying different features
|
||||||
any defined features with a new one.
|
for ``<LIBRARY>`` in different :genex:`LINK_LIBRARY` generator expressions.
|
||||||
|
|
||||||
This property takes a ``feature`` name which will be applied to the
|
When set on a target, this property holds a single library feature name, which
|
||||||
``link-item`` specified by ``<LIBRARY>`` suffix property. For example:
|
will be applied to ``<LIBRARY>`` when linking that target.
|
||||||
|
|
||||||
.. code-block:: cmake
|
.. code-block:: cmake
|
||||||
|
|
||||||
add_library(lib1 ...)
|
add_library(lib1 ...)
|
||||||
target_link_libraries(lib1 PUBLIC "$<LINK_LIBRARY:feature1,external>")
|
|
||||||
|
|
||||||
add_library(lib2 ...)
|
add_library(lib2 ...)
|
||||||
target_link_libraries(lib2 PUBLIC "$<LINK_LIBRARY:feature2,lib1>")
|
|
||||||
|
|
||||||
add_library(lib3 ...)
|
add_library(lib3 ...)
|
||||||
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
|
|
||||||
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
|
target_link_libraries(lib1 PUBLIC "$<LINK_LIBRARY:feature1,external>")
|
||||||
``DEFAULT`` to get the standard behavior (i.e. no feature):
|
target_link_libraries(lib2 PUBLIC "$<LINK_LIBRARY:feature2,lib1>")
|
||||||
|
target_link_libraries(lib3 PRIVATE lib1 lib2)
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
# 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
|
.. code-block:: cmake
|
||||||
|
|
||||||
|
# When linking lib3, discard any library feature for lib1
|
||||||
set_property(TARGET lib3 PROPERTY LINK_LIBRARY_OVERRIDE_lib1 DEFAULT)
|
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
|
Contents of ``LINK_LIBRARY_OVERRIDE_<LIBRARY>`` may use
|
||||||
:manual:`generator expressions <cmake-generator-expressions(7)>`.
|
:manual:`generator expressions <cmake-generator-expressions(7)>`.
|
||||||
|
|
||||||
This property takes precedence over :prop_tgt:`LINK_LIBRARY_OVERRIDE`
|
For more information about library features, see the
|
||||||
target property.
|
:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>` and
|
||||||
|
:variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` variables.
|
||||||
For more information about features, see
|
|
||||||
:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>`
|
|
||||||
and :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` variables.
|
|
||||||
|
@ -3,25 +3,14 @@ CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>
|
|||||||
|
|
||||||
.. versionadded:: 3.24
|
.. versionadded:: 3.24
|
||||||
|
|
||||||
This variable defines, for the specified ``<FEATURE>`` and the linker language
|
This variable defines how to link a group of libraries for the specified
|
||||||
``<LANG>``, the expression expected by the linker when libraries are specified
|
``<FEATURE>`` when a :genex:`LINK_GROUP` generator expression is used and
|
||||||
using :genex:`LINK_GROUP` generator expression.
|
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::
|
The :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>` variable should be defined
|
||||||
|
instead for features that are independent of the link language.
|
||||||
* 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.
|
|
||||||
|
|
||||||
.. include:: CMAKE_LINK_GROUP_USING_FEATURE.txt
|
.. include:: CMAKE_LINK_GROUP_USING_FEATURE.txt
|
||||||
|
|
||||||
Predefined Features
|
|
||||||
^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
CMake pre-defines some features of general interest:
|
|
||||||
|
|
||||||
.. include:: LINK_GROUP_PREDEFINED_FEATURES.txt
|
|
||||||
|
@ -3,11 +3,12 @@ CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED
|
|||||||
|
|
||||||
.. versionadded:: 3.24
|
.. versionadded:: 3.24
|
||||||
|
|
||||||
Set to ``TRUE`` if the ``<FEATURE>``, as defined by variable
|
This variable specifies whether the ``<FEATURE>`` is supported for the link
|
||||||
:variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>`, is supported for the
|
language ``<LANG>``. If this variable is true, then the ``<FEATURE>`` must
|
||||||
linker language ``<LANG>``.
|
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.
|
||||||
|
|
||||||
.. note::
|
If ``CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED`` is false or is not
|
||||||
|
set, then the :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED` variable
|
||||||
This variable is evaluated before the more generic variable
|
will determine whether ``<FEATURE>`` is deemed to be supported.
|
||||||
:variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED`.
|
|
||||||
|
@ -3,25 +3,14 @@ CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>
|
|||||||
|
|
||||||
.. versionadded:: 3.24
|
.. versionadded:: 3.24
|
||||||
|
|
||||||
This variable defines, for the specified ``<FEATURE>`` and the linker language
|
This variable defines how to link a library or framework for the specified
|
||||||
``<LANG>``, the expression expected by the linker when libraries are specified
|
``<FEATURE>`` when a :genex:`LINK_LIBRARY` generator expression is used and
|
||||||
using :genex:`LINK_LIBRARY` generator expression.
|
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::
|
The :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` variable should be defined
|
||||||
|
instead for features that are independent of the link language.
|
||||||
* 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.
|
|
||||||
|
|
||||||
.. include:: CMAKE_LINK_LIBRARY_USING_FEATURE.txt
|
.. include:: CMAKE_LINK_LIBRARY_USING_FEATURE.txt
|
||||||
|
|
||||||
Predefined Features
|
|
||||||
^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
CMake pre-defines some features of general interest:
|
|
||||||
|
|
||||||
.. include:: LINK_LIBRARY_PREDEFINED_FEATURES.txt
|
|
||||||
|
@ -3,31 +3,20 @@ CMAKE_LINK_GROUP_USING_<FEATURE>
|
|||||||
|
|
||||||
.. versionadded:: 3.24
|
.. versionadded:: 3.24
|
||||||
|
|
||||||
This variable defines, for the specified ``<FEATURE>``, the expression expected
|
This variable defines how to link a group of libraries for the specified
|
||||||
by the linker when libraries are specified using :genex:`LINK_GROUP` generator
|
``<FEATURE>`` when a :genex:`LINK_GROUP` generator expression is used.
|
||||||
expression.
|
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.
|
* There is no language-specific definition for the same ``<FEATURE>``.
|
||||||
* Feature names defined in all uppercase are reserved to CMake.
|
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
|
The :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>` variable should be
|
||||||
:variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED` and
|
defined instead for features that are dependent on the link language.
|
||||||
: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``..
|
|
||||||
|
|
||||||
.. include:: CMAKE_LINK_GROUP_USING_FEATURE.txt
|
.. include:: CMAKE_LINK_GROUP_USING_FEATURE.txt
|
||||||
|
|
||||||
Predefined Features
|
|
||||||
^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
CMake pre-defines some features of general interest:
|
|
||||||
|
|
||||||
.. include:: LINK_GROUP_PREDEFINED_FEATURES.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> <SUFFIX>
|
||||||
|
|
||||||
``<PREFIX>`` and ``<SUFFIX>`` will be used to encapsulate the list of
|
On the linker command line, ``<PREFIX>`` will precede the list of libraries
|
||||||
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
|
.. include:: ../command/LINK_OPTIONS_LINKER.txt
|
||||||
:start-line: 3
|
:start-line: 3
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
@ -19,36 +26,53 @@ Examples
|
|||||||
Solving cross-references between two static libraries
|
Solving cross-references between two static libraries
|
||||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""
|
"""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||||
|
|
||||||
A common need is the capability to search repeatedly in a group of static
|
A project may define two or more static libraries which have circular
|
||||||
libraries until no new undefined references are created. This capability is
|
dependencies between them. In order for the linker to resolve all symbols
|
||||||
offered by different environments but with a specific syntax:
|
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
|
.. code-block:: cmake
|
||||||
|
|
||||||
set(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED TRUE)
|
set(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED TRUE)
|
||||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU"
|
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||||
AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
set(CMAKE_C_LINK_GROUP_USING_cross_refs
|
||||||
set(CMAKE_C_LINK_GROUP_USING_cross_refs "LINKER:--start-group"
|
"LINKER:--start-group"
|
||||||
"LINKER:--end-group")
|
"LINKER:--end-group"
|
||||||
elseif(CMAKE_C_COMPILER_ID STREQUAL "SunPro"
|
)
|
||||||
AND CMAKE_SYSTEM_NAME STREQUAL "SunOS")
|
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"
|
set(CMAKE_C_LINK_GROUP_USING_cross_refs
|
||||||
"LINKER:-z,rescan-end")
|
"LINKER:-z,rescan-start"
|
||||||
|
"LINKER:-z,rescan-end"
|
||||||
|
)
|
||||||
else()
|
else()
|
||||||
# feature not yet supported for the other environments
|
# feature not yet supported for the other environments
|
||||||
set(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED FALSE)
|
set(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED FALSE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(lib1 STATIC ...)
|
add_library(lib1 STATIC ...)
|
||||||
|
add_library(lib2 SHARED ...)
|
||||||
|
|
||||||
add_library(lib3 SHARED ...)
|
|
||||||
if(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED)
|
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()
|
else()
|
||||||
target_link_libraries(lib3 PRIVATE lib1 external)
|
target_link_libraries(lib2 PRIVATE lib1 external)
|
||||||
endif()
|
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``
|
* ``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``
|
* ``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
|
||||||
|
@ -3,11 +3,10 @@ CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED
|
|||||||
|
|
||||||
.. versionadded:: 3.24
|
.. versionadded:: 3.24
|
||||||
|
|
||||||
Set to ``TRUE`` if the ``<FEATURE>``, as defined by variable
|
This variable specifies whether the ``<FEATURE>`` is supported regardless of
|
||||||
:variable:`CMAKE_LINK_GROUP_USING_<FEATURE>`, is supported regardless the
|
the link language. If this variable is true, then the ``<FEATURE>`` must
|
||||||
linker language.
|
be defined by :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>`.
|
||||||
|
|
||||||
.. note::
|
Note that this variable has no effect if
|
||||||
|
:variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` is true for
|
||||||
This variable is evaluated if, and only if, the variable
|
the link language of the target.
|
||||||
:variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` is not defined.
|
|
||||||
|
@ -3,31 +3,17 @@ CMAKE_LINK_LIBRARY_USING_<FEATURE>
|
|||||||
|
|
||||||
.. versionadded:: 3.24
|
.. versionadded:: 3.24
|
||||||
|
|
||||||
This variable defines, for the specified ``FEATURE``, the expression expected
|
This variable defines how to link a library or framework for the specified
|
||||||
by the linker, regardless the linker language, when libraries are specified
|
``<FEATURE>`` when a :genex:`LINK_LIBRARY` generator expression is used.
|
||||||
using :genex:`LINK_LIBRARY` generator expression.
|
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.
|
* There is no language-specific definition for the same ``<FEATURE>``.
|
||||||
* Feature names defined in all uppercase are reserved to CMake.
|
This means :variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED`
|
||||||
|
cannot be true for the link language used by the target for which the
|
||||||
See also the associated variable
|
:genex:`LINK_LIBRARY` generator expression is evaluated.
|
||||||
: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``.
|
|
||||||
|
|
||||||
.. include:: CMAKE_LINK_LIBRARY_USING_FEATURE.txt
|
.. include:: CMAKE_LINK_LIBRARY_USING_FEATURE.txt
|
||||||
|
|
||||||
Predefined Features
|
|
||||||
^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
CMake pre-defines some features of general interest:
|
|
||||||
|
|
||||||
.. include:: LINK_LIBRARY_PREDEFINED_FEATURES.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.
|
|
||||||
|
Feature Definitions
|
||||||
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
A library feature definition is a list that contains one or three elements:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
[<PREFIX>] <LIBRARY_EXPRESSION> [<SUFFIX>]
|
[<PREFIX>] <LIBRARY_EXPRESSION> [<SUFFIX>]
|
||||||
|
|
||||||
When ``<PREFIX>`` and/or ``<SUFFIX>`` are specified, they encapsulate the list
|
When ``<PREFIX>`` and ``<SUFFIX>`` are specified, they precede and follow
|
||||||
of libraries.
|
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.
|
||||||
|
|
||||||
.. note::
|
``<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:
|
||||||
|
|
||||||
Even if ``<PREFIX>`` and ``<SUFFIX>`` are specified, there is not guarantee
|
* ``<LIBRARY>`` is expanded to the full path to the library for CMake targets,
|
||||||
that the list of specified libraries, as part of :genex:`LINK_LIBRARY`
|
or to a platform-specific value based on the item otherwise (the same as
|
||||||
generator expression, will be kept grouped. So, constructs like
|
``<LINK_ITEM>`` on Windows, or the library base name for other platforms).
|
||||||
``start-group`` and ``end-group``, as supported by ``GNU ld``, cannot be
|
* ``<LINK_ITEM>`` is expanded to how the library would normally be linked on
|
||||||
used.
|
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.
|
||||||
|
|
||||||
``<LIBRARY_EXPRESSION>`` is used to specify the decoration for each
|
In addition to the above, it is possible to have one pattern for paths
|
||||||
library. For that purpose, the patterns ``<LIBRARY>``, ``<LINK_ITEM>``, and
|
(CMake targets and external libraries specified with file paths) and another
|
||||||
``<LIB_ITEM>`` are available:
|
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.
|
.. code-block:: 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.
|
|
||||||
|
|
||||||
Moreover, it is possible to have different decorations for paths (CMake targets
|
set(CMAKE_LINK_LIBRARY_USING_weak_library
|
||||||
and external libraries specified with absolute paths) and other items specified
|
"PATH{-weak_library <LIBRARY>}NAME{LINKER:-weak-l<LIB_ITEM>}"
|
||||||
by name. For that purpose, ``PATH{}`` and ``NAME{}`` wrappers can be used.
|
)
|
||||||
|
|
||||||
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
|
.. include:: ../command/LINK_OPTIONS_LINKER.txt
|
||||||
:start-line: 3
|
:start-line: 3
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
@ -41,19 +60,24 @@ Examples
|
|||||||
Loading a whole static library
|
Loading a whole static library
|
||||||
""""""""""""""""""""""""""""""
|
""""""""""""""""""""""""""""""
|
||||||
|
|
||||||
A common need is the capability to load a whole static library. This capability
|
A common need is to prevent the linker from discarding any symbols from a
|
||||||
is offered by various environments but with a specific syntax:
|
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
|
.. code-block:: cmake
|
||||||
|
|
||||||
set(CMAKE_C_LINK_LIBRARY_USING_load_archive_SUPPORTED TRUE)
|
set(CMAKE_C_LINK_LIBRARY_USING_load_archive_SUPPORTED TRUE)
|
||||||
if(CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
|
if(CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
|
||||||
set(CMAKE_C_LINK_LIBRARY_USING_load_archive "-force_load <LIB_ITEM>")
|
set(CMAKE_C_LINK_LIBRARY_USING_load_archive "-force_load <LIB_ITEM>")
|
||||||
elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU"
|
elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||||
AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
set(CMAKE_C_LINK_LIBRARY_USING_load_archive
|
||||||
set(CMAKE_C_LINK_LIBRARY_USING_load_archive "LINKER:--push-state,--whole-archive"
|
"LINKER:--push-state,--whole-archive"
|
||||||
"<LINK_ITEM>"
|
"<LINK_ITEM>"
|
||||||
"LINKER:--pop-state")
|
"LINKER:--pop-state"
|
||||||
|
)
|
||||||
elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
|
elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
|
||||||
set(CMAKE_C_LINK_LIBRARY_USING_load_archive "/WHOLEARCHIVE:<LIBRARY>")
|
set(CMAKE_C_LINK_LIBRARY_USING_load_archive "/WHOLEARCHIVE:<LIBRARY>")
|
||||||
else()
|
else()
|
||||||
@ -62,41 +86,45 @@ is offered by various environments but with a specific syntax:
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(lib1 STATIC ...)
|
add_library(lib1 STATIC ...)
|
||||||
|
|
||||||
add_library(lib2 SHARED ...)
|
add_library(lib2 SHARED ...)
|
||||||
|
|
||||||
if(CMAKE_C_LINK_LIBRARY_USING_load_archive_SUPPORTED)
|
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
|
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()
|
else()
|
||||||
target_link_libraries(lib2 PRIVATE lib1 external)
|
target_link_libraries(lib2 PRIVATE lib1 external)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
CMake will generate the following link expressions:
|
CMake will generate the following link expressions:
|
||||||
|
|
||||||
* ``Clang``: ``-force_load /path/to/lib1.a -force_load libexternal.a``
|
* ``AppleClang``: ``-force_load /path/to/lib1.a -force_load libexternal.a``
|
||||||
* ``GNU``: ``-Wl,--whole-archive /path/to/lib1.a -lexternal -Wl,--no-whole-archive``
|
* ``GNU``: ``-Wl,--push-state,--whole-archive /path/to/lib1.a -lexternal -Wl,--pop-state``
|
||||||
* ``MSVC``: ``/WHOLEARCHIVE:/path/to/lib1.lib /WHOLEARCHIVE:external.lib``
|
* ``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
|
Linking a library as weak
|
||||||
"""""""""""""""""""""""""
|
"""""""""""""""""""""""""
|
||||||
|
|
||||||
On MacOS, it is possible to link a library in weak mode (the library and all
|
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
|
references are marked as weak imports). Different flags must be used for a
|
||||||
library specified by path and by name. This constraint by be solved by using
|
library specified by file path compared to one specified by name.
|
||||||
``PATH{}`` and ``NAME{}`` wrappers:
|
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
|
.. code-block:: cmake
|
||||||
|
|
||||||
if (CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
|
if (CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
|
||||||
set(CMAKE_LINK_LIBRARY_USING_weak_library
|
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)
|
set(CMAKE_LINK_LIBRARY_USING_weak_library_SUPPORTED TRUE)
|
||||||
endif()
|
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)
|
target_link_libraries(main PRIVATE lib external)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
CMake will generate the following link expression:
|
CMake will generate the following linker command line fragment when linking
|
||||||
``-weak_library /path/to/lib -Xlinker -weak-lexternal``
|
``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
|
||||||
|
@ -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``
|
``RESCAN``
|
||||||
The specified static libraries are searched repeatedly until no
|
Some linkers are single-pass only. For such linkers, circular references
|
||||||
new undefined references are created. Normally, an static library is searched
|
between libraries typically result in unresolved symbols. This feature
|
||||||
only once in the order that it is specified on the command line. If a symbol
|
instructs the linker to search the specified static libraries repeatedly
|
||||||
in that library is needed to resolve an undefined symbol referred to by an
|
until no new undefined references are created.
|
||||||
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
|
Normally, a static library is searched only once in the order that it is
|
||||||
all be searched repeatedly until all possible references are resolved (use
|
specified on the command line. If a symbol in that library is needed to
|
||||||
linker options ``--start-group`` and ``--end-group`` or, on ``SunOS``,
|
resolve an undefined symbol referred to by an object in a library that
|
||||||
``-z rescan-start`` and ``-z rescan-end``).
|
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
|
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
|
only when there are unavoidable circular references between two or more
|
||||||
static libraries.
|
static libraries.
|
||||||
|
|
||||||
This feature is available on ``Linux``, ``BSD``, and ``SunOS`` target
|
This feature is available when using toolchains that target Linux, BSD, and
|
||||||
platforms as well as ``Windows`` when ``GNU`` toolchain is used.
|
SunOS. It can also be used when targeting Windows platforms if the GNU
|
||||||
|
toolchain is used.
|
||||||
|
@ -1,88 +1,96 @@
|
|||||||
**Features available in all environments**
|
|
||||||
|
|
||||||
``DEFAULT``
|
``DEFAULT``
|
||||||
This feature enables default link expression. This is mainly
|
This feature corresponds to standard linking, essentially equivalent to
|
||||||
useful with :prop_tgt:`LINK_LIBRARY_OVERRIDE` and
|
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.
|
:prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` target properties.
|
||||||
|
|
||||||
**Features available for a subset of environments**
|
|
||||||
|
|
||||||
``WHOLE_ARCHIVE``
|
``WHOLE_ARCHIVE``
|
||||||
Force load of all members in a static library.
|
Force inclusion of all members of a static library. This feature is only
|
||||||
|
supported for the following platforms, with limitations as noted:
|
||||||
|
|
||||||
Target platforms supported: all ``Apple`` variants, ``Linux``, all ``BSD``
|
* Linux.
|
||||||
variants, ``SunOS``, ``Windows``, ``CYGWIN``, and ``MSYS``.
|
* All BSD variants.
|
||||||
|
* SunOS.
|
||||||
Platform-specific notes:
|
* 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
|
||||||
* On Apple platforms, the library must be specified as a CMake target name, a
|
``/path/to/libfoo.a``). Due to a limitation of the Apple linker, it
|
||||||
library file name (such as ``libfoo.a``), or a library file path (such as
|
cannot be specified as a plain library name like ``foo``, where ``foo``
|
||||||
``/path/to/libfoo.a``). It cannot be specified as a plain library name
|
is not a CMake target.
|
||||||
(such as ``foo``, where ``foo`` is not CMake target), due to a limitation
|
* Windows. When using a MSVC or MSVC-like toolchain, the MSVC version must
|
||||||
in the Apple linker.
|
be greater than 1900.
|
||||||
* On Windows platforms, for ``MSVC`` or MSVC-like toolchains, the version
|
* Cygwin.
|
||||||
must be greater than ``1900``.
|
* MSYS.
|
||||||
|
|
||||||
**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
|
|
||||||
|
|
||||||
``FRAMEWORK``
|
``FRAMEWORK``
|
||||||
This option tells the linker to search for the specified
|
This option tells the linker to search for the specified framework using
|
||||||
framework (use linker option ``-framework``).
|
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.
|
||||||
|
|
||||||
``NEEDED_FRAMEWORK``
|
``NEEDED_FRAMEWORK``
|
||||||
This is the same as the ``FRAMEWORK`` feature but means
|
This is similar to the ``FRAMEWORK`` feature, except it forces the linker
|
||||||
to really link with the framework even if no symbols are used from it (use
|
to link with the framework even if no symbols are used from it. It uses
|
||||||
linker option ``-needed_framework``).
|
the ``-needed_framework`` option and has the same linker constraints as
|
||||||
|
``FRAMEWORK``.
|
||||||
|
|
||||||
``REEXPORT_FRAMEWORK``
|
``REEXPORT_FRAMEWORK``
|
||||||
This is the same as the ``FRAMEWORK`` feature but
|
This is similar to the ``FRAMEWORK`` feature, except it tells the linker
|
||||||
also specifies that all symbols in that framework should be available to
|
that the framework should be available to clients linking to the library
|
||||||
clients linking to the library being created (use linker option
|
being created. It uses the ``-reexport_framework`` option and has the
|
||||||
``-reexport_framework``).
|
same linker constraints as ``FRAMEWORK``.
|
||||||
|
|
||||||
``WEAK_FRAMEWORK``
|
``WEAK_FRAMEWORK``
|
||||||
This is the same as the ``FRAMEWORK`` feature but forces
|
This is similar to the ``FRAMEWORK`` feature, except it forces the linker
|
||||||
the framework and all references to it to be marked as weak imports (use
|
to mark the framework and all references to it as weak imports. It uses
|
||||||
linker option ``-weak_framework``).
|
the ``-weak_framework`` option and has the same linker constraints as
|
||||||
|
``FRAMEWORK``.
|
||||||
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:
|
|
||||||
|
|
||||||
* (/path/to/)?FwName(.framework)?
|
|
||||||
* (/path/to/)?FwName.framework/FwName
|
|
||||||
* (/path/to/)?FwName.framework/Versions/\*/FwName
|
|
||||||
|
|
||||||
Library support
|
|
||||||
|
|
||||||
``NEEDED_LIBRARY``
|
``NEEDED_LIBRARY``
|
||||||
This is the same as specifying a link item (target or
|
This is similar to the ``NEEDED_FRAMEWORK`` feature, except it is for use
|
||||||
library) but means to really link with the item even if no symbols are used
|
with non-framework targets or libraries (Apple platforms only).
|
||||||
from it (use linker option ``-needed_library`` or ``-needed-l``).
|
It uses the ``-needed_library`` or ``-needed-l`` option as appropriate,
|
||||||
|
and has the same linker constraints as ``NEEDED_FRAMEWORK``.
|
||||||
|
|
||||||
``REEXPORT_LIBRARY``
|
``REEXPORT_LIBRARY``
|
||||||
This is the same as specifying a link item (target or
|
This is similar to the ``REEXPORT_FRAMEWORK`` feature, except it is for use
|
||||||
library) but also specifies that all symbols in that item should be available
|
with non-framework targets or libraries (Apple platforms only).
|
||||||
to clients linking to the library being created (use linker option
|
It uses the ``-reexport_library`` or ``-reexport-l`` option as appropriate,
|
||||||
``-reexport_library`` or ``-reexport-l``).
|
and has the same linker constraints as ``REEXPORT_FRAMEWORK``.
|
||||||
|
|
||||||
``WEAK_LIBRARY``
|
``WEAK_LIBRARY``
|
||||||
This is the same as specifying a link item (target or
|
This is similar to the ``WEAK_FRAMEWORK`` feature, except it is for use
|
||||||
library) but forces the item and all references to it to be marked as weak
|
with non-framework targets or libraries (Apple platforms only).
|
||||||
imports (use linker option ``-weak_library`` or ``-weak-l``).
|
It uses the ``-weak_library`` or ``-weak-l`` option as appropriate,
|
||||||
|
and has the same linker constraints as ``WEAK_FRAMEWORK``.
|
||||||
|
Loading…
Reference in New Issue
Block a user