【问题标题】:How do I compile boost for OS X 64b platforms with stdlibc++?如何使用 stdlibc++ 为 OS X 64b 平台编译 boost?
【发布时间】:2014-10-21 17:01:46
【问题描述】:

我想用 stdlibc++ 为 Mac OS X 10.9 编译 boost。我运行以下命令:

./b2 threading=multi link=static runtime-link=static cxxflags="-stdlib=libstdc++" linkflags="-stdlib=libstdc++"

构建成功完成;但是,我的应用程序构建在链接时失败,当它找不到符号时,就像 std::__1::locale::use_facet、std::__1::basic_string 等一样糟糕。相关的细节是 __1,我相信。

我的问题是,如何使用 stdlibc++ 为 OSX 64b 平台编译 boost?

更多信息:

我在编译过程中注意到以下日志:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib:文件:bin.v2/libs/filesystem/build/clang-darwin-4.2.1/release/link- static/runtime-link-static/threading-multi/libboost_filesystem.a(windows_file_codecvt.o) 没有符号

【问题讨论】:

  • 您正在使用-stdlib=libstdc++ 编译您的应用程序?因为这也是需要的
  • @Petesh 是的,我正在使用 libstdc++ 编译应用程序
  • 选择一个你构建的boost库,肯定依赖于STL中的某些东西,在它上面运行一个nm,通过c++filt管道它并检查它是否提到std::__1:: .如果它提到了这一点,那么 boost 已经 是用libstdc++ 构建的,在这种情况下你没有正确编译/链接你的应用程序。
  • @Petesh 如果我在 libboost_filesystem.a 上执行这些步骤,我会看到预期的命名空间。但是我确实在我的编译日志中注意到以下消息 >/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: bin.v2/libs/filesystem/build/clang-darwin -4.2.1/release/link-static/runtime-link-static/threading-multi/libboost_filesystem.a(windows_file_codecvt.o) 没有符号
  • 我有一个巨大的大脑放屁。你的 boost 是用 libc++ 编译的,而不是 libstdc++。我正在失去理智(对于此处的误导表示歉意)。

标签: c++ macos boost clang libstdc++


【解决方案1】:

已下载 Boost 1.55,使用以下方式引导:

./bootstrap.sh --prefix=/usr/local/boost155 cxxflags="-arch i386 -arch x86_64" \
    address-model=32_64 threading=multi macos-version=10.8 stage

使用:

./b2 threading=multi link=static runtime-link=static \
    cxxflags="-stdlib=libstdc++" linkflags="-stdlib=libstdc++"

libboost_chrono.a:

     U std::string::_Rep::_M_destroy(std::allocator<char> const&)
     U std::string::_Rep::_S_empty_rep_storage
     U std::string::append(char const*, unsigned long)
     U std::string::append(std::string const&)
     U std::string::assign(char const*, unsigned long)
     U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)
     U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&)

这意味着该库是使用选项 -stdlib=libstdc++ 构建的 - 即它与 C++ 运行时的 gnu 版本链接。

我们使用以下命令清除构建:

find . -name \*.o -print0 | xargs -0 rm
find . -name \*.a -print0 | xargs -0 rm

如果我们不这样做,那么它就不会重建,并且您最终会得到与以前相同的代码。接下来我们使用:

./b2 threading=multi link=static runtime-link=static \
    cxxflags="-stdlib=libc++" linkflags="-stdlib=libc++"

libboost_chrono.a:

     U std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::append(char const*)
     U std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::append(char const*, unsigned long)
     U std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::assign(char const*)
     U std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
     U std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string()

这意味着它是针对 libc++ 构建的。

这可以通过使用一个简单的测试c++程序来验证(表明链接):

#include <string>

int
main(int argc, char **argv)
{
    std::string s("Hello World");
    return 0;
}

$ make test
c++     test.cpp   -o test
$ nm ./test | c++filt
                 U std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__init(char const*, unsigned long)
                 U std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string()

$ rm test
$ make test CXXFLAGS=-stdlib=libstdc++
c++ -stdlib=libstdc++    test.cpp   -o test
$ nm ./test | c++filt
                 U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)
                 U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()

