clang++ as drop-in g++ replacement

I'm trying to use clang++ as drop-in replacement for G++ in a project.
I'm compiling for AArch64. When linking, clang seems to invoke the
native (x86) /usr/bin/ld instead of the one from AArch64 GCC suite. The
clang link command line looks like:

clang++ -target aarch64-linux-gnu -v \
  -gcc-toolchain /path/to/aarch64/gcc \ # Root of my AArch64 tool chain
  --sysroot=/path/to/aarch64/gcc/libc \ # From aarch64-linux-gnu-g++
-print-sysroot
  <some other options> <obj files>

And from the verbose output, I get:

Ubuntu clang version 3.4-1ubuntu3 (tags/RELEASE_34/final) (based on LLVM 3.4)
Target: aarch64--linux-gnu
Thread model: posix
Found candidate GCC installation:
/path/to/aarch64/gcc/lib/gcc/aarch64-linux-gnu/4.9.3
Selected GCC installation: /path/to/aarch64/gcc/lib/gcc/aarch64-linux-gnu/4.9.3
"/usr/bin/ld" --sysroot=/path/to/aarch64/gcc/aarch64-linux-gnu/libc ...

I don't get why clang got around choosing the native linker. The link
fails for obvious reasons that object files are AArch64 ELF.

The inferred target looks suspicious; so I changed it to just aarch64.
Even then, clang ends up invoking native linker.

Please advise.

PS: Please note that all these are from a legacy script that I'm
working on. I'm a rather novice clang user, and probably don't yet
know what I'm doing!

Hi Jeenu,

Your command line looks fairly correct. Clang falls back to the system linker when it fails to find a cross linker. A couple of things:

  1. In the sysroot that Linaro package, “libc” is a subdirectory of “aarch64-linux-gnu”. It looks like this is not the case for you - can I confirm that “/path/to/aarch64/gcc” contains the directory “aarch64-linux-gnu”?

  2. clang-3.4 is very old to be working on AArch64. It was the first release that contained AArch64 as a target and while we did our best to make it conformant, it was still fairly beta. clang-3.5 was the best release for AArch64 - it contained the backend merge and a bunch of work on its conformance. I’d recommend upgrading to clang-3.7, but at least to clang-3.5.

James

Hi Jeenu,

Your command line looks fairly correct. Clang falls back to the system
linker when it fails to find a cross linker. A couple of things:

1. In the sysroot that Linaro package, "libc" is a subdirectory of
"aarch64-linux-gnu". It looks like this is not the case for you - can I
confirm that "/path/to/aarch64/gcc" contains the directory
"aarch64-linux-gnu"?

Yes, it does.

2. clang-3.4 is very old to be working on AArch64. It was the first release
that contained AArch64 as a target and while we did our best to make it
conformant, it was still fairly beta. clang-3.5 was the best release for
AArch64 - it contained the backend merge and a bunch of work on its
conformance. I'd recommend upgrading to clang-3.7, but at least to
clang-3.5.

I moved to 3.6 (installed from package manager), but that too wouldn't
pick the right linker. After searching around, I gathered the -B
option to GCC, which I found working with clang too. So with
-B/path/to/aarch64/gcc/aarch64-linux-gnu/bin clang picks the AArch64
linker.

I couldn't find it documented with --help that clang would take -B
option though.

Do you have aarch64-linux-gnu-ld in your path? It should be picked up
automatically by clang if it can be found.

Joerg

No, I don't have AArch64 linker in $PATH - I usually refer to it with
its absolute path when required.

Is the target linker expected in $PATH? My impression was that hints
passed on with other options (sysroot, gcc-toolchain) were enough to
locate the right one.

The target linker is searched in tools directories (-B) and PATH. First
with target prefix, afterwards without. sysroot is only about searching
for include files as far as the compiler is concerned (and possibly some
special object files / libraries). No idea about gcc-toolchain, it is
not relevant for the systems I care about.

Joerg