mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-06 05:40:54 -06:00
113 lines
4.1 KiB
Plaintext
113 lines
4.1 KiB
Plaintext
|
|
It can contain one or three elements.
|
|
|
|
::
|
|
|
|
[<PREFIX>] <LIBRARY_EXPRESSION> [<SUFFIX>]
|
|
|
|
When ``<PREFIX>`` and/or ``<SUFFIX>`` are specified, they encapsulate the list
|
|
of libraries.
|
|
|
|
.. 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.
|
|
|
|
``<LIBRARY_EXPRESSION>`` is used to specify the decoration for each
|
|
library. For that purpose, the patterns ``<LIBRARY>``, ``<LINK_ITEM>``, and
|
|
``<LIB_ITEM>`` are available:
|
|
|
|
* ``<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.
|
|
|
|
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.
|
|
|
|
For all three elements of this variable, the ``LINKER:`` prefix can be used:
|
|
|
|
.. include:: ../command/LINK_OPTIONS_LINKER.txt
|
|
:start-line: 3
|
|
|
|
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:
|
|
|
|
.. 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 "MSVC")
|
|
set(CMAKE_C_LINK_LIBRARY_USING_load_archive "/WHOLEARCHIVE:<LIBRARY>")
|
|
else()
|
|
# feature not yet supported for the other environments
|
|
set(CMAKE_C_LINK_LIBRARY_USING_load_archive_SUPPORTED FALSE)
|
|
endif()
|
|
|
|
add_library(lib1 STATIC ...)
|
|
|
|
add_library(lib2 SHARED ...)
|
|
if(CMAKE_C_LINK_LIBRARY_USING_load_archive_SUPPORTED)
|
|
target_link_libraries(lib2 PRIVATE
|
|
"$<LINK_LIBRARY:load_archive,lib1,$<IF:$<LINK_LANG_AND_ID:C,Clang>,libexternal.a,external>>")
|
|
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``
|
|
* ``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:
|
|
|
|
.. 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>}")
|
|
set(CMAKE_LINK_LIBRARY_USING_weak_library_SUPPORTED TRUE)
|
|
endif()
|
|
|
|
add_library(lib SHARED ...)
|
|
add_executable(main ...)
|
|
if(CMAKE_LINK_LIBRARY_USING_weak_library_SUPPORTED)
|
|
target_link_libraries(main PRIVATE "$<LINK_LIBRARY:weak_library,lib,external>")
|
|
else()
|
|
target_link_libraries(main PRIVATE lib external)
|
|
endif()
|
|
|
|
CMake will generate the following link expression:
|
|
``-weak_library /path/to/lib -Xlinker -weak-lexternal``
|