Gcc searches for header files under the wrong directory - c++

I have two versions of gcc/g++ installed: gcc-4.5(installed from package manager, binary files are under /usr/bin, header files are under /usr/include) and gcc-4.4.3(compiled by myself, put under /opt/gcc-4.4.3).
When I made gcc/g++ 4.4.3 to be the default version (using "update-alternatives" to make /usr/bin/gcc and /usr/bin/g++ point to the corresponding one under directory "/opt/gcc-4.4.3/bin") and compiled the files, it always reported the following errors:
/usr/include/c++/4.5/bits/basic_string.h:1659: undefined reference to
`std::basic_string,
std::allocator::_S_construct_aux_2(unsigned long, char,
std::allocator const&)'
It seems that the compiler is trying to find the header files for c++ under /usr/include/c++/4.5, which causes the link error. When I changed the default version of gcc to gcc-4.5, the errors disappeared.
So how could I make the compiler search for the header files under the correct directory "/opt/gcc-4.4.3/include"? I have tried to export CPLUS_INCLUDE_PATH, but it seems not work.
PS: gcc -v
Using build-in specs
Target: x86_64-suse-linux
Configured with: ./configure --prefix=/opt/gcc-4.4.3
Thread model: posix
gcc version 4.4.3 (GCC)

Try compiling gcc 4.4.3 again, but use the --with-gxx-include-dir=/opt/gcc-4.4.3/include option in the configure step.

It might be an issue with what update-alternatives has done, or not done.
When I build an alternate compiler I tend to use a --prefix and --program-suffix=-XY just so I can spot problems. Check which cpp is being run:
/opt/gcc-4.4.3/bin/g++ --print-prog-name=cpp
cpp -v </dev/null
/opt/gcc-4.4.3/bin/cpp -v < /dev/null
/opt/gcc-4.4.3/bin/g++ -print-search-dirs | grep '^programs:'
(you can also check ld and as with --print-prog-name)
Setting CPPFLAGS="-v -H" during a build may help track things down too.
An ugly workaround might be CPPFLAGS="-nostdinc -nostdinc++ -I/opt/gcc-4.4.3/include/" but it's better to fix your compile environment, as that's likely to cause as many problems as it solves. There are also options -isystem and -sysroot to help in certain cases, see http://gcc.gnu.org/onlinedocs/cpp/Invocation.html .

Related

Linking error when compiling Crypto++ for ARMHF

I'm trying to compile the crypto++ library to run for the armhf architecture. I'm following the method provided in this answer. I tweaked the setenv-embed.sh to match my system's configuration. The output of running . ./setenv-embed.sh is
CPP: /usr/bin/arm-linux-gnueabihf-cpp
CXX: /usr/bin/arm-linux-gnueabihf-g++
AR: /usr/bin/arm-linux-gnueabihf-ar
LD: /usr/bin/arm-linux-gnueabihf-ld
RANLIB: /usr/bin/arm-linux-gnueabihf-gcc-ranlib-4.8
ARM_EMBEDDED_TOOLCHAIN: /usr/bin
ARM_EMBEDDED_CXX_HEADERS: /usr/arm-linux-gnueabihf/include/c++/4.8.2
ARM_EMBEDDED_FLAGS: -march=armv7-a mfloat-abi=hard -mfpu=neon -I/usr/arm-linux-gnueabihf/include/c++/4.8.2 -I/usr/arm-linux-gnueabihf/include/c++/4.8.2/arm-linux-gnueabihf
ARM_EMBEDDED_SYSROOT: /usr/arm-linux-gnueabihf
which indicates that the correct compilers have been found. However, when I build the library using make I run into the following error
/usr/lib/gcc-cross/arm-linux-gnueabihf/4.8/../../../../arm-linux-gnueabihf/bin/‌​ld: cannot find /usr/arm-linux-gnueabihf/lib/libc.so.6 inside /usr/arm-linux-gnueabihf
/usr/lib/gcc-cross/arm-linux-gnueabihf/4.8/../../../../arm-linux-gnueabihf/bin/‌​ld: cannot find /usr/arm-linux-gnueabihf/lib/libc_nonshared.a inside /usr/arm-linux-gnueabihf
/usr/lib/gcc-cross/arm-linux-gnueabihf/4.8/../../../../arm-linux-gnueabihf/bin/‌​ld: cannot find /usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3 inside /usr/arm-linux-gnueabihf
But when I open the location /usr/arm-linux-gnueabihf/lib I can find all the three error files mentioned above ie libc.so.6, libc_nonshared.a and ld-linux-armhf.so.3
I'm trying to compile the library for Beaglebone, if that helps.
Update 1:
The results of running make -f GNUmakefile-cross system after doing a fresh git pull
hassan#hassan-Inspiron-7537:~/cryptopp-armhf$ make -f GNUmakefile-cross system
CXX: /usr/bin/arm-linux-gnueabihf-g++
CXXFLAGS: -DNDEBUG -g2 -Os -Wall -Wextra -DCRYPTOPP_DISABLE_ASM -march=armv7-a -mfloat-abi=hard -mfpu=neon -mthumb -I/usr/arm-linux-gnueabihf/include/c++/4.8.2 -I/usr/arm-linux-gnueabihf/include/c++/4.8.2/arm-linux-gnueabihf --sysroot=/usr/arm-linux-gnueabihf -Wno-type-limits -Wno-unknown-pragmas
LDLIBS:
GCC_COMPILER: 1
CLANG_COMPILER: 0
INTEL_COMPILER: 0
UNALIGNED_ACCESS:
UNAME: Linux hassan-Inspiron-7537 3.13.0-35-generic #62-Ubuntu SMP Fri Aug 15 01:58:42 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
MACHINE:
SYSTEM:
RELEASE:
make: Nothing to be done for `system'.
The problem is simple. It is in the --sysroot option. The value of this option is /usr/arm-linux-gnueabihf/ and it is used by the linker and the resulting library folder becomes
/usr/arm-linux-gnueabihf/usr/arm-linux-gnueabihf/lib/
I removed the --sysroot option from line 68 in the file GNUmakefile-cross and everything compiled and linked OK.
However, I couldn't run the example on my BeagleBone Black because of mismatch of some shared libraries versions. But this wasn't a real problem for me, because in my application I link crypto++ statically, not dynamically.
Based on Crosswalking's research I think I can explain what is going on. I don't think I agree with the assessment "The problem is simple. It is in the --sysroot option" since the Crypto++ environment script and makefile are doing things as expected.
I think Crosswalking's answer could be how to work around it; but see open questions below. The following is from Crypto++ Issue 134: setenv-embedded.sh and GNUmakefile-cross:
I think this another distro problem, similar to g++-arm-linux-gnueabi
cannot compile a C++ program with
--sysroot.
It might be a Ubuntu problem or a Debian problem if it is coming from
upstream.
When cross-compiling, we expect the following (using ARMHF):
SYSROOT is /usr/arm-linux-gnueabihf
INCLUDEDIR is /usr/arm-linux-gnueabihf/include
LIBDIR is /usr/arm-linux-gnueabihf/lib
BINDIR is /usr/arm-linux-gnueabihf/bin
How LIBDIR morphed into into
/usr/arm-linux-gnueabihf/usr/arm-linux-gnueabihf/lib/ (i.e.,
$SYSROOT/$SYSROOT/lib) is a mystery. But in all fairness, building
GCC is not a trivial task.
You should probably file a bug report with Debian or Ubuntu (or
whomever provides the toolchain).
The open question for me is, since $SYSROOT/lib is messed up, then is $SYSROOT/include messed up, too?
If the include directory is also messed up, then the cross compile is using the host's include files, and not the target include files. That will create hard to diagnose problems later.
If both $SYSROOT/include and $SYSROOT/lib are messed up, then its not enough to simply remove --sysroot. Effectively, this is what has to be done:
# Exported by setenv-embedded
export=ARM_EMBEDDED_SYSROOT=/usr/arm-linux-gnueabihf
# Used by the makefile
-I $ARM_EMBEDDED_SYSROOT/$ARM_EMBEDDED_SYSROOT/include
-L $ARM_EMBEDDED_SYSROOT/$ARM_EMBEDDED_SYSROOT/lib
Which means we should be able to do the following:
# Exported by setenv-embedded
export=ARM_EMBEDDED_SYSROOT=/usr/arm-linux-gnueabihf/usr/arm-linux-gnueabihf
# Used by the makefile
--sysroot="$ARM_EMBEDDED_SYSROOT"
Finally, this looks a lot like Ubuntu's Bug 1375071: g++-arm-linux-gnueabi cannot compile a C++ program with --sysroot. The bug report specifically calls out ... the built-in paths use an extra "/usr/arm-linux-gnueabi".
We need the paths:
A) /usr/arm-linux-gnueabi/include/c++/4.7.3 B)
/usr/arm-linux-gnueabi/include/c++/4.7.3/arm-linux-gnueabi
But the built-in paths tries to use:
C) /usr/arm-linux-gnueabi/usr/arm-linux-gnueabi/include/c++/4.7.3
D)
/usr/arm-linux-gnueabi/usr/arm-linux-gnueabi/include/c++/4.7.3/arm-linux-gnueabi/sf
E)
/usr/arm-linux-gnueabi/usr/arm-linux-gnueabi/include/c++/4.7.3/backward
Notice the built-in paths use an extra "/usr/arm-linux-gnueabi"

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)

