Skip to content

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:

  1. Specifying a prefix to the lib: -weak_library <lib> or -force_load=<lib>
  2. Specifying a prefix and suffix to the lib: --whole-archive <lib> --no-whole-archive
  3. 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:

  1. 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.

  1. 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.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information