Reputation: 315
Say I have a final executable called exec and I need to link it with 2 shared libraries - libA and libB. For libA I would like to pass some linker flag, the other library I would prefer not to.
This is how my simplified CMakeLists.txt file looks like at the moment:
add_executable(exec
main.cpp
)
target_link_libraries(exec
PRIVATE
libA
libB
)
target_link_options(exec PRIVATE "-Wl,--no-as-needed")
Right now CMake will treat it as if I passed --no-as-needed option to both libraries.
I want to achieve this very strict order:
-Wl,-no-as-needed -llibA -Wl,-as-needed -llibB
From what I know CMake does not guarantee that libraries will be passed to linker in the order they're written in target_link_libraries as the order can change if it results from depencencies so I cannot write:
target_link_libraries(exec
PRIVATE
"-Wl,-no-as-needed"
libA
"-Wl,-as-needed"
libB
)
Upvotes: 1
Views: 4578
Reputation: 336
You are right in the assumption that CMake does not guarantee ordering of linker flags. Additionally, duplicate entries are used only once.
To solve it, you can use target_link_options instead of target_link_librares
in combination with SHELL:
prefix. This prefix allows you to create a group of linker flags that will not change order within the group.
It will get more complicated if libA is a CMake target, in which case target_link_libraries( exec PRIVATE libA )
will generate something more compilicated than just -llibA
. The most straightforward solution there would be to modify definition of target libA
to already include the flag with the SHELL:
prefix. But this does not seem to be your case.
So the solution is:
target_link_options( exec PRIVATE "SHELL:-Wl,-no-as-needed -llibA" )
target_link_options( exec PRIVATE "SHELL:-Wl,-as-needed -llibB" )
This can generate either -Wl,-no-as-needed -llibA -Wl,-as-needed -llibB
or -Wl,-as-needed -llibB -Wl,-no-as-needed -llibA
.
Upvotes: 3