问题
(Ubuntu 16.04.1)
By default on 16.04.1 clang is picking the gcc tool chain for 5.4. Unfortunately I have a library that requires pre-5.0 ABI and I do NOT have access to the source, nor has the implementer released a new version. I've been trying to use the --gcc-toolchain option, but I can NOT get it to work. (ctrbegin.o and crtend.o don't get the proper prefix at link.)
$ clang++-3.8 -v -print-search-dirs
clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/i686-linux-gnu/5.4.0
Found candidate GCC installation: /usr/bin/../lib/gcc/i686-linux-gnu/6.0.0
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9.3
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/6.0.0
Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/5.4.0
Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/6.0.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9.3
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.4.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6.0.0
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0
Candidate multilib: .;@m64
Selected multilib: .;@m64
programs: =/usr/bin:/usr/lib/llvm-3.8/bin:/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../x86_64-linux-gnu/bin
libraries: =/usr/lib/llvm-3.8/bin/../lib/clang/3.8.0:
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0:
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu:
/lib/x86_64-linux-gnu:
/lib/../lib64:
/usr/lib/x86_64-linux-gnu:
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../..:
/usr/lib/llvm-3.8/bin/../lib:
/lib:
/usr/lib
When I attempt to specify the --gcc-toolchain, clang seems to accept, then completely ignore the value. (Same thing happens with clang++-3.5 on 16.04.1.)
Is this the proper syntax? Notice that the library directories are missing from the output.
$ clang++-3.8 -v --gcc-toolchain=/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9.3 -print-search-dirs
clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
programs: =/usr/bin:/usr/lib/llvm-3.8/bin:/..//bin
libraries: =/usr/lib/llvm-3.8/bin/../lib/clang/3.8.0:/lib/x86_64-linux-gnu:/lib/../lib64:/usr/lib/x86_64-linux-gnu:/usr/lib/llvm-3.8/bin/../lib:/lib:/usr/lib
I have tried MANY variations on the above theme. (4.9, removing the relative path, etc.) I've tried the -isystem option and the -cxx-isystem option. (Both suggested as solutions to similar issues.)
What am i missing? (I hope it is simple and a head smack is in order!)
回答1:
It seems that you're passing a wrong path to --gcc-toolchain
option. It expects a path to GCC install prefix which is /usr
in case of GCC installed with a package manager. However, I don't think it's possible to choose what toolchain to use if you have several versions of GCC installed in your system and they all have the same prefix. Seems that clang just takes the latest version in $PREFIX/lib/gcc/x86_64-linux-gnu
directory. So, I'd recommend you to build the toolchain you need yourself and pass the installation prefix to --gcc-toolchain
option.
回答2:
Unfortunately I have a library that requires pre-5.0 ABI and I do NOT have access to the source
you don't need to switch gcc-toolchain to change ABI as the newer gcc versions have dual-abi support.
To switch the ABI overriding the preprocessor macro:
clang++ -D_GLIBCXX_USE_CXX11_ABI=0
So, I'd recommend you to build the toolchain you need yourself and pass the installation prefix to --gcc-toolchain option.
If it is alredy available, you might want to trick clang to use your selected toolchain by mimicking your /usr folder via symlinks while excluding the gcc versions you dont need.
回答3:
As Gaetano wrote in the linked ticket, you need to build a separate directory that can be passed to clang as --gcc-toolchain
. Here's my slightly refined code. No bin
and include
links are needed.
# The libstdc++ version you want to use
libstdcxx_version="4.9"
# Avoid calling arch twice
arch="$(arch)"
# The new toolchain root in the current directory
toolchain_root="$(pwd)/toolchain"
# The gcc library directory to be created
toolchain_gcc="$toolchain_root/lib/gcc/$arch-linux-gnu"
# Create that directory
mkdir -p "$toolchain_gcc"
# Find the longest matching libstdc++ version.
# Needed for clang-3.8 and older - they need 4.9.x rather than 4.9.
libstdcxx_dir=$(ls -d /usr/lib/gcc/$arch-linux-gnu/${libstdcxx_version}* \
| tail -1)
# Link the libstdc++ library directory to the new location
ln -sfn "$libstdcxx_dir" "$toolchain_gcc/"
# Now you can add "--gcc-toolchain=$toolchain_root" to the clang flags
来源:https://stackoverflow.com/questions/39218360/clang-gcc-toolchain-and-gcc-4-9-3-linking-issues