How to get statically linked binaries after gcc downgrade - linux

I'm not a linux expert but I'm running into the following problem which I hope to get solved here. My system has gcc 4.4 and I had to install an older version of gcc (gcc 4.2) on my home space so I can build a simulation tool.
Anyway, everything went well and I was able to build the tool.
However, when I now try to link statically using '-static' gcc option I get errors such as:
/usr/local/bin/ld: cannot find -lm
/usr/local/bin/ld: cannot find -lc
collect2: ld returned 1 exit status
I installed the dev package for glibc using (assuming the static version of the libraries will be installed)
$ yum install glibc-devel glibc-static
But I still get the errors.
I don't know where to go from here.
By the way, I added the local version of gcc (ie gcc 4.2) to PATH and the libs to the LD_LIBRARY_PATH and LIBRARY_PATH.
Do I need to get glibc and install it locally too, if so which version should I get?
Thanks

Related

How do I link libraries from multiple locations (corresponding to multiple GCC versions)?

I am currently trying to use Oracle Linux 6 OS on a SPARC S7 server to run the NPB benchmarks (with OpenMP multithreading support). The OS comes preloaded with gcc 4.4.7, which is missing the Niagara 7 optimizations. I downloaded devtoolset-3 from the Oracle Yum Repository, which has gcc 4.9.2 installed in /opt/rh/devtoolset-3/root/usr/bin. However, when I compile the NPB benchmark using the newer gcc, it automatically links to libraries associated with the older gcc 4.4.7 (located in /usr/lib). This caused my program to segfault during execution. I believe that it is because libgomp 4.4.7 is incompatible with libgomp 4.9.2. I have tried several ways of linking to the libraries in the gcc 4.9.2 folder (which is /opt/rh/devtoolset-3/root/usr/lib/gcc); none of the methods work:
-Xlinker -rpath=lib_location
-Wl -Bstatic
-L lib_location
The closest I got was when using -Wl -Bstatic ~/libgomp.a or -static -L ~/libgomp.a. It fails to find libraries such as libm that reside in the default gcc lib folder (usr/lib).
The actual command used to link is:
/opt/rh/devtoolset-3/root/usr/bin/gcc -O3 -fopenmp -mcmodel=medmid -static -L/opt/rh/devtoolset-3/root/usr/lib/gcc/sparc64-redhat-linux/4.9.2 -o ../bin/bt.W.x bt.o initialize.o exact_solution.o exact_rhs.o set_constants.o adi.o rhs.o x_solve.o y_solve.o solve_subs.o z_solve.o add.o error.o verify.o ../common/print_results.o ../common/c_timers.o ../common/wtime.o -lm -L/opt/rh/devtoolset-3/root/usr/lib/gcc/sparc64-redhat-linux/4.9.2/lib/
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lm
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lrt
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lpthread
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lc
Is there a way I can link just the libgomp library from gcc 4.9.2 while linking the remaining libraries from gcc 4.4.7?
The devtoolset compilers are all using the system libgcc, libstdc++, version 4.4.7, and can therefore not compile e.g. c++11.
I guess the gcc53-c++-5.3.0-1.el6.x86_64.rpm will do. Comes with the internal */gcc53/lib64{libgcc_s.so**, libgomp.so**, libstdc++} (version 5.3.0) ... Provides /usr/bin/{ gcc53, g++53 }
The package was created a year ago ... well tested, as extra compiler. Download link : https://drive.google.com/file/d/0B7S255p3kFXNbTBneHgwSzBodFE/view?usp=sharing
If you're going to do the -Wl,-Bstatic thing, make sure to follow it immediately by -Wl,-Bdynamic to reset to normal after your added library argument. By default, not all system libraries have static versions installed, which is why you get e.g. cannot find -lc.
So you can try this as a modification of your workaround:
-Wl,-Bstatic ~/libgomp.a -Wl,-Bdynamic
Not pretty, and this question deserves a much better answer (this is still pretty much a hack), but it should get the job done for now.

What causes a library not found error in gcc, when the library exists?

