Add flag(s) to link library or group of libraries
For some time now, multiple issues were raised (#16947 (closed), #18751 (closed), #20078 (closed), #21511 (closed)) for the impossibility to reliably specify some "decoration" to a library or group of libraries during link phase.
Currently, using target_link_libraries()
command, it is only possible, in a safe and reliable way, to specify raw
libraries (by raw
, I mean library names without any "decoration"). It is required to offer a way to specify some "decorations" of libraries. Different needs are identified:
- Specifying a prefix to the lib:
-weak_library <lib>
or-force_load=<lib>
- Specifying a prefix and suffix to the lib:
--whole-archive <lib> --no-whole-archive
- Specifying an indivisible group of libs:
-start-group <lib1>,<lib2> -end-group
Moreover, depending on the effective linker language used, the same feature can require a different syntax.
A possible solution is now identified based on the following elements:
- Specification of the effective syntax for the library decoration.
For that purpose a variable can be defined capturing language specific syntax for each feature. Two syntaxes can be supported to handle the various cases described above:
# case 1: prefix
set(CMAKE_CXX_WEAK_LIBRARY "-weak_library <LIBRARY>")
set(CMAKE_CXX_FORCE_LOAD "-force_load=<LIBRARY>")
# case 2
set(CMAKE_CXX_WHOLE_ARCHIVE "-whole-archive <LIBRARY> -no-whole-archive")
# or if multiple libraries can be specified for this option
set(CMAKE_CXX_WHOLE_ARCHIVE "-whole-archive " "<LIBRARY>" " -no-whole-archive" " ")
# case 3
set(CMAKE_CXX_GROUP "-start-group " "<LIBRARY>" " -end-group" ",")
the variable has the following syntax:
CMAKE_<LANG>_<FEATURE>
and it can contain one element used to generate final syntax for each library or 3 or 4 elements:
<PREFIX> <LIBRARY_ITEM> <SUFFIX> [<SEPARATOR>]
In this case the prefix and suffix encapsulate the list of libraries. If the <SEPARATOR>
is not specified, a space is used.
And to finish, pattern <LIBRARY>
can be used as a placeholder for the final library name.
I hope this syntax is flexible enough to handle any syntax required by various compilers/linkers. Moreover, by externalizing the definition, we get a portable way to specify libraries behaviors (most common cases can be part of CMake
product) and it is easy for the users to extend this for any special need.
- Specification of libraries as part of link step.
We can rely on some generator expression, for example $<LINK_LIBRARY:...>
. Moreover, this approach make sense because the effective syntax cannot be identified until the generation because it depends on the effective linker language.
add_library(X ...)
add_library(Y ...)
target_link_libraries(Y PRIVATE $<LINK_LIBRARY:WEAK_LIBRARY,X>)
The syntax of the genex is $<LINK_LIBRARY:behavior,list of libraries>
. The behavior argument will be used to identify the variable specifying the syntax.
And for a group of libraries:
add_library(A ...)
add_library(B ...)
add_library(C ...)
add_library(Y ...)
target_link_libraries(Y PRIVATE $<LINK_LIBRARY:GROUP,A;B;C>)
Based on this proposition, Multiple design choices must be done for the various cases. This is the goal of this issue.