Version information:
/usr/lib/lapack/liblapack.so:
libc.so.6 (GLIBC_2.14) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.4) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libc.so.6
libgcc_s.so.1 (GCC_4.0.0) => /lib/x86_64-linux-gnu/libgcc_s.so.1
libgfortran.so.3 (GFORTRAN_1.0) => /usr/lib/x86_64-linux-gnu/libgfortran.so.3
libgfortran.so.3 (GFORTRAN_1.4) => /usr/lib/x86_64-linux-gnu/libgfortran.so.3
libm.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libm.so.6
So there are 3 rows of libc.so.6, versioned at GLIBC_2.xx.
What does that mean? What version of libc.so.6 does this liblapack.so require?
How can I get liblapack.so's version?
What does that mean?
It means that liblapack.so requires versioned symbols from libc.so.6 with versions GLIBC_2.2.5, GLIBC_2.4 and GLIBC_2.14. You can read about versioned symbols here.
What version of libc.so.6 does this liblapack.so require?
It requires 2.14 or newer. In general, GLIBC never removes symbols, only adds new ones, and so will still provide symbols versioned at GLIBC_2.2.5 even in the latest GLIBC-2.24.
If it did ever remove such "old" versioned symbol, that would break any old binaries that depended on that symbol (which is why it's not done).
How can I get liblapack.so's version?
It doesn't look like liblapack.so itself is using any versioned symbols. You can look at your package manager to find out what version of liblapack.so you have. Something like:
dpkg -S /usr/lib/lapack/liblapack.so
liblapack-dev: /usr/lib/lapack/liblapack.so
dpkg -l liblapack-dev
...
ii liblapack-dev 3.5.0-2ubuntu1 amd64 Library of linear algebra routines 3 - static version
Related
we have old Linux distribution and the vendor doesn't support its updates. We want to build our c++ code with a modern compiler, for that we are building GCC compiler from sources (something very similar to https://github.com/darrenjs/howto/blob/master/build_scripts/build_gcc_10.sh)
Now the problem is that we can not deploy the executables because users' machine do not contain libstdc++.so.6 for this GLIBC. Is there a way to compile GCC and make it based on old local GLIBC that the vendor provides?
[EDIT]: After build my executable of xenenterprise 8.0.0 with GCC 10.1.0 that was built from sources:
[root#xen8 sandbox-gcov]# ldd build/main
linux-vdso.so.1 => (0x00007ffddf9fd000)
libstdc++.so.6 => /var/opt/gcc-10.1.0/lib64/libstdc++.so.6 (0x00007fb82155f000)
libm.so.6 => /lib64/libm.so.6 (0x00007fb82125d000)
libgcc_s.so.1 => /var/opt/gcc-10.1.0/lib64/libgcc_s.so.1 (0x00007fb821045000)
libc.so.6 => /lib64/libc.so.6 (0x00007fb820c77000)
/lib64/ld-linux-x86-64.so.2 (0x00007fb82192c000)
Then got error on another machine with native GCC 4.8.5 20150623 (Red Hat 4.8.5-44):
[root#xen8-1 sandbox-gcov]# ldd build/main
build/main: /lib64/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by build/main)
build/main: /lib64/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by build/main)
linux-vdso.so.1 => (0x00007ffeec5fe000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f92099db000)
libm.so.6 => /lib64/libm.so.6 (0x00007f92096d9000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f92094c3000)
libc.so.6 => /lib64/libc.so.6 (0x00007f92090f5000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9209ce3000)
I am using using Centos 6.6 and there is a shared library the build generates used by number of executable and any executable using this shared library cannot find it as seen by ldd.
I can locate the library:
$ locate libcs.so.1
/opt/cloudshield/lib/libcs.so.1
ldd shows the following:
$ sudo ldd /opt/cloudshield/lib/libcs.so.1
ldd: warning: you do not have execution permission for `/opt/cloudshield/lib/libcs.so.1'
linux-vdso.so.1 => (0x00007ffff4fff000)
libc.so.6 => /lib64/libc.so.6 (0x00007f7a0fd56000)
/lib64/ld-linux-x86-64.so.2 (0x000000340ba00000)
$ sudo ldconfig -v | grep libcs.so.1
Is it because of the kernel library linux-vdso.so.1?
Executable cannot find the library libcs.so.1:
[fpeter#localhost radius]$ ldd radius
`linux-vdso.so.1 => (0x00007fff634b4000)
libconfd.so => /home/fpeter/trunk/thirdparty/tailf/confd/lib/libconfd.so (0x00007f5db20e6000)
libcs.so.1 => not found
libpthread.so.0 => /lib64/libpthread.so.0 (0x000000340c600000)
libc.so.6 => /lib64/libc.so.6 (0x000000340c200000)
libm.so.6 => /lib64/libm.so.6 (0x000000340ce00000)
libcrypto.so.1.0.0 => /usr/lib64/libcrypto.so.1.0.0 (0x0000003ba4a00000)
/lib64/ld-linux-x86-64.so.2 (0x000000340ba00000)
libdl.so.2 => /lib64/libdl.so.2 (0x000000340be00000)
libz.so.1 => /lib64/libz.so.1 (0x000000340d600000)
Add /opt/cloudshield/lib/ to your LD_LIBRARY_PATH environment variable, e.g.:
LD_LIBRARY_PATH=/opt/cloudshield/lib
export LD_LIBRARY_PATH
See also How to build library ithoutsudo or
shared libraries.
Environment: Ubuntu 14.04. gcc 4.8.2
I am working on a C++ console application. When I run "ldd" on the executable, I see the following:
linux-vdso.so.1 => (0x00007fffe495e000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f9ffa754000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9ffa38e000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f9ffa087000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9ffaa6e000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f9ff9e71000
I am wondering if it is possible to define flags on gcc/linker such that the final executable does not depend on any shared libraries.
Simply add -static while linking :-)
Static linking should be avoided not only for security reasons.
BTW: As I know there is no way to create a static lib from a dynamic one. So if you have only the shared lib, you can't link static.
I have custom built gcc-4.7.2 in my environment. The system gcc is gcc-4.3.4.
I have patched the RUNPATH for all my custom gcc's binaries and shared libraries using patchelf --set-rpath
However, when I run ldd on my 4.7.2 cc1 it picks up the system libstdc++ instead of the one pointed to by the RUNPATH:
$ ldd /sdk/x86_64/2.11.1/gcc-4.7.2/libexec/gcc/x86_64-suse-linux/4.7.2/cc1
libcloog-isl.so.1 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libcloog-isl.so.1 (0x00007f072dce8000)
...
libc.so.6 => /lib64/libc.so.6 (0x00007f072bfe0000)
--> libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f072bcd5000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f072babe000)
/lib64/ld-linux-x86-64.so.2 (0x00007f072df0d000)
As can be seen the RUNPATH specifies the gcc-4.7.2 library locations:
$ readelf -a /sdk/x86_64/2.11.1/gcc-4.7.2/libexec/gcc/x86_64-suse-linux/4.7.2/cc1 | grep PATH
0x000000000000001d (RUNPATH) Library runpath: \
[/sdk/x86_64/2.11.1/gcc-4.7.2/lib64: \
/sdk/x86_64/2.11.1/gcc-4.7.2/lib: \
/sdk/x86_64/2.11.1/gcc-4.7.2/libexec/gcc/x86_64-suse-linux/lib64: \
/sdk/x86_64/2.11.1/gcc-4.7.2/lib/gcc/x86_64-suse-linux/4.7.2: \
/hostname/sig/lib64: \
/hostname/sig/lib]
I know that libstdc++.so.6 exists in the first entry in the RUNPATH:
$ ls -l /sdk/x86_64/2.11.1/gcc-4.7.2/lib64/libstdc++.so*
lrwxrwxrwx .../sdk/x86_64/2.11.1/gcc-4.7.2/lib64/libstdc++.so -> libstdc++.so.6.0.17
lrwxrwxrwx .../sdk/x86_64/2.11.1/gcc-4.7.2/lib64/libstdc++.so.6 -> libstdc++.so.6.0.17
-rwxr-x--- .../sdk/x86_64/2.11.1/gcc-4.7.2/lib64/libstdc++.so.6.0.17
-rwxr-x--- .../sdk/x86_64/2.11.1/gcc-4.7.2/lib64/libstdc++.so.6.0.17-gdb.py
I don't have an LD_LIBRARY_PATH set in my environment:
$ echo $LD_LIBRARY_PATH
$
How come it doesn't pick up the library found in RUNPATH?
How can I force it to use the gcc-4.7.2 libraries?
The problem is that one of the prerequisites (libppl.so) also imports libstdc++. That prerequisite was built using the system gcc, and therefore finds /usr/lib64/libstdc++.so.6
$ ldd /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libppl.so
linux-vdso.so.1 => (0x00007fffd10db000)
libgmpxx.so.4 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libgmpxx.so.4 (0x00007f4716f92000)
libgmp.so.10 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libgmp.so.10 (0x00007f4716d26000)
--> libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f4716a25000)
libm.so.6 => /lib64/libm.so.6 (0x00007f47167a0000)
libc.so.6 => /lib64/libc.so.6 (0x00007f4716441000)
libgcc_s.so.1 => /usr/lib64/libgcc_s.so.1 (0x00007f471622c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f47174b4000)
Once a library has been located by the dynamic linker once, it will no longer be searched for; that location will be used for any subsequent requirements.
I resolved this by rebuilding the prerequisites with the new gcc.
$ ldd /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libppl.so
linux-vdso.so.1 => (0x00007fffd10db000)
libgmpxx.so.4 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libgmpxx.so.4 (0x00007f4716f92000)
libgmp.so.10 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libgmp.so.10 (0x00007f4716d26000)
--> libstdc++.so.6 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/../lib64/libstdc++.so.6 (0x00007f4716a25000)
libm.so.6 => /lib64/libm.so.6 (0x00007f47167a0000)
libc.so.6 => /lib64/libc.so.6 (0x00007f4716441000)
libgcc_s.so.1 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/../lib64/libgcc_s.so.1 (0x00007f471622c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f47174b4000)
I'm thinking the final step is to now rebuild gcc with the newly build prerequisites.
build prerequisites with system gcc
build new gcc
rebuild prerequisites with new gcc
rebuild gcc with rebuilt prerequisites
Whether the final step is necessary I'm not sure.
You need to set the LD_LIBRARY_PATH to point to the desired libstdc++. RUNPATH is evaluated after LD_LIBRARY_PATH.
Quoting from RPATH issue:
The dynamic linker will look for a matching library in the following locations, in this order, which can be changed (see the footnotes below):
1. the DT_RPATH dynamic section attribute of the library causing the lookup
2. the DT_RPATH dynamic section attribute of the executable
3. the LD_LIBRARY_PATH environment variable, unless the executable is setuid/setgid.
4. the DT_RUNPATH dynamic section attribute of the executable
5. /etc/ld.so.cache
6. base library directories (/lib and /usr/lib)
How can I drop dynamic dependency on libgmp and go from this:
linux-vdso.so.1 => (0x00007fffdccb1000)
libgmp.so.10 => /usr/lib/x86_64-linux-gnu/libgmp.so.10 (0x00007fb01afc1000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fb01acc7000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fb01aabe000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fb01a8ba000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fb01a69d000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb01a2df000)
/lib64/ld-linux-x86-64.so.2 (0x00007fb01b249000)
to this (currently desired):
linux-vdso.so.1 => (0x00007fffdccb1000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fb01acc7000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fb01aabe000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fb01a8ba000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fb01a69d000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb01a2df000)
/lib64/ld-linux-x86-64.so.2 (0x00007fb01b249000)
in a clean and portable way that just works on all GNU/Linux distributions (and not messing up with BSDs (including OS X))?
Do you see any other dependencies that may cause problems in the currently desired list as given above when distributing a single Haskell binary targeting multiple GNU/Linux distributions?
Notes:
my app is GPLv3 so no license violation issues arise regarding GMP
Specifying a path to libgmp.a does not work ( How to selectively link certain system libraries statically into Haskell program binary? ), libgmp is still listed in the ldd output.
If you pass -optl-static -optl-pthread to GHC, it'll statically link all the runtime library dependencies, including GMP. Setting ld-options: -static -pthread in your Cabal file should accomplish the same thing.
That means you'll statically link in glibc too, but that probably won't be a problem, although it might increase binary size quite a bit. Using an alternative libc like musl or uClibc should help counteract that, if it's a problem for you.