【问题标题】:g++ undefined reference error when linking to third party shared libraries链接到第三方共享库时出现 g++ 未定义的引用错误
【发布时间】:2017-09-27 21:02:52
【问题描述】:

我正在尝试链接一个使用来自第三方的多个共享库的 c++ 程序。主要是,这些库来自一个名为 MBSim 的 github 项目,我下载了最新的每日构建及其所有二进制文件、库和头文件,我安装在 /usr/local/mbsim-env 上。

最重要的库是libmbsimlibopenmbvcppinterfacelibfmatveclibboost_filesystem(最后一个是MBSim 发行版附带的)。

我设置了一个简单的代码来测试它,它的编译就像一个魅力使用

    g++ main.cpp -m64 -g3 -std=c++11 -Wall 
              -Wfatal-errors -Werror -Wno-unknown-pragmas -fopenmp 
              `pkg-config --cflags mbsim` -I. -c -o main.o

pkg-config 部分调用,您可能想知道,包含目录和标志:

    -DHAVE_ANSICSIGNAL -DHAVE_OPENMBVCPPINTERFACE -DHAVE_BOOST_FILE_LOCK
    -I/usr/local/mbsim-env/include 
    -I/usr/include/x86_64-linux-gnu
    -I/usr/include/x86_64-linux-gnu/c++/5 
    -I/usr/local/include

当我尝试将对象与预编译库链接时出现问题:

    g++ system.o main.o -o teste -L/usr/local/mbsim-env/lib 
                  -lmbsim -lopenmbvcppinterface -lboost_system 
                  -lfmatvec -lm 
                  -Wl,-rpath,/usr/local/mbsim-env/lib

编辑: 在上述命令中,我也尝试使用pkg-config --libs。结果保持不变。

首先,链接器会发出警告,指出我正在链接旧的 bo​​ost 库:

    /usr/bin/ld: warning: libboost_system.so.1.53.0,
                 needed by /usr/local/mbsim-env/lib/libmbsim.so, 
                 may conflict with libboost_system.so.1.61.0

我知道这一点,但我有意链接旧版本,因为那是用于编译 MBSim 库的版本。

在那之后,我从 MBSim 调用的几乎每个方法都收到了几个 undefined reference 警告:

    system.cpp:59: undefined reference to
       MBSim::RigidBody::RigidBody(std::__cxx11::basic_string<char,
       std::char_traits<char>, std::allocator<char> > const&)'

在我看来,这个错误意味着目标库没有实现RigidBody 方法。嗯,我知道他们会这样做。

我的第一个猜测是链接器可能正在查看错误的库路径,所以我设置了LD_LIBRARY_PATH=/usr/local/mbsim-env/lib 并将-rpath 添加到同一个文件夹中。这根本没有帮助。

一些谷歌搜索告诉我问题可能是在 64 位编译并将其与 32 位库链接。我相信情况并非如此:我在 Ubuntu 16.04 64 位上完成了所有工作,MBSim 库也是 64 位。

有人能指出我走出这个死胡同吗?

【问题讨论】:

  • 链接时也使用pkg-config --libs
  • @BasileStarynkevitch,我也这样做了。我编辑了原始问题以包含该信息。
  • MBSim 似乎想要一条与/usr/local/mbsim-env不同的路径
  • @Ripi2 你的意思是它是用不同的路径硬编码的?可能会跳转到原始编译网站?
  • 我不知道。这是 MBSim 的决定。他们是否有一个 make 或 cmake 脚本,您可以查看搜索提示?

标签: c++ linux linker


【解决方案1】:

难道您的第 3 方共享库是使用旧版本的 GCC 编译的? GCC 5 中引入了一个新的 ABI。它可能在您的平台上默认启用。见https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html

您可以尝试切换到旧 ABI,但这可能需要您的其他库也已使用旧 ABI 编译。您也许还可以显式地为第 3 方库切换 ABI。

【讨论】:

  • 谢谢@any1,解决了这个问题。我在编译命令中添加了-D_GCLIBXX_USE_CXX11_ABI=0,对std::__cxx11::basic_string 方法的未定义引用消失了。
【解决方案2】:

MBSim::RigidBody::RigidBody(std::__cxx11::basic_string&lt;std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;)的未定义引用

这是对MBSim::RigidBody::RigidBody(const string&amp;) 的引用,使用g++ -std=c++11g++ 版本5 或更高版本编译。

any1 可能猜对了,您下载的 libmbsim.so 的二进制文件是使用 g++ 4.x 构建的,并使用此签名定义了相同的函数:

MBSim::RigidBody::RigidBody(std::basic_string<char, std::char_traits<char>,
                                              std::allocator<char> > const&)

注意缺少__cxx11 命名空间。您可以轻松地确认或反驳这一点:

nm -C libmbsim.so | grep 'MBSim::RigidBody::RigidBody'

如果确实是这种不匹配的原因,只需使用你的编译器从源代码重建这个项目。这就是开源的目的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-28
    • 2019-02-12
    • 1970-01-01
    • 2012-07-07
    • 2016-03-02
    • 1970-01-01
    • 2014-04-29
    • 2017-06-22
    相关资源
    最近更新 更多