Linking g++ 4.8 to libstdc++ - c++

I downloaded and built gcc 4.8.1 on my desktop, running 64-bit Ubuntu 12.04. I built it out of source, like the docs recommend, and with the commands
../../gcc-4.8.1/configure --prefix=$HOME --program-suffix=-4.8
make
make -k check
make install
It seemed to pass all the tests, and I installed everything into my home directory w/ the suffix -4.8 to distinguish from the system gcc, which is version 4.6.3.
Unfortunately when I compile c++ programs using g++-4.8 it links to the system libc and libstdc++ rather than the newer ones compiled from gcc-4.8.1. I downloaded and built gcc 4.8 because I wanted to play around with the new C++11 features in the standard library, so this behaviour is definitely not what I wanted. What can I do to get gcc-4.8 to automatically link to the standard libraries that came with it rather than the system standard libraries?

When you link with your own gcc you need to add an extra run-time linker search path(s) with -Wl,-rpath,$(PREFIX)/lib64 so that at run-time it finds the shared libraries corresponding to your gcc.
I normally create a wrapper named gcc and g++ in the same directory as gcc-4.8 and g++-4.8 which I invoke instead of gcc-4.8 and g++-4.8, as prescribed in Dynamic linker is unable to find GCC libraries:
#!/bin/bash
exec ${0}SUFFIX -Wl,-rpath,PREFIX/lib64 "$#"
When installing SUFFIX and PREFIX should be replaced with what was passed to configure:
cd ${PREFIX}/bin && rm -f gcc g++ c++ gfortran
sed -e 's#PREFIX#${PREFIX}#g' -e 's#SUFFIX#${SUFFIX}#g' gcc-wrapper.sh > ${PREFIX}/bin/gcc
chmod +x ${PREFIX}/bin/gcc
cd ${PREFIX}/bin && ln gcc g++ && ln gcc c++ && ln gcc gfortran
(gcc-wrapper.sh is that bash snippet).
The above solution does not work with some versions of libtool because g++ -Wl,... -v assumes linking mode and fails with an error.
A better solution is to use specs file. Once gcc/g++ is built, invoke the following command to make gcc/g++ add -rpath to the linker command line (replace ${PREFIX}/lib64 as necessary):
g++ -dumpspecs | awk '/^\*link:/ { print; getline; print "-rpath=${PREFIX}/lib64", $0; next } { print }' > $(dirname $(g++ -print-libgcc-file-name))/specs

I just had the same problem when building gcc-4.8.2. I don't have root access on that machine and therefore need to install to my home directory. It took several attempts before I figured out the magic required to get this to work so I will reproduce it here so other people will have an easier time. These are the commands that I used to configure gcc:
prefix=/user/grc/packages
export LDFLAGS=-Wl,-rpath,$prefix/lib
export LD_RUN_PATH=$prefix/lib
export LD_LIBRARY_PATH=$prefix/lib
../../src/gmp-4.3.2/configure --prefix=$prefix
../../src/mpfr-2.4.2/configure --prefix=$prefix
../../src/mpc-0.8.1/configure --prefix=$prefix --with-mpfr=$prefix --with-gmp=$prefix
../../src/gcc-4.8.2/configure --prefix=$prefix --with-mpfr=$prefix --with-gmp=$prefix --with-mpc=$prefix --enable-languages=c,c++
That got me a working binary but any program I built with that version of g++ wouldn't run correctly unless I built it with the -Wl,-rpath,$prefix/lib64 option. It is possible to get g++ to automatically add that option by providing a specs file. If you run
strace g++ 2>&1 | grep specs
you can see which directories it checks for a specs file. In my case it was $prefix/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/specs so I ran g++ -dumpspecs to create a new specs file:
cd $prefix/lib/gcc/x86_64-unknown-linux-gnu/4.8.2
$prefix/bin/g++ -dumpspecs > xx
mv xx specs
and then edited that file to provide the -rpath option. Search for the lines like this:
*link_libgcc:
%D
and edit to add the rpath option:
*link_libgcc:
%D -rpath /user/grc/packages/lib/%M
The %M expands to either ../lib or ../lib64 depending on whether you are building a 32-bit or a 64-bit executable.
Note that when I tried this same trick on an older gcc-4.7 build it didn't work because it didn't expand the %M. For older versions you can remove the %M and just hardcode lib or lib64 but that is only a viable solution if you only ever build 32-bit executables (with lib) or only ever build 64-bit executables (with lib64).

