【问题标题】:CMake: setting a linker flag on a static library, to be used by the consumer when linking (Visual Studio)CMake:在静态库上设置链接器标志,供消费者在链接时使用(Visual Studio)
【发布时间】:2015-10-22 21:15:09
【问题描述】:

我有以下情况:一个静态库MyStaticLib依赖于FFmpeg项目的几个库(libavformat等)。

FFmpeg 库是用“/SAFESEH:NO”选项链接的(不是我),这意味着链接到它们的任何图像(通过它们的导入库)也必须用相同的选项链接(失败所以使链接器中止“LNK2026:模块对 SAFESEH 图像不安全”)。

我已经尝试了所有我能想到的方法,但我还没有找到一种方法可以将该选项附加到我的 MyStaticLib 以使其传播给消费者。

这看起来很奇怪,因为 CMake 确实提供了将 编译器 选项传播给消费者的方法:与 PUBLIC 选项一起使用的命令 target_compile_options() 正是这样做的。

链接器标志没有类似的功能吗?

【问题讨论】:

  • 根据这个mail,它打算使用target_link_libraries(MyStaticLib INTERFACE "/SAFESEH:NO")来传播链接器标志,或者直接设置INTERFACE_LINK_LIBRARIES属性。但是 CMake 错误地使用该属性中的“/”符号:它假定该属性是 Windows 上的路径,并将“/”替换为“\”。
  • 感谢@Tsyvarev,这证实了我的想法。你知道 CMake 维护者是否意识到这一点?
  • 我不知道。使用“windows slash”搜索 cmake bugtracker 未发现与给定问题相关的任何问题。所以,你可以填一个。 cmake 可能的解决方案可能是将字符 '/' 替换为 '\' 仅当它不是第一个时。据我所知,与类 UNIX 系统不同,字符串 \bla-bla-bla 不能表示 Windows 上的路径。

标签: c++ visual-c++ linker cmake


【解决方案1】:

VC++ compiler 和 linker 都接受 正斜杠 (/) 和破折号 (–) 作为选项说明符。 作为mentioned by @tsyvarev,CMake 可能存在正斜杠问题,将其视为路径分隔符。 因此,您需要使用以下命令将链接器选项添加到 MyStaticLib 目标并将该选项传播给 MyStaticLib 使用者:

target_link_libraries(MyStaticLib PUBLIC "-SAFESEH:NO")

或者如果您的构建配置也支持其他编译器:

target_link_libraries(MyStaticLib PUBLIC "$<$<CXX_COMPILER_ID:MSVC>:-SAFESEH:NO>")

【讨论】:

    【解决方案2】:

    从 CMake 3.13 开始,您需要改用 target_link_options():

    target_link_options(${CMAKE_PROJECT_NAME} PUBLIC "$<$<C_COMPILER_ID:MSVC>:-SAFESEH:NO>")
    

    使用 CMake 3.16.2 和 MSVC2019 测试。

    【讨论】:

    • 根据CMake documentation,target_link_options() 只是target_link_libraries() 的替代品,它不是推荐的替代品。另请注意target_link_options()“不能用于为静态库目标添加选项,因为它们不使用链接器”。
    猜你喜欢
    • 2016-02-25
    • 2011-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多