是的,它正在使用相关标志进行编译。它确实表明如果您使用 XCode 5,您必须将 -stdlib=libstdc++ 传递给您正在编译的everything,因为它现在默认使用 -stdlib=libc++。这意味着依赖于您所依赖的c++ stdlib 的任何基于 C++ 的库也必须使用相同的标志进行编译。

小心使用 增量 构建的 boost - 如果您不清除 .o.a 文件,它们不会根据更改的标志重新编译,从而保持编译后的文件,所以如果它们被错误编译,那么你会遇到问题。

【讨论】:

  • 您知道如何在 FreeBSD 下编译它吗?当我尝试在 FreeBSD 下使用此命令 sudo ./b2 -j 4 threading=multi link=static toolset=clang cxxflags="-stdlib=libstdc++" linkflags="-stdlib=libstdc++ 编译 boost 时,出现以下错误 libs/atomic/src/lockpool.cpp:15:10: fatal error: 'cstddef' file not found #include &lt;cstddef&gt;
  • 您正在编译一个新版本的 FreeBSD (11.0?),它没有安装 gcclibstdc++ 的副本。您首先需要确保它们已安装在系统上;那么您可能能够构建它。 FreeBSD 项目从gcc 转移到clang,所以从长远来看,最好用clang 构建所有东西,而不是试图让它工作。
  • Petesh,感谢您的快速回复!是的,我有 FreeBDS 11.0,实际上我安装了gcc,这里是locate 输出:/usr/local/lib/gcc48/{libstdc++.a, libstdc++.so, libstdc++.so.6, libstdc++.so.6.0.19, libstdc++.so.6.0.19-gdb.py, libstdc++.a, libstdc++.so, libstdc++.so.6, libstdc++.so.6.0.20, libstdc++.so.6.0.20-gdb.py} /usr/local/lib/gcc5/{libstdc++.a, libstdc++.so, libstdc++.so.6, libstdc++.so.6.0.21, libstdc++.so.6.0.21-gdb.py, libstdc++fs.a} /usr/ports/lang/libstdc++_stldoc_4.2.2/{Makefile, distinfo, pkg-descr} 在这种情况下可能有什么问题?
  • toolset=clang-stdlib=libstdc++ 一起使用是行不通的——它依赖于使用该支持编译的clang,它不在FreeBSD 上。您必须使用 gcc 引导和构建 boost 以获得 libstdc++ 支持 - ./bootstrap.sh --with-toolset=gcc &amp;&amp; ./b2 -j 4 threading=multi link=static
  • 看起来是与预编译头相关的内部编译器错误 - 可能是特定于编译器的。作为一种潜在的解决方法,请执行 rm bin.v2/libs/math/build/gcc-5.4.0/release/link-static/threading-multi/../src/tr1/pch.hpp.gch &amp;&amp; touch bin.v2/libs/math/build/gcc-5.4.0/release/link-static/threading-multi/../src/tr1/pch.hpp.gch 然后重新运行 b2 - 这会破坏预编译的头文件,希望可以帮助您解决问题。
【解决方案2】:

我使用一个简单的命令行来完成在 boost 邮件列表中找到的技巧: http://lists.boost.org/boost-users/2014/02/81274.php

这是 sn-p,以防链接不再起作用:

$ cd tools/build/v2/ 
$ ./bootstrap.sh 
$ cd ~/boost-stdc++-install/boost_1_54_0 
$ cd ~/boost-stdc++-install/boost_1_54_0 
$ tools/build/v2/b2 \ 
     --build-dir=`pwd`/tmp/build/ \ 
     --stagedir=`pwd`/tmp/stage/ \ 
     --buildid=libstdc++ \ 
     --layout=tagged -j24 \ 
     toolset=clang \ 
     cxxflags="-ftemplate-depth=999 -stdlib=libstdc++" \ 
     linkflags="-stdlib=libstdc++" \ 
     define=BOOST_SYSTEM_NO_DEPRECATED stage 

【讨论】:

    猜你喜欢
    • 2011-11-03
    • 1970-01-01
    • 1970-01-01
    • 2010-12-15
    • 2014-07-02
    • 2019-09-27
    • 1970-01-01
    • 2013-11-23
    • 1970-01-01
    相关资源
    最近更新 更多