After a reformat/reinstall of Linux, I'm trying to build some code that used to work. I'm not sure how to debug this sort of error. While I'd like to know what's wrong with this code below, I'd like to also know how to track down the problem -- what are the clues to look for?
$ more test.c
void main() {}
$ gcc test.c
<works>
$ gcc test.c -lboost_system
/usr/bin/ld: cannot find -lboost_system
collect2: error: ld returned 1 exit status
$ gcc test.c -lboost_filesystem
/usr/bin/ld: cannot find -lboost_filesystem
collect2: error: ld returned 1 exit status
$ locate boost_filesystem
/usr/lib64/libboost_filesystem.so.1.58.0
$ locate boost_system
/usr/lib64/libboost_system.so.1.58.0
$ uname -a
Linux mycomputer 4.2.6-301.fc23.x86_64 #1 SMP Fri Nov 20 22:22:41 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
$ sudo dnf list installed | grep boost
boost-date-time.x86_64 1.58.0-9.fc23 #updates
boost-filesystem.x86_64 1.58.0-9.fc23 #updates
boost-iostreams.x86_64 1.58.0-9.fc23 #updates
boost-system.x86_64 1.58.0-9.fc23 #updates
boost-thread.x86_64 1.58.0-9.fc23 #updates
UPDATE
#Kenny suggested I look for the devel package. It wasn't installed. dnf install boost-devel and it got installed. Then, when I run gcc test.c -lboost_system, it works. However, I'm still at a loss. What mechanism/file/setting got changed to make this work? When I run locate boost_system, I still come up with the same. I realize that package installed some header files, but my test.c didn't mention boost in it.
In Debian and Debian-derived distros, such as Ubuntu, library packages are usually divided in the binary package and the development package.
The library binary package will usually have the shared library file, with its full, three-digit-version name (libfoo.so.1.2.3) and a symlink to it with the one and/or two-digit-version name (libfoo.so.1.2, libfoo.so.1) pointing to the first one. This one-or-two-digit-version file is what it is actually looked for when running a program (google for ELF SONAME for details).
The library development package will usually contain the header files (*.h) and a symlink without any version numbers to the shared object (libfoo.so). Optionally, there may be also a static library file (libfoo.a).
Now, when you compile a program and you add the -lfoo option, the linker will look for a file libfoo.so that is actually a symlink to libfoo.so.1.2.3 and it will use that file as a shared library.
And that's why this symlink is in the dev package and not the bin one: since the shared library has a SONAME with libfoo.so.1 or libfoo.so.1.2 the runtime program does not need the libfoo.so symlink. It's only used for building.
PS: to see the files in a package do not use locate. Use dpkg -L libboost-filesystem-dev.

How to dynamically link libraries in automake?

I'm trying to build a package on lauchpad. For it to build I need to set a static path using the LDADD variable in automake:
relay_LDADD = /usr/lib/x86_64-linux-gnu/libm.so /usr/lib/x86_64-linux-gnu/libX11.so.6 $(RELAY_LIBS)
This compiles on the 64 bit build but fails on the 32 bit build. I tried using PKG_CHECK_MODULES but it says
No package 'm' found
No package 'X11' found
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
I know it not a non standard path since launchpad is doing the building? How can I get this to work?
The build failed without the libraries specified even though the package specifies them in the build-requires.
You have tried to outwit the buid-system, and it has outwitted you.
It's generally a bad idea to hard-code paths.
Debian (and ubuntu is just a derivative), has started to ship binaries (like libraries) in architecture-dependent directories, to allow installations for multiple architectures on a single system.
These libraries are installed into /usr/lib/<host-triplet>, where <host-triplet> depends on the architecture; e.g. x86_64-linux-gnu is the amd64 architecture for systems with a linux and the gnu tools.
a 32bit system would typically have a host-triplet of i386-linux-gnu.
Since you are hard-coding the library path to a 64bit location( /usr/lib/x86_64-linux-gnu/libm.so) this fails on all systems but 64bit/linux/gnu.
Instead you should just tell the linker to link against the m library (libm), resp the X11 library (libX11).
Let the linker care for the correct architecture to pick:
relay_LDADD = -lm -lX11 $(RELAY_LIBS)
In general, if you want to link against a library foo, that provides a library-file libfoo.so you would use -lfoo (stripping away the leading lib and the trailing .so).
However, sometimes this is not enough; in those cases your library might use pkg-config to provide the full CFLAGS and LDFLAGS needed to compile/link against this library.
e.g. if I want to use libquicktime:
$ pkg-config --cflags libquicktime
-I/usr/include/lqt
$ pkg-config --libs libquicktime
-lquicktime -lpthread -lm -lz -ldl
So I would use something like:
myprog_CFLAGS += $(shell pkg-config --cflags libquicktime)
myprog_LDADD += $(shell pkg-config --libs libquicktime)
That would work in any GNU(?) Makefile (not related to autotools).
In an autotools project, you would probably move the pkg-config check into configure, using the m4-macro PKG_CHECK_MODULES

