怎么从CMake的目标中移除一个链接选项?

huangapple go评论72阅读模式
英文:

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

huangapple
  • 本文由 发表于 2023年3月31日 18:03:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/75897234.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定