What does the gcc -R parameter do? - c++

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.

Related

Cross compilation for gpsd shows "unrecognized option"

I am cross-compiling gpsd3.20 on my Ubuntu 16.04 for the ARM architecture. As you may know, gpsd uses Sconsctruct to compile the source codes. During my cross-compilation, the moment when it needs to create the libgps.so it shows an error unrecognized option '-Wl, -Bsymbolic'.
Before posting the question here, I have tried t check my toolchain binaries and I found out that if I run this line manually:
sudo ./arm-v7a-linux-gnueabihf-ld -o test/gpsd-3.20/libgps.so.25.0.0 -pthread -shared -Wl,-Bsymbolic-functions -Wl,-soname=libgps.so.25 test/gpsd-3.20/os_compat.os test/gpsd-3.20/rtcm2_json.os test/rtcm3_json.os test/gpsd-3.20/shared_json.os test/gpsd-3.20/timespec_str.os test/gpsd-3.20/libgpsmm.os -L. -lrt -lm -lrt
The above commands print out the exact error as I mentioned previously. However, if I run the exact command replacing ld with gcc, then there is no any errors.
sudo ./arm-v7a-linux-gnueabihf-gcc -o test/gpsd-3.20/libgps.so.25.0.0 -pthread -shared -Wl,-Bsymbolic-functions -Wl,-soname=libgps.so.25 test/gpsd-3.20/os_compat.os test/gpsd-3.20/rtcm2_json.os test/rtcm3_json.os test/gpsd-3.20/shared_json.os test/gpsd-3.20/timespec_str.os test/gpsd-3.20/libgpsmm.os -L. -lrt -lm -lrt
Upon checking the arm-v7a-linux-gnueabihf-gcc --help, I found out that, gcc support -Wloptions whereas in the arm-v7a-linux-gnueabihf-ld it doesn't support the -Wl options. So now I am not sure how to change the SConstruct file so that it doesn't execute ld instead I want it to execute gcc especially for the libgps.so part.
(can't comment), so as answer: have you tried to set the env.-var.:
export LD=arm-v7a-linux-gnuabihf-gcc
Gcc takes -Wl,XXX and passes XXX to the linker.
I think you've got two combining problems here, though there's some guessing involved without looking into the build itself. First, scons shouldn't be adding the flag when building a library (https://github.com/SCons/scons/issues/3248 - fixed but, I believe, not part of a release). Second, "linking" should probably be done using gcc. If you call gcc to link, it still calls the linker behind the scenes - after dealing with options that are intended for gcc, which -Wl,-Bsymbolic is, it means pass -Bsymbolic on to the linking phase (indicated by -Wl, the 'l' meaning linker). So I'm supposing that the way you've told scons about the cross toolchain isn't quite right either, if it's calling ld directly you're probably going to have other issues as well.

How can I tell GCC to use custom library for -l instead of the system one?

I have a custom build of SQLite3 at /somepath, so /somepath/.libs contains libsqlite3.so.0.8.6 and the symbolic links to it. I wanted to link a program against it and assumed
g++ -O3 -g -fPIC -I /somepath -I /somepath/src -L /somepath/.libs -lsqlite3 -o myfile.so myfile.cpp
would work. It compiles, but I get a segmentation fault due to some problem in my code, and when trying to debug I run into the issues which look like LD_PRELOAD not working with my program and Setting my lib for LD_PRELOAD makes some processes produce loader errors: I can run LD_PRELOAD=myfile.so /somepath/sqlite3 ..., but under GDB I get symbol lookup error and LD_DEBUG=all LD_PRELOAD=myfile.so gdc -c core /somepath/sqlite3 ... reveals symbols are getting looked up in /usr/lib/x86_64-linux-gnu/libsqlite3.so.0 instead of /somepath/libsqlite3.so.0, and unsurprisingly missing the symbols for functions added in the custom build. How can I fix this and debug my code?
The -lsqlite3 argument should be last. Order of arguments to g++ matters a lot. You should read more about runpath and perhaps pass -Wl,-rpath,/somepath/.libs
You may want to pass -v once to g++ to understand what is happening (what programs are actually running). You might also pass -Wl,--verbose to ask a more verbose link.
Then you can use ldd on your executable (and also readelf) to find out more what are its link time dependencies.
With suitable arguments to g++ you should not need additional options to gdb
From http://visualgdb.com/gdbreference/commands/set_solib-search-path
Inside gdb use the commands below.
set solib-search-path [Directories]
show solib-search-path

Compiling C++ with g++ -m32 option

I am trying to compile as this :
-bash-4.1$ g++ -static -m32 Hello.cpp
and getting errors like this:
/opt/rh/devtoolset-4/root/usr/libexec/gcc/x86_64-redhat-linux/5.2.1/ld: skipping incompatible /opt/rh/devtoolset-4/root/usr/lib/gcc/x86_64-redhat-linux/5.2.1/libstdc++.a when searching for -lstdc++
/opt/rh/devtoolset-4/root/usr/libexec/gcc/x86_64-redhat-linux/5.2.1/ld: cannot find -lstdc++
collect2: error: ld returned 1 exit status
I have tried this as well but still get the exact same error above:
g++ -static -m32 -L/opt/rh/devtoolset-4/root/usr/lib/gcc/x86_64-redhat-linux/5.2.1/32 Hello.cpp
I have tried in both orders - nothing helps.
Why is it still looking at the wrong directory?
Is using -m32 option override -L option?
I could not find much documentation on -m32 option.
Please help.
Thanks!
Why is it still looking at the wrong directory?
Compiler always looking in predefined directories first. -L options adds your path to these list of directories, so because of it compiler is stil looking at the wrong directory. For more detailed output try to compiler your program with detailed output -### or -v options.
Is using -m32 option override -L option?
The answer is no - -m32 options is option to generate 32bit code, for example:
You may generate 32bit code that will work on 32bit machine, on your 64bit machine. Also you may run this code on your 64bit machine - it will work well.
I could not find much documentation on -m32 option.
Here is the link to the GCC docs
And here is doc about directory searching options
Also to say to compiler where to find libraries, you may set
LD_LIBRARY_PATH in your env
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$FULL_PATH_TO_YOUR_LIB
Do not override env vars - cause it may cause more problems if you are not absolutely sure in what you are doing.

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"

Gcc searches for header files under the wrong directory

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 .