CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>¶
New in version 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 LINK_LIBRARY
generator expression.
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
CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED
and
CMAKE_LINK_LIBRARY_USING_<FEATURE>
variable for the definition of
features independent from the link language.
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 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:
To pass options to the linker tool, each compiler driver has its own syntax. The
LINKER:
prefix and,
separator can be used to specify, in a portable way, options to pass to the linker tool.LINKER:
is replaced by the appropriate driver option and,
by the appropriate driver separator. The driver prefix and driver separator are given by the values of theCMAKE_<LANG>_LINKER_WRAPPER_FLAG
andCMAKE_<LANG>_LINKER_WRAPPER_FLAG_SEP
variables.For example,
"LINKER:-z,defs"
becomes-Xlinker -z -Xlinker defs
forClang
and-Wl,-z,defs
forGNU GCC
.The
LINKER:
prefix can be specified as part of aSHELL:
prefix expression.The
LINKER:
prefix supports, as an alternative syntax, specification of arguments using theSHELL:
prefix and space as separator. The previous example then becomes"LINKER:SHELL:-z defs"
.Note
Specifying the
SHELL:
prefix anywhere other than at the beginning of theLINKER:
prefix is not supported.
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:
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:
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
Predefined Features¶
CMake pre-defines some features of general interest:
Features available in all environments
DEFAULT
This feature enables default link expression. This is mainly useful with
LINK_LIBRARY_OVERRIDE
andLINK_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
, allBSD
variants,SunOS
,Windows
,CYGWIN
, andMSYS
.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 asfoo
, wherefoo
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 than1900
.
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
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
).
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 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.
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
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
).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
).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
).