gcc -print-search-dirs will tell you where your compiler is looking for runtime libraries, etc. You can override this with the -B<prefix> option.

Related

How to change default GCC compiler to be used with MPI on Linux CentOS

I have two GCC compilers installed on a Linux (CentOS) machine. The old version of GCC (4.4.7) is in the default folder (came with CentOS) and the newer one that I intend to use is in /usr/local/gcc/4.9.3/. My code utilizes MPI and LAPACK/LAPACKE/BLAS libraries and with the old GCC I used to compile source (for example “main.cpp”) like this:
mpiCC main.cpp -o main -L/home/USER1/lapack-3.6.1 -llapacke -llapack -lblas -lm –Wall
This still invokes the old GCC 4.4.7. What should I modify so the above MPI compilation (mpiCC) invokes GCC 4.9.3 executable from the new location at /usr/local/gcc/4.9.3/el6/bin/ ?
From MPICH Installer's Guide version 3.2 (page 6):
"The MPICH configure step will attempt to find the C, C++, and Fortran compilers for you, but if you either want to override the default or need to specify a compiler that configure doesn't recognize, you can specify them on the command line [...]. For example, to select the Intel compilers instead of the GNU compilers on a system with both, use"
./configure CC=icc CXX=icpc F77=ifort FC=ifort ...
Is there a way to dicriminate between different version of GCC compilers in ./configure ?
I guess mpiCC uses the first gcc compiler found in the $PATH variable.
You should be able to set the new version of gcc by running:
PATH="/usr/local/gcc/4.9.3/el6/bin:$PATH" mpiCC main.cpp -o main -L/home/USER1/lapack-3.6.1 -llapacke -llapack -lblas -lm –Wall
If you really want two versions of GCC installed at the same time and use both of them here is a good link that explains how to do this:
http://gcc.gnu.org/faq.html#multiple
Finally found how. Here is the recipe:
1) check your if you shell is bash, if not set it to bash: $ echo $SHELL
/bin/tcsh
It was tcsh and needed to be set to bash.
2) Switch to bash: $ bash
bash-4.1$
3) Add new version of GCC to the front of the PATH:
bash-4.1$ export PATH=/usr/local/gcc/4.9.3/el6/bin:$PATH
4) Check the PATH: bash-4.1$ echo $PATH
/usr/local/gcc/4.9.3/el6/bin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin
5) Check version of GCC used (It picks up the first GCC from the PATH):
bash-4.1$ gcc --version
gcc (GCC) 4.9.3
Note: this is just for the current session.

How to force clang to use some library by default?

