llvm / llvm-project

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

clang doesnt use library search path that it was built with #20884

Open llvmbot opened 10 years ago

llvmbot commented 10 years ago
Bugzilla Link 20510
Version trunk
OS Linux
Attachments config log
Reporter LLVM Bugzilla Contributor
CC @DougGregor,@zygoloid,@rnk,@viccpp

Extended Description

The symptom of this problem is that clang builds can fail with an error similar to:

clang++: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.18' not found (required by clang++)

This appears to be because clang does not "remember" the search path it was built with. In this case, clang was built w/gcc 4.9.0, which is installed in /usr/local.

/shared/clang $ /usr/local/bin/gcc -print-search-dirs
install: /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/
programs: =/usr/local/libexec/gcc/x86_64-unknown-linux-gnu/4.9.0/:/usr/local/libexec/gcc/x86_64-unknown-linux-gnu/4.9.0/:/usr/local/libexec/gcc/x86_64-unknown-linux-gnu/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../x86_64-unknown-linux-gnu/bin/x86_64-unknown-linux-gnu/4.9.0/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../x86_64-unknown-linux-gnu/bin/
libraries: =/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../x86_64-unknown-linux-gnu/lib/x86_64-unknown-linux-gnu/4.9.0/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../x86_64-unknown-linux-gnu/lib/../lib64/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../x86_64-unknown-linux-gnu/4.9.0/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../lib64/:/lib/x86_64-unknown-linux-gnu/4.9.0/:/lib/../lib64/:/usr/lib/x86_64-unknown-linux-gnu/4.9.0/:/usr/lib/../lib64/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../x86_64-unknown-linux-gnu/lib/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../:/lib/:/usr/lib/

/shared/clang $ Release+Asserts/bin/clang++ -print-search-dirs
programs: =/shared/clang/Release+Asserts/bin:/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../x86_64-redhat-linux/bin
libraries: =/shared/clang/Release+Asserts/bin/../lib/clang/3.6.0:/usr/lib/gcc/x86_64-redhat-linux/4.4.7:/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64:/lib/../lib64:/usr/lib/../lib64:/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../..:/shared/clang/Release+Asserts/bin/../lib:/lib:/usr/lib

As you can see, clang is picking up the library search paths from the system default compiler (gcc 4.4), rather than the search paths with which clang was built (gcc 4.9).

Using LD_LIBRARY_PATH is not an option -- our build scripts deliberately unset LD_LIBRARY_PATH before linking to ensure that only specifically named library paths are searched.

I'm attaching the config.log, which appears to show clang picking up gcc 4.9.0 for the build (as expected).

The command used to build clang is:

make clean distclean;CFLAGS="-std=gnu89" ../llvm/configure --prefix=/build/share/clang --enable-optimized --enable-targets=x86_64 && make

At this point I'm not necessarily looking for a fix, but an indication whether this is a legitimate problem with clang, or possibly a problem on our end.

Thanks!

llvmbot commented 9 years ago

OK, I think I've finally figured this out.

I wrote up my findings in this blog post: http://btorpey.github.io/blog/2015/01/02/building-clang/

I'd appreciate it if Reid et al. could take a look and offer any suggestions, corrections, etc.

Thanks!

llvmbot commented 9 years ago

I think it would be good to figure out why the --with-gcc-toolchain= option isn't working. As far as I can tell, it does exactly what you want: it bakes in the path to a gcc installation so that it can find it for headers and libraries. This would remove the need to thread --gcc-toolchain flags through all your build systems, which seems like a win.

