C++: All boost path operations segfault (OSX / GCC)

末鹿安然 提交于 2019-12-04 04:37:12

You're mixing implementations of the C++ standard library.

Boost, when installed via brew will be compiled using clang++. This toolchain uses libc++ by default.

g++ insists on using it's own libstdc++ implementation.

These implementations are not binary compatible, which is where the problems are arising.

I extracted a fresh copy of boost into a subdirectory, did a:

$ ./bootstrap.sh --prefix=/usr/local/boost156 cxxflags="-arch i386 -arch x86_64" address-model=32_64 threading=multi macos-version=10.9 toolset=g++-4.8 stage

Then built-it (static only; there's a build issue where it can't make the dynamic libraries in this situation under OSX - ld complains that the -h option is not supported):

$ ./b2 --layout=tagged threading=multi link=static toolset=gcc-4.8

When I compiled your code (because of threading=multi, I had to add -mt to the link options):

$ g++-4.8 -g -std=c++11 -Iboost_1_56_0  -Lboost_1_56_0/stage/lib -lboost_filesystem-mt -lboost_system-mt main.cpp -o ./path-test
$ ./path-test
hello/../world

$

i.e. it worked just fine in this case.

What does this mean?

  • C++ libraries on OSX are a complete PITA if you're trying to mix g++ and clang++
  • because all clang++ code defaults to being built with libc++ you're going to have to have private copies of any c++ libraries if you intend to build them with g++
  • homebrew is just following orders when it compiles with clang++

It's a mess, but if you stick to the <sarcasm>one true compiler</sarcasm>, then you'll be fine. TBH I prefer clang's error messages and the static analysis is excellent; but if you have to use g++, you'll have to keep private copies of any c++ libraries that you want to use, also compiled with g++.

In addition to Petesh excellent answer, for anyone struggling with building boost using gcc via homebrew:

brew install boost --build-from-source --env=superenv --cc=gcc-<Your GCC version>

Note the --env=superenv switch, which is a recent addition to Homebrew, so make sure your brew is up to date!

If you are running into issues and aren't sure if boost was compiled with gcc or clang, use otool -L on any boost dynamic library (.dylib file) and look for the libc++ or libstdc++ entry.

For example, running the following command after I finally got it working right:

otool -L /usr/local/lib/libboost_system.dylib

Produces the following output:

/usr/local/lib/libboost_system.dylib:
    /usr/local/lib/libboost_system.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/local/lib/gcc/x86_64-apple-darwin13.3.0/4.9.1/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.20.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
    /usr/local/Cellar/gcc/4.9.1/lib/gcc/x86_64-apple-darwin13.3.0/4.9.1/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)

The second entry shows that this boost lib links against GCC's libstd++. If instead it said /usr/lib/libc++.dylib, then it is still linked against Apple's clang runtime.

Note that using brew enables all variants (single / multi / static / dynamic) as the formula's maintainers incorporate patches to make sure it compiles successfully on OSX - which may not be the base with vanilla boost.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!