I build clang by clang against libc++, libc++abi, compiler-rt in the following steps:
To download (and update) llvm and sub-projects I use the following script:
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
cd llvm/tools
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
svn co http://llvm.org/svn/llvm-project/clang-tools-extra/trunk clang/tools/extra
svn co http://llvm.org/svn/llvm-project/lldb/trunk lldb
svn co http://llvm.org/svn/llvm-project/lld/trunk lld
svn co http://llvm.org/svn/llvm-project/polly/trunk polly
cd ../projects/
svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt
svn co http://llvm.org/svn/llvm-project/libunwind/trunk libunwind
svn co http://llvm.org/svn/llvm-project/openmp/trunk openmp
svn co http://llvm.org/svn/llvm-project/libcxxabi/trunk libcxxabi
svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx
First of all I build llvm, clang, libunwind against libgcc and libstdc++ using gcc and install them in /usr/local. In all the following steps except the last one I use this fresh clang/clang++.
Then I separately build libunwind, both the 32-bit and 64-bit versions (they are essential, as will be further, because asan needs the 32-bit versions of some libraries during the final compilation of the whole project tree) and install it in /usr/local/lib and /usr/local/lib32 correspondingly (also I update LD_LIBRARY_PATH respectively).
Build libcxxrt ABI library both 32-bit and 64-bit versions and install them properly.
Build libcxx against libcxxrt both 32-bit and 64-bit versions and install them properly.
Then build libc++abi against libc++ both 32-bit and 64-bit versions and install them properly.
Then build libc++ against libc++abi both 32-bit and 64-bit versions and install them properly over the previous version linked to libcxxrt.
After all I build the whole project tree against libc++, libc++abi, libunwind, compiler-rt and install it over old clang in /usr/local.
(I am almost sure that no step is redundant here.)
At the final step I have a problem: I have to add extra parameters to the linker (I add them to CMAKE_EXE_LINKER_FLAGS and CMAKE_SHARED_LINKER_FLAGS) -lunwind and -lc++abi. Moreover, every time I use the resulting clang++ with -stdlib=libc++ and compiler-rt (or, equally, CLANG_DEFAULT_CXX_STDLIB=libc++ and CLANG_DEFAULT_RTLIB=compiler-rt) in my projects I have to do it over and over. It annoying. Say Qt Creator generated project's CMakeLists.txt should be corrected by hand or by cmake-gui.
How to make clang driver to automatically specify these options to ld at runtime? Is there something similar to RPATH mechanism? Or is there some specific CMake variable (specified before llvm building process) to achieve desired behaviour?
Can I use RPATH for my purposes?
Surely I don't want to make some bash-script like wrappers (similar to clang++-libc++) to specify additional parameters. I want the libraries to be hardcoded somewhere in the clang binary itself.
There are a couple of workarounds have been suggested. I ended up with the following workaround:
mkdir build
cd build
# backup:
cp -vaf /usr/local/lib/libc++.{a,so.1.0} /usr/local/lib/libc++abi.{a,so.1.0} /usr/local/lib/libunwind.{a,so.1.0} .
clang -shared -fPIC -pthread -o fuse.so -Wl,--whole-archive libc++.a libc++abi.a libunwind.a -Wl,--no-whole-archive -ldl -lm
ar x libc++.a
ar x libc++abi.a
ar x libunwind.a
ar rc fuse.a *.o
sudo chown root:root fuse.*
sudo cp -vaf fuse.so /usr/local/lib/
sudo ln -svf /usr/local/lib/libc++.so.1 /usr/local/lib/fuse.so
sudo cp -vaf fuse.a /usr/local/lib/
sudo mv -vf /usr/local/lib/libc++.a /usr/local/lib/libc++.a.bak
sudo ln -svf /usr/local/lib/libc++.a /usr/local/lib/fuse.a
It merges all the libraries used (libc++, libc++abi and libunwind) into the one single *.a or *.so file. Then libc++.a and libc++.so are replaced with (links to) resulting assemblied files, saving a previous versions for possible backup.
It works perfectly for me.
But this is not the answer. Maybe someday clang will not have such a problem right from the box.

clang++ can not locate c++ header and library

