控制共享库的导出符号时,与“gcc -fvisibility=hidden”等效的 CMake 是啥?

Posted

技术标签:

【中文标题】控制共享库的导出符号时,与“gcc -fvisibility=hidden”等效的 CMake 是啥?【英文标题】:What is the CMake equivalent to "gcc -fvisibility=hidden" when controlling the exported symbol of a shared library?控制共享库的导出符号时,与“gcc -fvisibility=hidden”等效的 CMake 是什么? 【发布时间】:2013-06-09 11:20:40 【问题描述】:

我用 C++ 开发了跨平台软件。据我所知,Linux .so默认导出所有符号,通过"gcc -fvisibility=hidden"我可以将所有导出的符号设置为隐藏,然后为我要导出的类和函数设置__attribute__(visibility("default")),这样我就可以控制我的想要导出。

我的问题是,使用 CMake,我怎样才能将工作作为“gcc -fvisibility=hidden”控制?

【问题讨论】:

【参考方案1】:

你可以像这样向 Cmake 编译器添加一个标志:

set(CMAKE_C_FLAGS "$CMAKE_C_FLAGS -fvisibility=hidden")

为确保这仅在 Linux 下完成,您可以使用以下代码:

if(UNIX AND CMAKE_COMPILER_IS_GNUCC)
    set(CMAKE_C_FLAGS "$CMAKE_C_FLAGS -fvisibility=hidden")
endif()

【讨论】:

事实上,-fvisibility=hidden 也可以与 clang 一起使用,因此如果您希望能够同时使用具有此功能的两个编译器,您可以使用类似:IF ("$CMAKE_CXX_COMPILER_ID" STREQUAL "GNU" OR "$CMAKE_CXX_COMPILER_ID" STREQUAL "Clang") ... ENDIF()【参考方案2】:

您应该使用当前的 CMake 版本和 <LANG>_VISIBILITY_PRESET 属性,而不是直接设置编译器标志。这样,您可以避免 CMakeLists 中的编译器细节并提高跨平台适用性(避免支持 GCC 而不是 Clang 等错误)。

即,如果您使用 C++,您可以调用 set(CMAKE_CXX_VISIBILITY_PRESET hidden) 全局设置属性,或set_target_properties(MyTarget PROPERTIES CXX_VISIBILITY_PRESET hidden) 将设置限制为特定库或可执行目标。如果您使用 C,只需在上述命令中将 CXX 替换为 C。您可能还想调查VISIBLITY_INLINES_HIDDEN 属性。

GENERATE_EXPORT_HEADER 的文档包含与这两个属性相关的更多提示和示例。

【讨论】:

我找不到任何合适的例子。你能详细说明一下吗?我的猜测是 c++ SET_TARGET_PROPERTIES(mytarget CXX_VISIBILITY_PRESET hidden) @Abai 添加了更多详细信息

以上是关于控制共享库的导出符号时,与“gcc -fvisibility=hidden”等效的 CMake 是啥?的主要内容,如果未能解决你的问题,请参考以下文章

当另一个库具有相同的符号时,gdb 不显示来自共享库的符号

共享库的外部符号如何在主程序中解析?

需要在 GDB 中加载共享库的调试符号

共享库

导出符号意味着什么?

CMake、SWIG 和共享库