【问题标题】:Boost undefined symbol when building .so library with CMake使用 CMake 构建 .so 库时提升未定义符号
【发布时间】:2021-11-06 22:19:50
【问题描述】:

我正在使用 Boost 1.75.0 的 CMake 在 Linux 上构建一个共享库 (.so)。

在CMakeLists.txt中,Boost的添加方式如下:

find_package(Boost REQUIRED COMPONENTS system chrono filesystem date_time log iostreams program_options)

并添加到目标:

target_link_libraries(mytarget PUBLIC ${Boost_LIBRARIES})

CMake 找到了 Boost,所以这里没问题。

Boost 作为静态库链接。当我列出链接的目标文件时,我得到了正确的库:

-- LIB_FILES: ...;/path/to/boost/debug/lib/libboost_filesystem.a;...

库编译和链接没有错误。

但是,当我使用库的简单功能时,我收到以下错误:

undefined symbol: _ZNK5boost10filesystem16filesystem_error4whatEv

这个符号在库中确实是未定义的:

$ nm -g libmytarget.so | grep _ZNK5boost10filesystem16filesystem_error4whatEv
                 U _ZNK5boost10filesystem16filesystem_error4whatEv

解构后的名称为boost::filesystem::filesystem_error::what() const,在boost/filesystem/exception.hpp中定义为

namespace boost
{
  namespace filesystem
  {
    class BOOST_FILESYSTEM_DECL filesystem_error : public std::exception
    {
    public:
      virtual const char * what() const throw();
...

请注意,我的代码调用此方法。

符号在libboost_filesystem.a中定义,供链接器使用,作为文本(代码)部分的符号:

$ nm -g /path/to/boost/debug/lib/libboost_filesystem.a | grep _ZNK5boost10filesystem16filesystem_error4whatEv
00000000000003fa T _ZNK5boost10filesystem16filesystem_error4whatEv

我的问题

我不明白这个符号怎么可能在编译库中未定义,当它存在于静态链接库(文件libboost_filesystem.a)中时,它被链接器识别和使用。

【问题讨论】:

  • 不确定你的编译器标志是什么样的,但这听起来很像我见过的问题, -flto 和 -fdevirtualize 不能很好地与 gcc pre 9.0 一起使用。
  • @JohnIlacqua 我正在使用 g++ 10.3.0

标签: c++ linux boost cmake


【解决方案1】:

在 CMake 中启用 INTERPROCEDURAL_OPTIMIZATION 解决了这个问题:

set_target_properties(mytarget PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)

现在,符号已正确链接:

$ nm -g libmytarget.so | grep filesystem_error4what
00000000001cfe22 T _ZNK5boost10filesystem16filesystem_error4whatEv

但我仍然不知道幕后发生了什么以及为什么会首先弹出此错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-14
    • 2021-07-08
    • 2022-10-25
    • 1970-01-01
    • 2017-05-18
    • 2020-03-01
    • 2017-05-10
    • 1970-01-01
    相关资源
    最近更新 更多