Facebook warpdrive build - D Programming language

Of late, facebook opensourced warp, C/C++ preprocessor.
https://github.com/facebook/warp
I'm trying to build it using dmd and stuck with some build errors.
I downloaded dmd.2.065.0.zip for dmd compiler - dmd2/linux/bin64/dmd
I also see a bunch of libraries, for example libphobos2.a
Then when I build warp, I see some errors from ld, that keep complaining that phobos2.a could not be found. I exported LD_LIBRARY_PATH to the dir where this library is stored but no luck.
I compiled in verbose mode, and it doesn't give more info.
Command:
/path/to//building_stuff/dmd2/linux/bin64/dmd -O -inline -release -ofwarp cmdline.d constexpr.d context.d directive.d expanded.d file.d id.d lexer.d loc.d macros.d main.d number.d outdeps.d ranges.d skip.d sources.d stringlit.d textbuf.d -v
Error excerpt:
function textbuf.Textbuf!char.Textbuf.length
function textbuf.Textbuf!char.Textbuf.resize
gcc warp.o -o warp -m64 -L/path/to/building_stuff/dmd2/linux/bin64/../lib64 -Xlinker --export-dynamic -l:libphobos2.a -lpthread -lm -lrt
/usr/bin/ld: cannot find -l:libphobos2.a
collect2: ld returned 1 exit status
--- errorlevel 1
I was hoping the D language experts here, or those who know about warp already could give me some hint.
I was not on CentOS, as warp demands. I wonder if that could anyway be the reason.
I was not using gcc 4.7.x as warp demands, but, to me, the library could just not be located doesn't look like a problem from old gcc I have.
I was on redhat5.5 machine with 4.1 gcc.
CentOS is basically a RedHat, so everything should work OK. As people commented, your real problem is the -l:libphobos2.a in your link line. Remember, GNU/Linux allows colons in file-names, so :libphobos2.a is a perfectly valid file, and GNU ld won't find it in the library search paths.
Note that they've added a make file to easy on your compilation, I managed to compile it using "make -j" and only editing the dmd command line in the make.
just rename "libphobos2.a" to "lib:libphobos2.a.a"
I faced a similar problem with ld version 2.17, but with version 2.20 this 'l:<libfilename>' kinda syntax works fine.

