llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.51k stars 11.79k forks source link

Clang fails to find crtbegin.o #9269

Open llvmbot opened 13 years ago

llvmbot commented 13 years ago
Bugzilla Link 8897
Version trunk
OS Linux
Reporter LLVM Bugzilla Contributor
CC @zygoloid

Extended Description

I get the following for the Driver/hello.c test on SuSE Linux 10.1:

"/ptmp/dag/build.llvm.trunk.official.opt/x86_64-unknown-linux-gnu/Release+Asserts/bin/clang" -cc1 -triple x86_64-unknown-linux-gnu -emit-obj -mrelax-all -disable-free -main-file-name hello.c -mrelocation-model static -mdisable-fp-elim -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-linker-version 2.17 -resource-dir /ptmp/dag/build.llvm.trunk.official.opt/x86_64-unknown-linux-gnu/Release+Asserts/bin/../lib/clang/2.9 -ferror-limit 19 -fmessage-length 0 -fgnu-runtime -fdiagnostics-show-option -o /tmp/cc-cppG60.o -x c /ptmp/dag/llvm-project.official/llvm/trunk/tools/clang/test/Driver/hello.c "/opt/cpkg/v6/binutils/2.17/bin/ld" --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o /ptmp/dag/build.llvm.trunk.official.opt/x86_64-unknown-linux-gnu/tools/clang/test/Driver/Output/hello.c.tmp /usr/lib/../lib64/crt1.o /usr/lib/../lib64/crti.o crtbegin.o -L -L/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/../../.. /tmp/cc-cppG60.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed crtend.o /usr/lib/../lib64/crtn.o /opt/cpkg/v6/binutils/2.17/bin/ld: crtbegin.o: No such file: No such file or directory clang: error: linker command failed with exit code 1 (use -v to see invocation)

I believe this is happening because the gcc used to build clang is not in a standard location:

/opt/gcc/4.5.1/bin/g++

Or alternatively, the system gcc is not listed in the ToolChains.cpp GccVersions list:

const char* GccVersions[] = {"4.5.1", "4.5", "4.4.5", "4.4.4", "4.4.3", "4.4", "4.3.4", "4.3.3", "4.3.2"};

dag@royale:/ptmp/dag/compiler_ref$ which gcc /usr/bin/gcc dag@royale:/ptmp/dag/compiler_ref$ gcc --version gcc (GCC) 4.1.2 20070115 (prerelease) (SUSE Linux) Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

In any case, the driver should not rely on a small set of hardcoded guesses as to where crtbegin.o is. A simple solution would be to use the build gcc's -print-search-dirs to get a list of candidate directories and fall back on the hardcoded ones as a last resort. Obviously different handling would be required if gcc were not the build compiler but for Linux, most of the time it will be.

llvmbot commented 7 years ago

I got bitten by this while cross compiling.

if clang is relying on gcc it should extract the sysroot and crtbegin paths using

-print-sysroot AND -print-libgcc-file-name

Currently it gets alternatively wrong either sysroot or the crtbegin path.

llvmbot commented 13 years ago

A small summary of the status is that clang only looks for the system compiler. It doesn't care about the gcc used to build it.

I don't have time to invest in this now, but I think a reasonable implementation is

*) The "toolchain dir" and other information needed by the driver (like extra ld options) should be set via the command line. The same clang binary should be able to handle a host build and being as a cross compiler for arm for example.

*) The default for those options should be produced by configure/cmake and would normally be those of the compiler used to build clang.

*) During build configure/cmake should accept options so that the clang being built, by default, behaves differently from the system compiler. For example, --driver_extra_ld_args="--hash-style=gnu".