【问题标题】:Link different C++ standard libraries on Mac OS X在 Mac OS X 上链接不同的 C++ 标准库
【发布时间】:2013-10-28 12:27:12
【问题描述】:

现在 Mac OS X 上可以存在多个 C++ 标准库,现在看起来很混乱。根据https://stackoverflow.com/a/8457799/1772681的说法,混合使用libstdc++和libc++会导致链接错误,抓住这种危险的情况,是一件好事。

另一方面,还有两种情况需要进一步调查,我在 github gist (https://gist.github.com/manphiz/7195515) 中为此创建了一些测试用例。它确认混合链接到 libstdc++(来自系统或 vanilla GNU GCC)和 libc++(系统)的动态库将导致链接错误。但是,如果一个动态库链接到系统 libstdc++,而另一个动态库链接到 vanilla GNU GCC libstdc++,然后将两者链接到二进制文件中也可以,对于我的简单测试用例,它甚至可以在运行时工作。

$ make -f Makefile.system_gnu 
g++-4.8 -g -Wall -fPIC -o main.o -c main.cc
g++-4.8 -g -Wall -fPIC -o test_a.o -c test_a.cc
g++-4.8 -dynamiclib -o libtest_a.dylib test_a.o
clang++ -g -Wall -fPIC "-stdlib=libstdc++" -o test_b.o -c test_b.cc
clang++ -dynamiclib "-stdlib=libstdc++" -o libtest_b.dylib test_b.o
g++-4.8 -o test main.o -L. -ltest_a -ltest_b

$ ./test
main_test_a_test_b

所以这里需要建议:

  • 我们可以混合使用系统 libstdc++ 和手动构建的 GNU GCC libstdc++ 吗?如果没有,什么时候会造成麻烦?
  • 我们可以混合使用系统 libc++ 和手动构建的 Clang libc++ 吗?如果没有,什么时候会造成麻烦?

编译器信息:

$ clang -v
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix

$ gcc-4.8 -v
Using built-in specs.
COLLECT_GCC=gcc-4.8
COLLECT_LTO_WRAPPER=/opt/homebrew/Cellar/gcc48/4.8.2/libexec/gcc/x86_64-apple-darwin13.0.0/4.8.2/lto-wrapper
Target: x86_64-apple-darwin13.0.0
Configured with: ../configure --build=x86_64-apple-darwin13.0.0 --prefix=/opt/homebrew/Cellar/gcc48/4.8.2 --enable-languages=c,c++,fortran,java,objc,obj-c++ --program-suffix=-4.8 --with-gmp=/opt/homebrew/opt/gmp4 --with-mpfr=/opt/homebrew/opt/mpfr2 --with-mpc=/opt/homebrew/opt/libmpc08 --with-cloog=/opt/homebrew/opt/cloog018 --with-isl=/opt/homebrew/opt/isl011 --with-system-zlib --enable-version-specific-runtime-libs --enable-libstdcxx-time=yes --enable-stage1-checking --enable-checking=release --enable-lto --disable-werror --enable-plugin --disable-nls --with-ecj-jar=/opt/homebrew/opt/ecj/share/java/ecj.jar --enable-multilib
Thread model: posix
gcc version 4.8.2 (GCC)

系统为 Mac OS X 10.9。

【问题讨论】:

    标签: c++ macos std libstdc++ libc++


    【解决方案1】:

    我不代表 Apple,但观察他们的行动,我相信他们的目标是回到 Mac OS(和 iOS)的一个标准库实现——那就是 libc++。我相信在未来的某个时候,libstdc++ 将不再是 Mac OS X 的一部分。

    我们可以混合使用系统 libc++ 和手动构建的 Clang libc++ 吗?如果没有,什么时候会出事?

    我经常这样做——但我不会替换 usr/lib 中的那个。相反,我在设置环境变量 DYLD_LIBRARY_PATH 以指向我新建的 libc++ 后运行特定程序。替换 /usr/lib 中的那个可能会使您的系统变砖。 (如果您破坏了 dylib 中的某些内容 - 或者只是更改了 std::string 的布局,比如说)。

    【讨论】:

    • 其实我想知道如果我使用的两个共享库链接到不同的 libc++ 会发生什么(一个链接到系统 libc++,一个链接到我用 llvm 构建的 libc++)。
    • 另外,对于 libstdc++ 案例,我的示例是否有效意味着 libstdc++ 保持 API 兼容性,因此可以从链接到不同版本的 libstdc++ 的 dylib 边界传递调用?
    • 我认为这意味着您在示例中调用的 libstdc++ 部分保持 API 兼容性(或者,至少任何 API 兼容性都是非致命的) - 但您进行的下一个 libstdc++ 调用可能会中断.
    • 感谢您的回答。我认为这实际上取决于共享库的工作方式,并且还取决于实现。还请在我认为对其他人有帮助的答案中包含您对 libstdc++ 的评论。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多