Linking g++ 4.8 to libstdc++

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.

What does the gcc -R parameter do?

I am trying to run an autotools configure script for the bson-cpp project, and it fails because it cannot determine what flags it needs to compile with boost_filesystem. A quick look at confg.log shows:
g++ -o conftest -g -O2 -pthread -L/usr/local/lib -R/usr/local/lib -L/usr/local/libexec conftest.o -lboost_filesystem-mt -lboost_system-mt >&5
g++: error: unrecognized option '-R'
So, naturally, I tried to find out what the R option does, but I can't seem to find it documented anywhere. I've checked here and here to no avail. What does the option do and how do I tell autotools not to use it?
-R does not seem to be an option for g++ or gcc anywhere. -R may be a linker option on some platforms that is equivalent of -rpath to gnu ld, ... This seems to be a known bug in boost builds ... have a look at Use -Wl to pass arguments to the linker.
It actually has the patch available there
I am re-posting it for convenience, however PLEASE PLEASE look at the original URL linked above for official patch!
--- ../gnote/m4/boost.m4 2011-01-25 14:30:18.000000000 +0200
+++ m4/boost.m4 2011-02-27 20:57:11.686221539 +0200
## -403,7 +403,7 ##
LDFLAGS=$boost_save_LDFLAGS
LIBS=$boost_save_LIBS
if test x"$Boost_lib" = xyes; then
- Boost_lib_LDFLAGS="-L$boost_ldpath -R$boost_ldpath"
+ Boost_lib_LDFLAGS="-L$boost_ldpath -Wl,-R$boost_ldpath"
Boost_lib_LDPATH="$boost_ldpath"
break 6
else
It's an option similar to -rpath, but available only on some platforms. The script is maybe failing detecting your platform ?
It is not a valid option for GCC, so it does not do anything.
It is possibly a valid option for other compilers though, which could be why autoconf gives it a shot.
Not all errors in the config.log files are a problem. autoconf figures out a lot of things by "guessing", i.e. trying something and keeping that if it worked.