My OS is OS X 10.10.2 and the default compiler for C is clang.
But this version of clang does not support ubsan (undefined sanitizer) which comes in the 3.4 release of clang. I also want to use KLEE to do some analysis. AFAIK KLEE works well with LLVM-<=3.4. I decided to install
llvm-3.4 and clang-3.4 in my laptop.
After installing clang-3.4 in my system, I encountered a issue that the compiler can not locate the c++ header file. I installed clang-3.4 in /usr/local and I can find the c++ header file in /usr/local/include/c++/4.8.4. How can I add this directory to the search path of clang-3.4 and also the c++ library?
for the following demo code:
#include <iostream>
using namespace std;
int main(){
cout<<"Hellow World\n";
return 0;
}
When I compile it using command clang++ test.cpp, I got the error
test1.cpp:1:10: fatal error: 'iostream' file not found
#include <iostream>
^
1 error generated.
Below is the version of clang I used
clang version 3.4 (tags/RELEASE_34/final)
Target: x86_64-apple-darwin14.1.0
Thread model: posix
I used the following shell command to install llvm-3.4 and clang-3.4:
wget http://llvm.org/releases/3.4/llvm-3.4.src.tar.gz \
http://llvm.org/releases/3.4/clang-3.4.src.tar.gz \
http://llvm.org/releases/3.4/clang-tools-extra-3.4.src.tar.gz \
http://llvm.org/releases/3.4/compiler-rt-3.4.src.tar.gz
tar zxf llvm-3.4.src.tar.gz
tar zxf clang-3.4.src.tar.gz -C llvm-3.4/tools
mv llvm-3.4/tools/clang{-3.4,}
tar zxf clang-tools-extra-3.4.src.tar.gz -C llvm-3.4/tools/clang/tools
mv llvm-3.4/tools/clang/tools/{clang-tools-extra-3.4,extra}
tar zxf compiler-rt-3.4.src.tar.gz -C llvm-3.4/projects
mv llvm-3.4/projects/compiler-rt{-3.4,}
cd llvm-3.4
./configure --enable-cxx11 \
--enable-bindings=none --enable-shared \
--enable-debug-symbols --enable-optimized
make
make install
Now I have two versions of clang in my OS, one is the default one shipped with OSX located in /usr/bin and the other is clang-3.4 located in /usr/local/bin. The previous one can find the C++ header file while the latter can not.
Did you read the user documentation of clang notably the section on command line options ? BTW, current (march 2015) version of clang is 3.6!
For C++ code you should use the clang++ command, not the clang command.
You might pass -I and -L options to clang++ but you might perhaps have misinstalled your clang compiler.
You should be aware of the -v and -H options of clang or clang++ ; they could be useful, at least to understand more your issue.
addenda
BTW, a program reported to work with Clang 3.4 is extremely likely to work with a more modern version, like Clang 3.5 or 3.6
You probably have a PATH issue; you should have configure -d your Clang-3.4 & LLvm-3.4 programs with --program-suffix=-my-3.4 (if you do that, repeat your entire compiler build and installation) and you probably should run /usr/local/bin/clang++-my-3.4 ; maybe you also need some --with-gcc-toolchain additional configure option.
I'm pretty sure that you should be able to try to compile or use your mysterious software requiring Clang-3.4 with a more modern version like 3.5 or 3.6 ; your MacOSX 10.10.2 is rumored to have a Clang-3.5 based system compiler, it very probably is able to compile and work with your mysterious software.

why self built g++ compiler fails to compile my code

I wanted to use latest g++ compiler(4.9.1) on suse linux, but suse only supports an older g++ version. So, I took a latest source code from one of the gnu mirror sites and compiled it myself. Everything went fine. But when I tried to compile my test code using the built g++, the compilation fails with error,
"/root/home/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/os_defines.h:39:22: fatal error: features.h: No such file or directory".
I can find a "features.h" in "/root/home/include/c++/4.9.1/parallel", but I feel that it should be there in "/root/home/include/c++/4.9.1/" itself.
I copied "/root/home/include/c++/4.9.1/parallel/features.h" to "/root/home/include/c++/4.9.1/" just to see what happens. Now it complains with error "whcar.h" not found.
Have I missed something.
Here are the steps I followed to build g++.
1. /root/home/gcc_build/objdir# ../gcc-4.9.1/configure --prefix=/root/home/ --disable-multilib
2. /root/home/gcc_build/objdir# make -j16
3. /root/home/gcc_build/objdir# make install
4. /root/home/gcc_build/test# /root/home/bin/g++ --sysroot /root/home -m64 test.cpp
I resolved the issue by removing sysroot option and pointing c++ include and library path to my home directory. One thing I noticed was that the g++ source does not come with libc and c header files, and libc has to be installed seperately. But with sysroot option, g++ was trying to look all the header files in my home directory.
Below is the command I used to successfully compile the code.
/root/home/bin/g++ -I /root/home/include/c++/4.9.1 -L /root/home/lib64 -Wl,--rpath=/root/home/lib64 --std=c++0x -m64 test.cpp
Take a look at the GCC Directory Options. It is important to use the correct "specifier" as well (-isystem, -L, -B, -I etc)

How can I set rpath on gcc binaries during bootstrap?

