We have a CMake project which adds link-options at the top-level via add_link_options
.
We use them for a lot of static-library-targets. We also have two special targets. Each of those two targets is built separately as an relocatable output module by an tiarmclang LTS2.1.2 TI-compiler. So they are partially linked. And get their final linking into the main-target.
This is achieved by not having the targets implemented with add_library
but with add_executable
.
Now it's important the targets won't use the top-level-link-options since those options would link the relocatable output module in a wrong way which makes problems later on.
They should either independently use their own defined link-options and drop the ones from above or at least it shall be possible to remove previous set link-options.
The setup is in minimal like this:
#top-level
add_link_options(
"-Wl,--reread_libs"
"-Wl,--ram_model" #should not be used in relocatable target
"-Wl,-e_vectors" #should not be used in relocatable target
"-Wl,--diag_suppress=10063"
)
#main-target
add_executable(main-target
#some sources here
)
target_link_libraries(main-target PUBLIC
relocatable-target
)
target_link_options(main-target PRIVATE
#some additional link-options like map-file and so on
)
#relocatable target
add_executable(relocatable-target
#some sources here
)
set_target_properties(relocatable-target PROPERTIES SUFFIX ".out"
ENABLE_EXPORTS on
)
target_link_options(relocatable-target PRIVATE
#separate link-options here
)
I may remove the problematic link-options from the top-level add_link-options
but then the logical relation is the wrong way: the main-target needs to do changes because of a target way below. That's not how it should work.
I thought that since the add_executable
signifies: "Hey I am a separate running entity" CMake would automatically not use the top-level-linker-options. Is there a way to do this?
I did not find any solution for this problem. I found some hundreds of lines of CMake-macros for compile-options to achieve something similar but that could not be the solution.
As already mentioned in the comments, it doesn't make sense that you're using add_linker_options
for static library targets. From the add_link_options
docs:
Note: This command cannot be used to add options for static library targets, since they do not use a linker. To add archiver or MSVC librarian flags, see the
STATIC_LIBRARY_OPTIONS
target property.
But putting that aside for the sake of discussion, to answer the question in general about how to remove linker flags added by add_link_options
: The docs of add_link_options
says:
This command can be used to add any link options, but alternative commands exist to add libraries (
target_link_libraries()
orlink_libraries()
). See documentation of the directory and target LINK_OPTIONS properties.
If you look at the docs pointed to for the directory property, you'll see that it says:
This property holds a semicolon-separated list of options given so far to the
add_link_options()
command.This property is used to initialize the
LINK_OPTIONS
target property when a target is created, which is used by the generators to set the options for the compiler.
So you just need to read out the value of your target's LINK_OPTIONS
property into a CMake variable, modify the CMake variable to remove that option, and then write the value of the CMake variable back into the target property. For example:
add_link_options("-foo" "-remove-me" "-bar" "-baz")
add_library(mytarget SHARED foo.cpp)
get_target_property(mytarget_LINK_OPTIONS mytarget LINK_OPTIONS)
message("mytarget_LINK_OPTIONS: ${mytarget_LINK_OPTIONS}") # original value
list(REMOVE_ITEM mytarget_LINK_OPTIONS "-remove-me")
message("mytarget_LINK_OPTIONS: ${mytarget_LINK_OPTIONS}") # modified value
set_target_properties(mytarget PROPERTIES LINK_OPTIONS "${mytarget_LINK_OPTIONS}")
get_target_property(mytarget_LINK_OPTIONS mytarget LINK_OPTIONS)
message("mytarget_LINK_OPTIONS: ${mytarget_LINK_OPTIONS}") # written-back value
, which will print the following during configuration:
mytarget_LINK_OPTIONS: -foo;-remove-me;-bar;-baz
mytarget_LINK_OPTIONS: -foo;-bar;-baz
mytarget_LINK_OPTIONS: -foo;-bar;-baz
Another potential option (I have not verified) could be to set a custom target property on those special targets that indicates it doesn't want those link options, and then wrap your special general add_link_options
options with a target property generator expression.