【发布时间】:2019-12-05 22:24:12
【问题描述】:
我们有一个多项目 cmake 设置,其中包括一些 IMPORTED 静态库。对于我们的其中一个可执行文件,我们需要强制链接其中一些IMPORTED 库中的所有符号,因此我们需要在该库的名称之前将-Wl,-force_load 传递给编译器。请注意,这些导入的库之间存在依赖关系,因此需要在链接命令行中以正确的顺序放置它们。这些依赖关系通过set_target_properties(fake_2 PROPERTIES INTERFACE_LINK_LIBRARIES ...) 在根CMakeLists.txt 中声明。
我们使用的是相当标准的target_link_libraries(lib_a PUBLIC -Wl,-force_load fake_4),但事实证明,cmake 将-Wl,-force_load 视为一个相当随意的链接器标志,如果您将其应用于多个库,例如:
target_link_libraries(lib_a PUBLIC -Wl,-force_load fake_4)
target_link_libraries(lib_a PUBLIC -Wl,-force_load fake_3)
不必将这些链接器标志应用于fake_4 和fake_3。在某些情况下,它会删除该标志并将其仅应用于其中一个库。尝试解决这个问题
target_link_libraries(lib_a PUBLIC "-Wl,-force_load $<TARGET_PROPERTY:fake_4,IMPORTED_LOCATION>")
导致链接器标志被放置在库之前,但随后 cmake 无法识别导入的库,因此它忽略了它们之间的依赖关系。
可以在此处找到展示这些问题的完整示例项目:https://github.com/REVLUTION/cmake-example
注意:如果您想查看那里的一些 cmets,这是从 cmake discussion forums 移出的。
【问题讨论】:
-
AFAIK
-force_load为链接到应用程序的动态库进行降神会(默认情况下,dll-s 是延迟加载的)。静态库只是成为可执行文件的一部分,因此它们没有单独的“加载”。 -
通常当您链接静态库时,仅保留在其他代码中使用的符号。
-force_load告诉编译器包括所有符号,即使它们似乎没有被使用。这对于 TensorFlow 之类的东西是必要的,因为在编译时无法知道将要调用的函数集。