C++ GCC符号可见性支持相关配置及使用问题咨询
为什么要求同时修饰源文件中的定义?
- 这是最佳实践而非语法强制要求:如果编译库时开启了
-fvisibility=hidden选项,所有符号默认隐藏。只要源文件编译时正确包含了带可见性修饰的头文件,函数定义会自动继承声明的可见性属性,不需要额外修饰。 - 要求同时修饰是为了规避人为失误:如果源文件写函数定义时漏了对应头文件的引入,定义的可见性就会变成默认的隐藏,最终导致要么库导出符号缺失,要么链接时报符号找不到的错误。两处都加修饰可以保证可见性属性一致,避免这类排查成本很高的问题。
此处必须使用extern的原因是什么?
- 此处的
extern不是强制要求,只是文档写法更严谨的体现:全局函数默认本身就是外部链接属性,加extern只是显式强调这一属性。 - 加
extern有两个兼容层面的作用:一是统一函数和变量的导出写法(导出全局变量时必须加extern才能正确标记符号属性),二是兼容不同编译器的行为差异,比如部分旧版MSVC在某些场景下导出函数不加extern会产生不必要的警告。
CMake中FOX_DLL应该在什么位置、如何定义?
FOX_DLL只需要在编译动态库自身的时候定义,用户链接使用你的库时不需要定义该宏,因此推荐用CMake的目标私有编译定义配置,写法如下:
# 假设你的动态库目标名为 fox add_library(fox SHARED src/fox_impl.cpp src/tool.cpp include/fox.h ) # 仅在编译fox库自身时定义FOX_DLL,不会传递给依赖fox的其他目标 target_compile_definitions(fox PRIVATE FOX_DLL)
如果你的项目需要同时支持编译为静态库和动态库,可以用生成器表达式自动适配:
target_compile_definitions(fox PRIVATE $<$<STREQUAL:$<TARGET_PROPERTY:fox,TYPE>,SHARED>:FOX_DLL> )
这样CMake会自动判断当前编译目标类型,只有编译为动态库时才会添加FOX_DLL定义。
内容的提问来源于stack exchange,提问作者Ingo
相关产品推荐
相关产品推荐