configure test with static lib

I am trying to cross compile libpng for RaspberryPi on Ubuntu 14.04 (x_64) with zlib
but configure fails with
configure:11400: arm-linux-gnueabihf-gcc -o conftest -g -O2 -I/home/user/RPI_DEV/lib/include conftest.c -lz -lm >&5
/home/user/RPI_DEV/xtools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/../lib/gcc/arm-linux-gnueabihf/4.8.3/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lz
collect2: error: ld returned 1 exit status
configure:11400: $? = 1
configure: failed program was:
....
Because I am using toolchain for arm, arm-ld cant find zlib.
Is there any option for configure not to compile with shared lib but to try with static lib (eg. -static -lz).
Command is
./configure --enable-static=true --enable-shared=false --with-zlib-include="/home/user/RPI_DEV/lib/include" --with-zlib-lib="/home/user/RPI_DEV/lib/lib" LDFLGS="-L/home/user/RPI_DEV/lib/lib" CPPFLAGS="-I/home/user/RPI_DEV/lib/include" -enable-static --host=arm-linux-gnueabihf --prefix=/home/user/RPI_DEV/lib --exec-prefix=/home/user/RPI_DEV/lib
You need to cross build and install zlib into your toolchain before trying to use it in another project.
What you are doing might work but only if you spell LDFLAGS correctly:
LDFLGS="-L/home/user/RPI_DEV/lib/lib"
Note the missing 'A'. I don't know why your second attempt worked, given you had the same misspelling; possibly you had a correct LDFLAGS in your environment?
Anyway there should be a Ubuntu cross-development guide somewhere that explains how to do this. It's slightly off topic but for Gentoo you use 'crossdev' to install the toolchain then a crossdev specific version of the normal package installation mechanism ([host]-emerge) to install zlib into the toolchain.
Also, the arguments --with-zlib-include and --with-zlib-lib are not supported by any current version of libpng I can find. If you are cross-compiling libpng for an RPi (or, indeed, any ARM system) you should be using the latest version of 1.6 that you can find.
Unless someone solves this the RIGHT way, this is hack I've done.
Open configure.ac file
Find and comment out line
AC_CHECK_LIB(z, zlibVersion, , AC_ERROR([zlib not installed]))
Configure will pass wihout check for zlib and then add zlib by hand
LDFLGS="-L/home/user/RPI_DEV/lib/lib -L/home/user/RPI_DEV/lib/lib/libz.a"
Run autoconf
Run ./configure ...

Qt5 Linux cannot find Qt libraries

I am trying to compile an existing QT library with QT5.1 Beta on Ubuntu 12.04 with Clang.
This project compiles fine with QT4.8.4.
I am getting the below linker error when I compile the project with QT5.1 Beta.
/usr/bin/ld: cannot find -lQt5OpenGL
/usr/bin/ld: cannot find -lQt5Widgets
/usr/bin/ld: cannot find -lQt5Network
/usr/bin/ld: cannot find -lQt5Gui
/usr/bin/ld: cannot find -lQt5Core
My current system setup is as follows:
Installed the 64 bit linux pre-built package of QT5.1 Beta on my home directory
Added Qt5.1 qmake bin directory to PATH environment variable
Added QT5.1 lib directory to LD_LIBRARY_PATH
Installed Clang 3.3 and libc++
In QT Creator added a Kit with QT5.1 and Clang and built the project using this kit
I am getting the error on both launching the qtcreator from icon and bash.
The developer who was using this ubuntu system before had installed QT4 using apt-get.
I think QT4 got installed in the default OS directories and QT4 gets picked up always rather than QT5 when I build my project. I removed the QT4 packages that were under /usr/** path
When the build fails ,I see the below command being executed in qtcreator's compiler output window.
clang++ debug/moc-xxx.o -L -L/home/user/Qt5.1.0/5.1.0-beta1/gcc_64/lib -lQ5OpenGL -lQt5Widgets -lQt5Network -lQt5Gui -lGL -lpthread
Does the -L with no path tell the compiler to use the libs from the system's default paths?
What am I missing here?
You need to compile Qt with Clang first (Clang-3.2 example):
http://libre.tibirna.org/projects/qgit/wiki/Compile_Qt5_with_clang
because pre-built Linux Qt libraries are for gcc.
After building Qt you can configure the Kit for Qt Creator:
http://libre.tibirna.org/projects/qgit/wiki/Compile_QGit_with_Qt5_and_clang

Resources