CMake构建.so共享库链接静态Boost时出现undefined symbol未定义符号问题
问题根因
出现该问题的核心原因通常是以下三类:
- 编译你的项目代码时定义了Boost动态链接相关的宏,导致编译器标记该符号需要从外部动态库导入,哪怕链接了静态库也不会解析该符号
- 你使用的Boost静态库编译时未添加
-fPIC参数,无法合并到位置无关的共享库中,链接器自动跳过了对应的符号定义 - 链接器默认的
--as-needed策略未识别到该虚函数的隐式引用,未将静态库中对应的符号打包到共享库中
你没有主动调用该方法仍出现符号引用的原因是:boost::filesystem::filesystem_error::what() const是虚函数,只要你的代码调用了任何可能抛出filesystem_error异常的Boost.Filesystem接口,编译器生成的虚函数表就会包含该方法的地址引用,属于隐式依赖。
解决方案
按优先级依次尝试以下方案即可解决:
- 显式指定Boost静态链接宏
在CMakeLists.txt中给你的目标添加静态链接标记,避免Boost头文件自动识别为动态导入:
target_compile_definitions(mytarget PRIVATE BOOST_ALL_STATIC_LINK)
如果只需要针对Filesystem组件设置,可以替换为BOOST_FILESYSTEM_STATIC_LINK。
- 重新编译带-fPIC的Boost静态库
编译Boost静态库时添加位置无关代码编译参数,确保可以合并到共享库中:
./bootstrap.sh ./b2 cxxflags=-fPIC link=static --with-system --with-chrono --with-filesystem --with-date_time --with-log --with-iostreams --with-program_options install
编译完成后替换你之前使用的Boost静态库即可。
- 强制链接器打包所有Boost静态库符号
如果前两个方案无效,可以强制链接器将所有Boost静态库的目标文件合并到你的共享库中,忽略默认的按需引用策略:
target_link_libraries(mytarget PUBLIC -Wl,--whole-archive ${Boost_LIBRARIES} -Wl,--no-whole-archive )
内容的提问来源于stack exchange,提问作者WolfgangP
相关产品推荐
相关产品推荐