I am trying to build gcc 4.7.2 using a custom prefix $PREFIX
I have built and installed all the prerequisites into my prefix location, and then successfully configured, built and installed gcc.
The problem that I now have is that $PREFIX is not in the library search path, and therefore the shared libraries cannot be found.
$PREFIX/bin $ ./g++ ~/main.cpp
$PREFIX/libexec/gcc/x86_64-suse-linux/4.7.2/cc1plus: \
error while loading shared libraries: \
libcloog-isl.so.1: \
cannot open shared object file: No such file or directory
What works, but isn't ideal
If I export LD_LIBRARY_PATH=$PREFIX/lib then it works, but I'm looking for something which works without having to set environment variables.
If I use patchelf to set the RPATH on all the gcc binaries then it also works; however this involves searching out all elf binaries and iterating over them calling patchelf, I would rather have something more permanent.
What I think would be ideal for my purposes
So I'm hoping there is a way to have -Wl,-rpath,$PREFIX/lib passed to make during the build process.
Since I know the paths won't need to be changed this seems like the most robust solution, and can be also be used for when we build the next gcc version.
Is configuring the build process to hard code the RPATH possible?
What I have tried, but doesn't work
Setting LDFLAGS_FOR_TARGET prior to calling configure:
All of these fail:
export LDFLAGS_FOR_TARGET="-L$PREFIX/lib -R$PREFIX/lib"
export LDFLAGS_FOR_TARGET="-L$PREFIX/lib"
export LDFLAGS_FOR_TARGET="-L$PREFIX/lib -Wl,-rpath,$PREFIX/lib"
Setting LDFLAGS prior to calling configure:
export LDFLAGS="-L$PREFIX/lib -Wl,-rpath,$PREFIX/lib"
In any event I worry that these will override any of the LDFLAGS gcc would have had, so I'm not sure these are a viable option even if they could be made to work?
My configure line
For completeness here is the line I pass to configure:
./configure \
--prefix=$PREFIX \
--build=x86_64-suse-linux \
--with-pkgversion='SIG build 12/10/2012' \
--disable-multilib \
--enable-cloog-backend=isl \
--with-mpc=$PREFIX \
--with-mpfr=$PREFIX \
--with-gmp=$PREFIX \
--with-cloog=$PREFIX \
--with-ppl=$PREFIX \
--with-gxx-include-dir=$PREFIX/include/c++/4.7.2
I've found that copying the source directories for gmp, mpfr, mpc, isl, cloog, etc. into the top level gcc source directory (or using symbolic links with the same name) works everywhere. This is in fact the preferred way.
You need to copy (or link) to those source directory names without the version numbers for this to work.
The compilers do not need LD_LIBRARY_PATH (although running applications built with the compilers will need an LD_LIBRARY_PATH to the $PREFIX/lib64 or something like that - but that's different)
Start in a source directory where you'll keep all your sources.
In this source directory you have your gcc directory either by unpacking a tarball or svn...
I use subversion.
Also in this top level directory you have, say, the following source tarballs:
gmp-5.1.0.tar.bz2
mpfr-3.1.1.tar.bz2
mpc-1.0.1.tar.gz
isl-0.11.1.tar.bz2
cloog-0.18.0.tar.gz
I just download these and update to the latest tarballs periodically.
In script form:
# Either:
svn checkout svn://gcc.gnu.org/svn/gcc/trunk gcc_work
# Or:
bunzip -c gcc-4.8.0.tar.bz2 | tar -xvf -
mv gcc-4.8.0 gcc_work
# Uncompress sources.. (This will produce version numbered directories).
bunzip -c gmp-5.1.0.tar.bz2 | tar -xvf -
bunzip -c mpfr-3.1.1.tar.bz2 | tar -xvf -
gunzip -c mpc-1.0.1.tar.gz | tar -xvf -
bunzip -c isl-0.11.1.tar.bz2 | tar -xvf -
gunzip -c cloog-0.18.0.tar.gz | tar -xvf -
# Link outside source directories into the top level gcc directory.
cd gcc_work
ln -s ../gmp-5.1.0 gmp
ln -s ../mpfr-3.1.1 mpfr
ln -s ../mpc-1.0.1 mpc
ln -s ../isl-0.11.1 isl
ln -s ../cloog-0.18.0 cloog
# Get out of the gcc working directory and create a build directory. I call mine obj_work.
# I configure the gcc binary and other outputs to be bin_work in the top level directory. Your choice. But I have this:
# home/ed/projects
# home/ed/projects/gcc_work
# home/ed/projects/obj_work
# home/ed/projects/bin_work
# home/ed/projects/gmp-5.1.0
# home/ed/projects/mpfr-3.1.1
# home/ed/projects/mpc-1.0.1
# home/ed/projects/isl-0.11.1
# home/ed/projects/cloog-0.18.0
mkdir obj_work
cd obj_work
../gcc_work/configure --prefix=../bin_work <other options>
# Your <other options> shouldn't need to involve anything about gmp, mpfr, mpc, isl, cloog.
# The gcc build system will find the directories you linked,
# then configure and compile the needed libraries with the necessary flags and such.
# Good luck.
I've been using this configure option with gcc-4.8.0, on FreeBSD, after building and installing gmp, isl and cloog:
LD_LIBRARY_PATH=/path/to/isl/lib ./configure (lots of other options) \
--with-stage1-ldflags="-rpath /path/to/isl/lib -rpath /path/to/cloog/lib -rpath /path/to/gmp/lib"
and the resulting gcc binary does not need any LD_LIBRARY_PATH. The LD_LIBRARY_PATH for configure is needed because it compiles a test program to check for the ISL version, which would fail if it didn't find the ISL shared lib.
I tried it on Linux (Ubuntu) where it failed during configuring because the -rpath args were passed to gcc instead of ld. I could fix this by using
--with-stage1-ldflags="-Wl,-rpath,/path/to/isl/lib,-rpath,/path/to/cloog/lib,-rpath,/path/to/gmp/lib"
instead.
Just using configure --with-stage1-ldflags="-Wl,-rpath,/path/to/lib" was not enough for me to build gcc 4.9.2, bootstrap failed in stage 2. What works is to pass he flags directly to make via
make BOOT_LDFLAGS="-Wl,-rpath,/path/to/lib"
I got this from https://gcc.gnu.org/ml/gcc/2008-09/msg00214.html
While it still involves setting environment variables, what I do is that I define LD_RUN_PATH, which sets the rpath. That way the rest of the system can keep using the system provided libraries instead of using the ones that your gcc build generates.
I am going to make a suggestion that I believe solves your problem, although it definitely does not answer your question. Let's see how many downvotes I get.
Writing a generic wrapper script to set LD_LIBRARY_PATH and then to run the executable is easy; see https://stackoverflow.com/a/7101577/768469.
The idea is to pass something like --prefix=$PREFIX/install to configure, building an install tree that looks like this:
$PREFIX/
install/
lib/
libcloogXX.so
libgmpYY.so
...
bin/
gcc
emacs
...
bin/
.wrapper
gcc -> .wrapper
emacs -> .wrapper
.wrapper is a simple shell script:
#!/bin/sh
here="${0%/*}" # or use $(dirname "$0")
base="${0##*/}" # or use $(basename "$0")
libdir="$here"/../install/lib
if [ "$LD_LIBRARY_PATH"x = x ] ; then
LD_LIBRARY_PATH="$libdir"
else
LD_LIBRARY_PATH="$libdir":"$LD_LIBRARY_PATH"
fi
export LD_LIBRARY_PATH
exec "$here"/../install/bin/"$base" "$#"
This will forward all arguments correctly, handle spaces in arguments or directory names, and so forth. For practical purposes, it is indistinguishable from setting the rpath like you want.
Also, you can use this approach not only for gcc, but for your entire my-personal-$PREFIX tree. I do this all the time in environments where I want an up-to-date suite of GNU tools, but I do not have (or want to admit to have) root access.
Try to add your $PREFIX to /etc/ld.so.conf and then run ldconfig:
# echo $PREFIX >> /etc/ld.so.conf
# ldconfig
This will recreate cache that is used by runtime linker and it will pick up your libraries.
WARNING: This operation will cause ALL applications to use your newly compiled libraries in $PREFIX instead of default location