Compiling C++ with g++ -m32 option - c++

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.

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

Linking against a c/c++ library

I have some basic questions regarding linking against a C/C++ library. I am trying to understand the difference in using the two different usages -L/usr/local/lib -lm usage and /usr/local/lib/libm.a usage. E.g., when I compile and link an example from the [SUNDIALS] library, both of the following work
gcc -Wall cvRoberts_dns.c -o cvRoberts_dns.exe -I/usr/local/include -L/usr/local/lib/ -lsundials_cvode -lsundials_nvecserial -lm
OR
gcc -Wall cvRoberts_dns.c -o cvRoberts_dns.exe /usr/local/lib/libsundials_cvode.a /usr/local/lib/libsundials_nvecserial.a
However, to compile and link an example from the library [libsbml], the following works
g++ -Wall readSBML.cpp -o readSBML.exe -I/usr/local/include -L/usr/local/lib -lsbml
but the this does not
g++ -Wall readSBML.cpp -o readSBML.exe /usr/local/lib/libsbml.a
If required, I can post the complete error message I get, but the last line of the message is as follows
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
My questions are as follows:
In the second style of linking (of the first example), there is no information regarding where to find the include files (header files), how does the compiler know the information supplied in -I/usr/local/include which is provided in the first style of the first example?
In the second style of first example there is no /usr/local/lib/libm.a (it actually gives an error message that libm.a cannot be found if I try to include it), then why -lm is required in the first style?
How do I compile the second example in the second style (i.e., using /usr/local/lib/libsbml.a)? I do see that there are files - libsbml.a and libsbml-static.a in the /usr/local/lib folder, but none of them work.
If it helps, I am on an OS X machine.
I would be very thankful if any one could help in this regard.
Just an update - I tried
g++ -Wall readSBML.cpp -o readSBML.exe /usr/local/lib/libsbml.5.dylib
and that compiled and linked just fine.
Thanks
SN
In general
The -L option is meant to find where the libraries themselves are. Each library is a collection of one or more object code (machine language) files. There is no need to find the include files.
The -I option has nothing to with linker, it helps the compiler resolve the header files used in your driver programme( eg Roberts_dns.c). This happens during the pre-processing stage.
In the second style of linking (of the first example), there is no
information regarding where to find the include files (header files),..
If the compilation worked as you expected,it may be because /usr/local/include is in the default include path for gcc. To check the default include path for gcc do gcc -xc -E -v -.
In the second style of first example there is no
/usr/local/lib/libm.a(it actually gives an error message that libm.a
cannot be found if I try to include it), then why -lm is required in
the first style?
In Linux, some libraries like libc.a are directly linked to your execultable by default while libm.a is not. In Mac (your environment), though, libm is directly link to the executable by default. So you don't have to explicitly link it. It is less likely that libm.a is located in /usr/local/lib/. So you got an error. But why link it in the first place?

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.

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.