链接到第三方共享库时g ++未定义的引用错误

时间:2017-09-27 21:02:52

标签: c++ linux linker

我正在尝试链接一个使用第三方共享库的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。结果保持不变。

首先,链接器发出警告,我正在链接一个较旧的boost库:

    /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 64bits中完成了所有工作,而MBSim库也是64位。

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

2 个答案:

答案 0 :(得分:1)

您的第三方共享库是否可以使用较旧版本的GCC进行编译?在GCC 5中引入了新的ABI。它可能默认在您的平台上启用。请参阅https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html

您可以尝试切换到较旧的ABI,但这可能需要您的其他库也使用旧的ABI进行编译。您也可以明确切换第三方库的ABI。

答案 1 :(得分:0)

  

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

的未定义引用

这是MBSim::RigidBody::RigidBody(const string&)的引用,使用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'

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