CMake子项目的覆盖策略

6

我的CMake项目编译一个Python .so/.dylib扩展模块,该模块链接了一个大型静态库。我希望为子项目的静态库编译使用隐藏的符号可见性:这将使链接器(或LTO优化器)丢弃由我的Python模块未使用的符号。

最好的方法是在子项目的静态库目标上使用 CXX_VISIBILITY_PRESET 和相关设置。

然而,子项目使用 3.1.0 版本的策略来声明:

cmake_minimum_required (VERSION 3.1.0)

策略 CMP0063 NEW: 为所有目标类型保留可见性属性。 只在版本3.3及以上引入,因此 set_target_properties 没有效果。

我的项目需要CMake 3.3,但我无法控制子项目。

我想避免对子项目的 CMakeLists.txt 进行打补丁,但目前我没有其他方法。

有任何想法吗?


你可以使用链接器标志CMAKE_STATIC_LINKER_FLAGS来替代使用属性。 - Tsyvarev
这是一个编译时选项。理想情况下,我会全局设置CXX_VISIBILITY_PRESET为“hidden”,然后set_target_properties(python_module PROPERTIES CXX_VISIBILITY_PRESET default)。有效地为声明私有符号的源设置了'-fvisibility=hidden'编译器标志。 - Piezoid
如果你确定子项目可以使用CMP0063策略,那么你可以替换子项目中的cmake_minimum_required函数,这样它就会启用给定的策略。参考这个答案了解CMake函数的替换方法。 - Tsyvarev
2个回答

12

cmake_minimum_required() 在 CMake 策略上有以下影响:

  • 所有在指定版本或之前引入的策略将被设置为使用 NEW 行为。
  • 所有在指定版本之后引入的策略将被取消设置。

但是,您可以使用 CMake 的CMAKE_POLICY_DEFAULT_CMP<NNNN> 全局变量来“默认为 CMake Policy CMP,否则它将保持未设置状态。”

以下是示例:

set(CMAKE_POLICY_DEFAULT_CMP0063 NEW)
add_subdirectory(MySubProjDir)

参考资料


0
你可以使用add_compile_option来指定适当的编译器选项。

目前,我在除了Python模块以外的所有目标上都使用target_compile_options(${TARGET_NAME} PRIVATE -fvisibility=hidden)。 正如标题所示,我更感兴趣的是一种通用方法,即从顶级项目的cmake_minimum版本中利用CMake功能(CMake语言中的策略),在需要较低版本的子项目中使用。 - Piezoid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接