英文:
How can I remove a link option from a target in CMake?
问题
代码部分不翻译,以下是翻译的内容:
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 a relocatable output module by a 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.
英文:
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.
答案1
得分: 2
如评论中已经提到的,对于静态库目标使用 add_linker_options
是没有意义的。根据 add_link_options
文档:
> 注意:此命令不能用于为静态库目标添加选项,因为它们不使用链接器。要添加归档程序或 MSVC 库管理器标志,请参阅 STATIC_LIBRARY_OPTIONS
目标属性。
但为了讨论,暂且将这个问题放在一边,一般来说,要回答关于如何移除 add_link_options
添加的链接器标志的问题:add_link_options
的文档中说:
> 此命令可用于添加任何链接选项,但也存在其他命令用于添加库(target_link_libraries()
或 link_libraries()
)。请参阅 目录 和 目标 LINK_OPTIONS 属性的文档。
如果查看指向目录属性的文档,你会看到:
> 此属性保存到目前为止通过 add_link_options()
命令给出的选项的 分号分隔的列表。
>
> 此属性用于在创建目标时初始化 LINK_OPTIONS
目标属性,生成器使用它来设置编译器的选项。
因此,你只需将你的目标的 LINK_OPTIONS
属性 的值 读取出来 到一个 CMake 变量中,修改 CMake 变量以移除该选项,然后将 CMake 变量的值写回目标属性。例如:
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}") # 原始值
list(REMOVE_ITEM mytarget_LINK_OPTIONS "-remove-me")
message("mytarget_LINK_OPTIONS: ${mytarget_LINK_OPTIONS}") # 修改后的值
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}") # 写回的值
这将在配置期间打印以下内容:
mytarget_LINK_OPTIONS: -foo;-remove-me;-bar;-baz
mytarget_LINK_OPTIONS: -foo;-bar;-baz
mytarget_LINK_OPTIONS: -foo;-bar;-baz
英文:
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()
or link_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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论