我正在尝试链接一个使用第三方共享库的c ++程序。主要是,这些库来自一个名为MBSim的github项目,我下载了最新的每日构建版本,其中包含我在/usr/local/mbsim-env
上安装的所有二进制文件,库和标题。
最重要的图书馆是libmbsim
,libopenmbvcppinterface
,libfmatvec
和libboost_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位。
有人能指出我走出这个死胡同吗?
答案 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++11
和g++
版本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'
如果这种不匹配确实是原因,只需使用您的编译器从源代码重建该项目。这就是开源用于。