使用boost序列化时出现链接器错误

14

我正在使用boost序列化。我编译时使用了-L/opt/local/lib -lboost_serialization -stdlib=libc++,但是遇到了几个(无法谷歌找到的)错误:

Undefined symbols for architecture x86_64:
  "boost::archive::text_oarchive_impl::save(std::__1::basic_string, std::__1::allocator > const&)", referenced from:
      void boost::archive::save_access::save_primitive, std::__1::allocator > >(boost::archive::text_oarchive&, std::__1::basic_string, std::__1::allocator > const&) in main.o
  "boost::archive::basic_text_oprimitive > >::~basic_text_oprimitive()", referenced from:
      boost::archive::text_oarchive_impl::~text_oarchive_impl() in main.o
  "boost::archive::text_oarchive_impl::text_oarchive_impl(std::__1::basic_ostream >&, unsigned int)", referenced from:
      boost::archive::text_oarchive::text_oarchive(std::__1::basic_ostream >&, unsigned int) in main.o
ld: symbol(s) not found for architecture x86_64

我正在对一个std::vector<std::string>进行序列化:

boost::archive::text_oarchive oa(std::cout);
oa << tasks;

我的boost安装有问题吗?


boost库是通用二进制文件,包含32位和64位的机器码(所以我猜这不是问题的原因):

$ file libboost_serialization.dylib
libboost_serialization.dylib: Mach-O universal binary with 2 architectures
libboost_serialization.dylib (for architecture i386): Mach-O dynamically linked shared library i386
libboost_serialization.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64

我在Mac OS X 10.7上使用sudo port install boost +universal安装了boost。


也许 boost 是使用不同于您正在使用的编译器构建的?我过去在 macports 中遇到过类似的问题,但是已经太久了,无法记住详细信息。 - ergosys
你能否提供一个小例子展示你如何使用序列化库?我没有使用过它,但是一旦我有了一个可工作的测试用例(指能够展示问题),我相信我可以找到问题所在。 - Dietmar Kühl
2个回答

17
我可以使用以下代码重现问题:
#include "boost/archive/text_oarchive.hpp"
#include "boost/serialization/vector.hpp"
#include <vector>
#include <string>

int main()
{
    std::vector<std::string> tasks;
    boost::archive::text_oarchive oa(std::cout);
    oa << tasks;
}

这段代码在使用g++clang++默认标志编译和链接,并使用-lboost_serialization进行链接时,没有问题。但是,当使用clang++libc++时,链接失败,错误信息如下(我已经在/opt/boost安装了Boost):
clang++ -c -stdlib=libc++ -I/opt/boost -W -Wall -ansi serialize.cpp
clang++ -o serialize.tsk -L/opt/boost/stage/lib -stdlib=libc++ serialize.o -lboost_serialization

基于这个前提,我认为使用-stdlib=libc++编译的构建项目需要自己构建Boost,并且可以根据Boost installation guide进行构建。
tar jxvf ~/Downloads/boost_1_48_0.tar.bz2
cd boost_1_48_0/tools/build/v2

# change the build rules to use -stdlib=libc++:
mv tools/clang-darwin.jam tools/clang-darwin.jam.orig
sed -e 's/CONFIG_COMMAND)"/CONFIG_COMMAND)" -stdlib=libc++/' < tools/clang-darwin.jam.orig > tools/clang-darwin.jam

./boostrap.sh
sudo ./b2 install --prefix=/opt/boost-clang
cd ../../..
/opt/boost-clang/bin/b2 --build-dir=/opt/tmp toolset=clang stage
sudo /opt/boost-clang/bin/b2 --build-dir=/opt/tmp toolset=clang install --prefix=/opt/boost-clang

我对clang-darwin.jam所做的修改几乎肯定不是预期的,但它们似乎起到了作用:我不太了解"bjam",只是试图找到一个适当的位置来应用这个变化。安装的某些步骤使用sudo将东西安装到受保护目录中。显然,你也可以安装到其他有写权限的目录中。我只是以一种防止意外出错的方式在我的机器上安装了这些内容。

但是,通过这种安装方式,我成功地构建了程序:

/opt/llvm/bin/clang++ -stdlib=libc++ -W -Wall -ansi -I/opt/boost-clang  -c -o serialize.o serialize.cpp
/opt/llvm/bin/clang++ -stdlib=libc++ -L/opt/boost-clang/lib serialize.o -lboost_serialization -o serialize.tsk

对我来说,编译时需要-I/opt/boost-clang。在按照所有步骤操作后,我仍然在链接阶段失败。我的操作系统是MacOS 10.13.6 High Sierra,使用的是Boost 1.69。我对步骤进行了轻微修改,但大部分相同。 - Joe Flack

0

看起来你的boost库可能是32位的。

这是一个问题,除非你尝试使用少数不仅仅是头文件的boost utils,否则你不会注意到它。


2
运行命令 "file boost_ser.so"。它会告诉你它是32位架构还是64位架构。 - Arunmu
"libboost_serialization.dylib:Mach-O 64位动态链接共享库x86_64" 嗯... - user142019
@WTP otool -vf libboost_serialization.dylib 显示了什么? - Drew Dormann
我遇到了这个问题。我使用的是64位Mac,并从Homebrew安装了64位的Boost。我从otool命令中没有得到任何输出(我必须输入完整路径),而对于file,我得到了lib:Mach-O 64位动态链接共享库x86_64 - Joe Flack

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接