Unfortunately, the "baking" is done with rpath. The policy in our shop is that NOTHING goes to QA or prod with an rpath (or runpath) in it. (I happen to agree, but even if I didn't that wouldn't matter, it's not going to change).

So, we know we need to have compiler support libraries on LD_LIBRARY_PATH, and that's OK -- the deployment tools take care of that. What's not so great is having to add compiler support libraries for the compiler that was used to compile the code that we're deploying. It would be one thing if we could get that information from clang somehow, but when we query clang for search dirs, it responds with the *system compiler's search dirs. On RH6, of course, the system compiler can't even compile clang, so that does no good at all.

Are you still having issues with programs linked by clang not finding the more recent version of libstdc++? In that case, I don't think clang is behaving differently from gcc in this respect. Any binaries produced by gcc from a non-standard installation path will link against libraries that the loader won't find by default.

Yes, and as noted above we're OK with that. It's the second level of indirection (which compiler compiled the the compiler that compiled the code itself) that is a major hassle.

There are three ways that glibc's loader finds libraries needed by a program:

  1. Looks in standard install paths (/usr/lib, /usr/lib64, etc)
  2. Looks in LD_LIBRARY_PATH
  3. Looks in RPATH in binary

I think the order is reversed, but no matter in our case, since co. policy forbids using RPATH in QA or prod.

You need to pick one of those approaches to help any program find dynamic libraries, but it seems like you've rejected all of them.

I'm open to anything at this point, including using libcxx to eliminate depencencies on gcc entirely (assuming that it will).

If necessary we can hard- code the dependency between a particular version of clang and the gcc version that was used to build it, and add BOTH sets of support libraries to LD_LIBRARY_PATH at runtime, but that seems like a hack, and error-prone -- which is why I'm trying to find another approach.

How do other programs in your environment find the dynamic libraries they need? Consider the program /build/share/bin/foo which links against /build/share/lib64/libbar.so.

In that case we add /build/share/lib64 to LD_LIBRARY_PATH at runtime. But again, that is NOT done using rpath, and the environment settings (including LD_LIBRARY_PATH) are controlled by an operations group separate from the dev group, which gives at least a modicum of security and traceability to the process.

I think it would be a good idea to raise these kinds of broad usage questions on cfe-dev.

I will give that a shot -- thanks for the suggestion! Although my guess is that anything that comes out of that will take a while to percolate.

Our bug tracker is configured to only send updates to llvmbugs@ on issue status changes, so further replies to this bug only go to people on the cc list (me), and I'm out of ideas. :(

Well, hopefully the above gives you a better understanding of the pickle we're in.

Going back to square one, the issue was that clang generates code that requires library versions that are not possible to discover by querying clang itself (e.g., by -print-search-dirs). If we could at least get that information, we could use it to generate some kind of manifest that could be used to ensure that dependent libraries are installed and configured at runtime.

As it stands, the values returned by -print-search-dirs are incorrect/useless in the case where clang was built with a compiler other than the standard system compiler.

In my case, I build clang with /build/share/gcc/4.9.0/bin/g++ -- but what I get from clang is:

$ lsb_release -a
LSB Version:    :base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch
Distributor ID: CentOS
Description:    CentOS release 6.5 (Final)
Release:    6.5
Codename:   Final
$ which gcc
/build/share/gcc/4.9.0/bin/gcc
$ which clang
/build/share/clang/3.6.0-svn/bin/clang
$ clang -print-search-dirs
programs: =/build/share/clang/3.6.0-svn/bin:/shared/build/share/clang/3.6.0-svn/bin:/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../x86_64-redhat-linux/bin
libraries: =/shared/build/share/clang/3.6.0-svn/bin/../lib/clang/3.6.0:/usr/lib/gcc/x86_64-redhat-linux/4.4.7:/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64:/lib/../lib64:/usr/lib/../lib64:/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../..:/shared/build/share/clang/3.6.0-svn/bin/../lib:/lib:/usr/lib

However, clang DOES seem to have this tucked away somewhere:

$ strings `which clang` | grep "/build/share/gcc"
/build/share/gcc/4.9.0/lib64:$ORIGIN/../lib

AND, it shows up as a dependency (although for the life of me I can't get either readelf or objdump to show it to me :-(

$ unset LD_LIBRARY_PATH
$ ldd `which clang`
    linux-vdso.so.1 =>  (0x00007fff13f47000)
    librt.so.1 => /lib64/librt.so.1 (0x0000003dae000000)
    libdl.so.2 => /lib64/libdl.so.2 (0x0000003dad400000)
    libtinfo.so.5 => /lib64/libtinfo.so.5 (0x0000003dbfc00000)
    libatomic.so.1 => /build/share/gcc/4.9.0/lib64/libatomic.so.1 (0x00007f5233b36000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003dad800000)
    libz.so.1 => /lib64/libz.so.1 (0x0000003dadc00000)
    libstdc++.so.6 => /build/share/gcc/4.9.0/lib64/libstdc++.so.6 (0x00007f5233823000)
    libm.so.6 => /lib64/libm.so.6 (0x0000003dacc00000)
    libgcc_s.so.1 => /build/share/gcc/4.9.0/lib64/libgcc_s.so.1 (0x00007f523360c000)
    libc.so.6 => /lib64/libc.so.6 (0x0000003dad000000)
    /lib64/ld-linux-x86-64.so.2 (0x0000003dac800000)

Anyway, thanks for taking the time to read this, as well as for all the great clang stuff that we can't wait to deploy!

rnk commented 9 years ago

I think it would be good to figure out why the --with-gcc-toolchain= option isn't working. As far as I can tell, it does exactly what you want: it bakes in the path to a gcc installation so that it can find it for headers and libraries. This would remove the need to thread --gcc-toolchain flags through all your build systems, which seems like a win.

Are you still having issues with programs linked by clang not finding the more recent version of libstdc++? In that case, I don't think clang is behaving differently from gcc in this respect. Any binaries produced by gcc from a non-standard installation path will link against libraries that the loader won't find by default.

There are three ways that glibc's loader finds libraries needed by a program:

  1. Looks in standard install paths (/usr/lib, /usr/lib64, etc)
  2. Looks in LD_LIBRARY_PATH
  3. Looks in RPATH in binary

You need to pick one of those approaches to help any program find dynamic libraries, but it seems like you've rejected all of them. How do other programs in your environment find the dynamic libraries they need? Consider the program /build/share/bin/foo which links against /build/share/lib64/libbar.so.

I think it would be a good idea to raise these kinds of broad usage questions on cfe-dev. Our bug tracker is configured to only send updates to llvmbugs@ on issue status changes, so further replies to this bug only go to people on the cc list (me), and I'm out of ideas. :(

llvmbot commented 9 years ago

Up till now, I've been working more or less solo w/clang, so the fact that I need to jump through hoops to get it working isn't too bad. However, now that we're getting ready to roll out clang support to our dev & QA environments, it's become a real pain.

Given our insistence on stripping rpath from executables, I can only think of two worakable approaches to dealing with the fact that clang itself depends on gcc libraries, and that clang generates code that also depends on gcc libraries.

  1. The clang install script could copy required libraries at install time from the source directories to the install directories. I don't know if this would run afoul of licensing terms for gcc, but if not it could be an attractive alternative for people who are looking for a self-contained clang distribution. We already need to know where to get library support for the compiler used, and our configuration management can properly set LD_LIBRARY_PATH at runtime to the clang directories.

  2. Switch to using llvm's libcxx and libcxxabi support, and eliminate all dependencies on gcc. This appears to be easier said than done -- building with the most recent version (222451) gives compile errors. So, before going down that rabbit hole, I have a couple of questions:

I'm not necessarily looking for a fix here (although that would be lovely), but I would certainly appreciate some guidance on what is likely to be the most effective approach.

Thanks again!

llvmbot commented 9 years ago

To follow up on earlier post, I've followed all the instructions and have working installs (sort of).

To make things work, I need to do the following:

  1. add --gcc-toolchain=... to compile and link flags when building my project;

In this case, the value specified for gcc-toolchain is hard-coded in makefile (actualy CMakeLists.txt as we're starting to use CMake for new stuff).

It would be nice if we could at least get the correct gcc-toolchain value from clang in such a way that we could parse it at build-time rather than having to hard-code it in make file. Unfortunately, both -print-search-dirs and -print-libgcc-file-name return the system compiler (in this case gcc 4.4.7), even though clang was built with gcc 4.9.0.

(FWIW, gcc is installed in a non-standard location as well -- our convention is to have all build tools and 3rd-party dependencies in /build/share//. ).

  1. Add the lib64 directory from the gcc-toolchain to the LD_LIBRARY_PATH for any executables built with that version of clang

Otherwise, we end up with /usr/lib64/libstdc++.so.6: versionGLIBCXX_3.4.15' not found (required by ...)` errors for any executables that were built with that version of clang.

Before you go there, we deliberately strip rpath from executables for a couple of reasons:

So, maybe I'm doing things wrong here, but based on reading the docs, and from what you've said earlier I don't think I am.

And if I'm not doing things wrong, this seems like an awful lot of hoops to jump through that are specific to clang.

FWIW, we've been doing things this way for about 7-8 years now using gcc (non-standard directory structure, locked-down PATH/LD_LIBRARY_PATH, no RPATH, etc.) and these have not been issues.

If there's a better way to do things (other than changing around our procedures, which frankly are not going to change any time soon), I'd love to know what it is.

Again, thanks for your help, suggestions and patience! This is not a knock on clang (which keeps getting better every time I take another look -- I can't wait to start working with the static thread safety analysis, for instance), but this whole experience has been a little frustrating.

llvmbot commented 10 years ago

OK, back from vacation, co. being sold, etc.

A couple of points:

As you can see, the correct -L parameter is being passed to clang++, but it would appear that this is ignored in the case of libstdc++, and that clang uses a burned-in path instead.

What I ended up doing is taking your suggestion to build clang w/rpath, as documented here: http://llvm.org/docs/GettingStarted.html#getting-a-modern-host-c-toolchain

FWIW, the build command looks like this (for building clang using gcc 4.9.0, with gcc installed in default location of /usr/local):

CC=/usr/local/gcc CXX=/usr/local/g++ cmake ../llvm -DCMAKE_CXX_LINK_FLAGS="-Wl,-rpath,/usr/local/lib64 -L/usr/local/lib64" -DCMAKE_BUILD_TYPE="Release" -DLLVM_TARGETS_TO_BUILD="X86"

My original point is still valid, though, I believe:

I'm just saying ....

llvmbot commented 10 years ago

P.S. I'm going to be on vacation for the next week or so, so if you reply and dont hear back from me right away, that's the reason.

Thanks again for all your help!

llvmbot commented 10 years ago

My point is that I think clang should behave more like gcc in this regard. If you look at the following info for gcc 4.9.0, you can see that even though it was built with the system compiler, it has the "correct" search paths baked in -- i.e., the paths corresponding to the code that itself will generate.

/home/btorpey $ which gcc
/usr/local/bin/gcc
/home/btorpey $ gcc --version
gcc (GCC) 4.9.0
Copyright (C) 2014 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.

/home/btorpey $ gcc -print-search-dirs
install: /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/
programs: =/usr/local/libexec/gcc/x86_64-unknown-linux-gnu/4.9.0/:/usr/local/libexec/gcc/x86_64-unknown-linux-gnu/4.9.0/:/usr/local/libexec/gcc/x86_64-unknown-linux-gnu/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../x86_64-unknown-linux-gnu/bin/x86_64-unknown-linux-gnu/4.9.0/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../x86_64-unknown-linux-gnu/bin/
libraries: =/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../x86_64-unknown-linux-gnu/lib/x86_64-unknown-linux-gnu/4.9.0/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../x86_64-unknown-linux-gnu/lib/../lib64/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../x86_64-unknown-linux-gnu/4.9.0/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../lib64/:/lib/x86_64-unknown-linux-gnu/4.9.0/:/lib/../lib64/:/usr/lib/x86_64-unknown-linux-gnu/4.9.0/:/usr/lib/../lib64/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../x86_64-unknown-linux-gnu/lib/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../:/lib/:/usr/lib/
/home/btorpey $ 

OTOH, clang has the system compiler search paths baked in, even though clang is generating code that does not reference those libraries -- instead clang is generating code that depends on the libraries of the compiler with which it was built.

/home/btorpey $ which clang
/shared/clangwgcc490/Release+Asserts/bin/clang
/home/btorpey $ clang --version
clang version 3.6.0 (trunk 214514) (llvm/trunk 214513)
Target: x86_64-unknown-linux-gnu
Thread model: posix
/home/btorpey $ clang -print-search-dirs
programs: =/shared/clangwgcc490/Release+Asserts/bin:/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../x86_64-redhat-linux/bin
libraries: =/shared/clangwgcc490/Release+Asserts/bin/../lib/clang/3.6.0:/usr/lib/gcc/x86_64-redhat-linux/4.4.7:/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64:/lib/../lib64:/usr/lib/../lib64:/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../..:/shared/clangwgcc490/Release+Asserts/bin/../lib:/lib:/usr/lib
/home/btorpey $ 

So, as to your statement "Clang is trying to act in exactly the same way as the "system" compiler", I submit that that is the wrong goal -- clang should just act "like itself" and generate code that is internally consistent with the libraries used by the compiler.

I understand that we can pass the required libraries to the linker, but that is a problem for a couple of reasons:

Last but not least, I tried rebuilding with the -with-gcc-toolchain optiion, but no joy there (let me know if you want the complete output), but that appears to crash gcc:

]0;[/shared/clang] /shared/clang $ export PATH=/usr/local/bin:$PATH
]0;[/shared/clang] /shared/clang $ gcc --version
gcc (GCC) 4.9.0
Copyright (C) 2014 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.

]0;[/shared/clang] /shared/clang $ make clean dist-clean;CFLAGS="-std=gnu89" ../llvm/configure --prefix=/build/share/clang --enable-optimized --enable-targets=x86_64 --with-gcc-toolchain=/usr/local && make
make: *** No rule to make target `clean'.  Stop.
checking for clang... no
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables... 
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for clang++... no
checking for g++... g++
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking how to run the C preprocessor... gcc -E
checking whether GCC or Clang is our host compiler... gcc
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking target system type... x86_64-unknown-linux-gnu
checking type of operating system we're going to host on... Linux
checking type of operating system we're going to target... Linux
checking target architecture... x86_64
checking whether GCC is new enough... yes
checking optimization flags... -O3
checking for GNU make... make
checking whether ln -s works... yes
checking for nm... /usr/bin/nm
checking for cmp... /usr/bin/cmp
checking for cp... /bin/cp
checking for date... /bin/date
checking for find... /usr/bin/find
checking for grep... /bin/grep
checking for mkdir... /bin/mkdir
checking for mv... /bin/mv
checking for ranlib... ranlib
checking for ar... ar
checking for rm... /bin/rm
checking for sed... /bin/sed
checking for tar... /bin/tar
checking for pwd... /bin/pwd
checking for dot... /usr/bin/dot
checking for a BSD-compatible install... /usr/bin/install -c
checking for bzip2... /usr/bin/bzip2
checking for cat... /bin/cat
checking for doxygen... /usr/bin/doxygen
checking for groff... /usr/bin/groff
checking for gzip... /usr/bin/gzip
checking for pdfroff... no
checking for zip... /usr/bin/zip
checking for ocamlc... no
checking for ocamlopt... no
checking for ocamldep... no
checking for ocamldoc... no
checking for gas... no
checking for as... /usr/bin/as
checking for linker version... 2.20.51.0.2
checking for compiler -Wl,-R<path> option... yes
checking for compiler -rdynamic option... yes
checking for compiler -Wl,--version-script option... yes
checking for grep that handles long lines and -e... (cached) /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking errno.h usability... yes
checking errno.h presence... yes
checking for errno.h... yes
checking tool compatibility... ok
checking optional compiler flags... -Wno-variadic-macros -Wno-missing-field-initializers   -Wno-maybe-uninitialized
checking for python... /usr/bin/python
checking for python >= 2.5... /usr/bin/python (2.6.6)
checking for sin in -lm... yes
checking for library containing dlopen... -ldl
checking for library containing clock_gettime... -lrt
checking for library containing setupterm... -ltinfo
checking for library containing el_init... no
checking for library containing mallinfo... none required
checking for pthread_mutex_init in -lpthread... yes
checking for library containing pthread_mutex_lock... none required
checking for library containing pthread_rwlock_init... none required
checking for library containing pthread_getspecific... none required
checking for compress2 in -lz... yes
checking for xml2-config... xml2-config
checking for libxml2 includes... -I/usr/include/libxml2
checking for xmlReadFile in -lxml2... yes
checking for dirent.h that defines DIR... yes
checking for library containing opendir... none required
checking for MAP_ANONYMOUS vs. MAP_ANON... yes
checking whether stat file-mode macros are broken... no
checking for sys/wait.h that is POSIX.1 compatible... yes
checking whether time.h and sys/time.h may both be included... yes
checking how to run the C++ preprocessor... g++ -E
checking cxxabi.h usability... yes
checking cxxabi.h presence... yes
checking for cxxabi.h... yes
checking dlfcn.h usability... yes
checking dlfcn.h presence... yes
checking for dlfcn.h... yes
checking execinfo.h usability... yes
checking execinfo.h presence... yes
checking for execinfo.h... yes
checking fcntl.h usability... yes
checking fcntl.h presence... yes
checking for fcntl.h... yes
checking for inttypes.h... (cached) yes
checking link.h usability... yes
checking link.h presence... yes
checking for link.h... yes
checking malloc.h usability... yes
checking malloc.h presence... yes
checking for malloc.h... yes
checking setjmp.h usability... yes
checking setjmp.h presence... yes
checking for setjmp.h... yes
checking signal.h usability... yes
checking signal.h presence... yes
checking for signal.h... yes
checking for stdint.h... (cached) yes
checking termios.h usability... yes
checking termios.h presence... yes
checking for termios.h... yes
checking for unistd.h... (cached) yes
checking utime.h usability... yes
checking utime.h presence... yes
checking for utime.h... yes
checking sys/mman.h usability... yes
checking sys/mman.h presence... yes
checking for sys/mman.h... yes
checking sys/param.h usability... yes
checking sys/param.h presence... yes
checking for sys/param.h... yes
checking sys/resource.h usability... yes
checking sys/resource.h presence... yes
checking for sys/resource.h... yes
checking sys/time.h usability... yes
checking sys/time.h presence... yes
checking for sys/time.h... yes
checking sys/uio.h usability... yes
checking sys/uio.h presence... yes
checking for sys/uio.h... yes
checking sys/ioctl.h usability... yes
checking sys/ioctl.h presence... yes
checking for sys/ioctl.h... yes
checking malloc/malloc.h usability... no
checking malloc/malloc.h presence... no
checking for malloc/malloc.h... no
checking mach/mach.h usability... no
checking mach/mach.h presence... no
checking for mach/mach.h... no
checking valgrind/valgrind.h usability... yes
checking valgrind/valgrind.h presence... yes
checking for valgrind/valgrind.h... yes
checking fenv.h usability... yes
checking fenv.h presence... yes
checking for fenv.h... yes
checking whether FE_ALL_EXCEPT is declared... yes
checking whether FE_INEXACT is declared... yes
checking pthread.h usability... yes
checking pthread.h presence... yes
checking for pthread.h... yes
checking zlib.h usability... yes
checking zlib.h presence... yes
checking for zlib.h... yes
checking CrashReporterClient.h usability... no
checking CrashReporterClient.h presence... no
checking for CrashReporterClient.h... no
checking __crashreporter_info__... no
checking for HUGE_VAL sanity... yes
checking for pid_t... yes
checking for size_t... yes
checking whether struct tm is in sys/time.h or time.h... time.h
checking for int64_t... yes
checking for uint64_t... yes
checking for backtrace... yes
checking for ceilf... yes
checking for floorf... yes
checking for roundf... yes
checking for rintf... yes
checking for nearbyintf... yes
checking for getcwd... yes
checking for powf... yes
checking for fmodf... yes
checking for strtof... yes
checking for round... yes
checking for log... yes
checking for log2... yes
checking for log10... yes
checking for exp... yes
checking for exp2... yes
checking for getpagesize... yes
checking for getrusage... yes
checking for getrlimit... yes
checking for setrlimit... yes
checking for gettimeofday... yes
checking for isatty... yes
checking for mkdtemp... yes
checking for mkstemp... yes
checking for mktemp... yes
checking for posix_spawn... yes
checking for pread... yes
checking for realpath... yes
checking for sbrk... yes
checking for setrlimit... (cached) yes
checking for strerror... yes
checking for strerror_r... yes
checking for setenv... yes
checking for strtoll... yes
checking for strtoq... yes
checking for sysconf... yes
checking for malloc_zone_statistics... no
checking for setjmp... yes
checking for longjmp... yes
checking for sigsetjmp... no
checking for siglongjmp... yes
checking for writev... yes
checking for futimes... yes
checking for futimens... yes
checking if printf has the %a format character... yes
checking for srand48/lrand48/drand48 in <stdlib.h>... yes
checking whether arc4random is declared... no
checking whether strerror_s is declared... no
checking for isnan in <math.h>... yes
checking for isnan in <cmath>... yes
checking for std::isnan in <cmath>... yes
checking for isinf in <math.h>... yes
checking for isinf in <cmath>... yes
checking for std::isinf in <cmath>... yes
checking for finite in <ieeefp.h>... no
checking for stdlib.h... (cached) yes
checking for unistd.h... (cached) yes
checking for getpagesize... (cached) yes
checking for working mmap... yes
checking for mmap of files... yes
checking if /dev/zero is needed for mmap... no
checking for GCC atomic builtins... yes
checking for 32-bit userspace on 64-bit system... no
checking for __dso_handle... yes
checking for compiler -fvisibility-inlines-hidden option... yes
configure: creating ./config.status
config.status: creating include/llvm/Config/Targets.def
config.status: creating include/llvm/Config/AsmPrinters.def
config.status: creating include/llvm/Config/AsmParsers.def
config.status: creating include/llvm/Config/Disassemblers.def
config.status: creating Makefile.config
config.status: creating llvm.spec
config.status: creating docs/doxygen.cfg
config.status: creating tools/clang/docs/doxygen.cfg
config.status: creating bindings/ocaml/llvm/META.llvm
config.status: creating include/llvm/Config/config.h
config.status: creating include/llvm/Config/llvm-config.h
config.status: creating include/llvm/Support/DataTypes.h
config.status: creating tools/clang/include/clang/Config/config.h
config.status: executing setup commands
config.status: executing Makefile commands
config.status: executing Makefile.common commands
config.status: executing examples/Makefile commands
config.status: executing lib/Makefile commands
config.status: executing test/Makefile commands
config.status: executing test/Makefile.tests commands
config.status: executing unittests/Makefile commands
config.status: executing tools/Makefile commands
config.status: executing utils/Makefile commands
config.status: executing projects/Makefile commands
config.status: executing bindings/Makefile commands
config.status: executing bindings/ocaml/Makefile.ocaml commands
llvm[0]: Constructing LLVMBuild project information.
...
llvm[4]: Compiling RecursiveASTVisitorTest.cpp for Release+Asserts build
g++: internal compiler error: Killed (program cc1plus)
0x409fd4 execute
    ../../gcc/gcc.c:2848
0x40a384 do_spec_1
    ../../gcc/gcc.c:4652
0x40cc46 process_brace_body
    ../../gcc/gcc.c:5935
0x40cc46 handle_braces
    ../../gcc/gcc.c:5849
0x40b1f9 do_spec_1
    ../../gcc/gcc.c:5306
0x40cc46 process_brace_body
    ../../gcc/gcc.c:5935
0x40cc46 handle_braces
    ../../gcc/gcc.c:5849
0x40b1f9 do_spec_1
    ../../gcc/gcc.c:5306
0x40af63 do_spec_1
    ../../gcc/gcc.c:5421
0x40cc46 process_brace_body
    ../../gcc/gcc.c:5935
0x40cc46 handle_braces
    ../../gcc/gcc.c:5849
0x40b1f9 do_spec_1
    ../../gcc/gcc.c:5306
0x40cc46 process_brace_body
    ../../gcc/gcc.c:5935
0x40cc46 handle_braces
    ../../gcc/gcc.c:5849
0x40b1f9 do_spec_1
    ../../gcc/gcc.c:5306
0x40cc46 process_brace_body
    ../../gcc/gcc.c:5935
0x40cc46 handle_braces
    ../../gcc/gcc.c:5849
0x40b1f9 do_spec_1
    ../../gcc/gcc.c:5306
0x40cc46 process_brace_body
    ../../gcc/gcc.c:5935
0x40cc46 handle_braces
    ../../gcc/gcc.c:5849
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
/bin/rm: cannot remove `/shared/clang/tools/clang/unittests/Tooling/Release+Asserts/RecursiveASTVisitorTest.d.tmp': No such file or directory
make[4]: *** [/shared/clang/tools/clang/unittests/Tooling/Release+Asserts/RecursiveASTVisitorTest.o] Error 1
make[4]: Leaving directory `/shared/clang/tools/clang/unittests/Tooling'
make[3]: *** [Tooling/.makeall] Error 2
make[3]: Leaving directory `/shared/clang/tools/clang/unittests'
make[2]: *** [all] Error 1
make[2]: Leaving directory `/shared/clang/tools/clang'
make[1]: *** [clang/.makeall] Error 2
make[1]: Leaving directory `/shared/clang/tools'
make: *** [all] Error 1
rnk commented 10 years ago

Reid:

Dont get me wrong -- I’m nuts about clang in general, and especially the static analysis, sanitizers and related bits that help people, including us, build software that is more reliable and correct. And I’m very grateful to those, like you, who make that possible.

Thanks!

With all due respect, however, what you suggest is a workaround, not a fix, and not a particularly good one either -- it requires manually adding the library search paths, not of the compiler, but of the compiler that the compiler was built with. Manually adding library search paths would be borked to begin with, but having to add the libraries that the compiler was built with is completely ridiculous.

I don't think this is too bad, it's just one more linker flag on top of installing and using a new version of GCC, which is already a tall order. Setting an rpath is the standard way of using any library that is not installed into /usr/lib. Clang is just a normal application that wants to use a newer copy of libstdc++.

Please reopen this so that this bug (and it is a bug) is visible to someone who wants to work on fixes for the compiler.

What action needs to be taken to make this easy? This really has more to do with what gcc does when you compile a C++ app with it. It will add -L flags to the link line, but it will not set an rpath.

In the meantime, I’m rebuilding clang with the native compiler (gcc 4.4.7) and hope that will work. I’ll post back here what I find out.

OK, clang wont build w/gcc 4.4.7 -- not surprising, as that's well documented.

OTOH, that does make it more egregious that clang insists on using that compiler as its default search path.

Clang is trying to act in exactly the same way as the "system" compiler, which it assumes is installed in /usr, and will search /usr/include, /usr/lib, and a variety of paths off of there. If you have a more modern gcc and libstdc++ toolchain that you want it to use, I believe you can set GCC_INSTALL_PREFIX at configure time. I don't know how to do that in autoconf, though. My best guess is --with-gcc-toolchain.

llvmbot commented 10 years ago

OK, clang wont build w/gcc 4.4.7 -- not surprising, as that's well documented.

OTOH, that does make it more egregious that clang insists on using that compiler as its default search path.

llvmbot commented 10 years ago

Reid:

Dont get me wrong -- I’m nuts about clang in general, and especially the static analysis, sanitizers and related bits that help people, including us, build software that is more reliable and correct. And I’m very grateful to those, like you, who make that possible.

With all due respect, however, what you suggest is a workaround, not a fix, and not a particularly good one either -- it requires manually adding the library search paths, not of the compiler, but of the compiler that the compiler was built with. Manually adding library search paths would be borked to begin with, but having to add the libraries that the compiler was built with is completely ridiculous.

Please reopen this so that this bug (and it is a bug) is visible to someone who wants to work on fixes for the compiler.

In the meantime, I’m rebuilding clang with the native compiler (gcc 4.4.7) and hope that will work. I’ll post back here what I find out.

Best Regards,

Bill Torpey

rnk commented 10 years ago

I tried to document this harder in r214565.

rnk commented 10 years ago

Set the rpath instead. Add -Wl,-rpath,/usr/local/lib64 or something like it to your link flags.

This is documented in http://llvm.org/docs/GettingStarted.html#getting-a-modern-host-c-toolchain, but it could probably be improved.

llvmbot commented 2 months ago

@llvm/issue-subscribers-clang-driver

Author: None (llvmbot)

| | | | --- | --- | | Bugzilla Link | [20510](https://llvm.org/bz20510) | | Version | trunk | | OS | Linux | | Attachments | [config log](https://user-images.githubusercontent.com/60944935/143749817-ad91c973-2f46-429a-bf28-9e0def3a6afb.gz) | | Reporter | LLVM Bugzilla Contributor | | CC | @DougGregor,@zygoloid,@rnk,@viccpp | ## Extended Description The symptom of this problem is that clang builds can fail with an error similar to: ``` clang++: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.18' not found (required by clang++) ``` This appears to be because clang does not "remember" the search path it was built with. In this case, clang was built w/gcc 4.9.0, which is installed in `/usr/local`. ```console /shared/clang $ /usr/local/bin/gcc -print-search-dirs install: /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/ programs: =/usr/local/libexec/gcc/x86_64-unknown-linux-gnu/4.9.0/:/usr/local/libexec/gcc/x86_64-unknown-linux-gnu/4.9.0/:/usr/local/libexec/gcc/x86_64-unknown-linux-gnu/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../x86_64-unknown-linux-gnu/bin/x86_64-unknown-linux-gnu/4.9.0/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../x86_64-unknown-linux-gnu/bin/ libraries: =/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../x86_64-unknown-linux-gnu/lib/x86_64-unknown-linux-gnu/4.9.0/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../x86_64-unknown-linux-gnu/lib/../lib64/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../x86_64-unknown-linux-gnu/4.9.0/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../lib64/:/lib/x86_64-unknown-linux-gnu/4.9.0/:/lib/../lib64/:/usr/lib/x86_64-unknown-linux-gnu/4.9.0/:/usr/lib/../lib64/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../../x86_64-unknown-linux-gnu/lib/:/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.9.0/../../../:/lib/:/usr/lib/ /shared/clang $ Release+Asserts/bin/clang++ -print-search-dirs programs: =/shared/clang/Release+Asserts/bin:/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../x86_64-redhat-linux/bin libraries: =/shared/clang/Release+Asserts/bin/../lib/clang/3.6.0:/usr/lib/gcc/x86_64-redhat-linux/4.4.7:/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64:/lib/../lib64:/usr/lib/../lib64:/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../..:/shared/clang/Release+Asserts/bin/../lib:/lib:/usr/lib ``` As you can see, clang is picking up the library search paths from the system default compiler (gcc 4.4), rather than the search paths with which clang was built (gcc 4.9). Using `LD_LIBRARY_PATH` is not an option -- our build scripts deliberately unset `LD_LIBRARY_PATH` before linking to ensure that only specifically named library paths are searched. I'm attaching the config.log, which appears to show clang picking up gcc 4.9.0 for the build (as expected). The command used to build clang is: ``` make clean distclean;CFLAGS="-std=gnu89" ../llvm/configure --prefix=/build/share/clang --enable-optimized --enable-targets=x86_64 && make ``` At this point I'm not necessarily looking for a fix, but an indication whether this is a legitimate problem with clang, or possibly a problem on our end. Thanks!