Clang++ --gcc-toolchain and gcc 4.9.3 linking issues
Asked Answered
C

4

8

(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!)

Cashmere answered 30/8, 2016 at 3:31 Comment(2)
did you find a solution? I am also dealing with a very similar problem.Pinchas
I had to get things working FAST, so I tabled clang until we can get all items under the same ABI. I reverted to GCC for now until I get a chance to work on the tools chain issue again.Cashmere
F
2

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.

Fiddlestick answered 6/12, 2016 at 14:9 Comment(1)
Thank you sooo much, just spent hours trying to work this out. This is more of a problem now than it used to be, as older versions of Clang will not link against newer versions of gcc, which ends up breaking the clang build if a newer version of gcc is installed. And the workaround is almost impossible to derive without answers like this.Tamatave
T
1

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.

Tonytonya answered 1/2, 2017 at 14:38 Comment(0)
U
1

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
Upright answered 23/2, 2018 at 2:22 Comment(0)
I
0

As of Clang-16, you can use --gcc-install-dir to simply pass the full path of the GCC installation you want to use.

Immunogenic answered 11/4, 2023 at 10:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.