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)
Related
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.
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.
I have a shared library (libhoard.so) that I'm trying to link with a simple test binary. However, depending on the machine I compile on the shared library doesn't show up in the test binary. I'm not sure what differences exist on the machines and is partly why I'm asking the question. I'm curious what I can do to troubleshoot why the shared library doesn't show up on the test binary on the "broken" machine?
I used this command to compile both binaries (libhoard.so is in the same directory):
$ g++ -L. -lhoard hoard_test.o
Broken machine:
$ ldd a.out
linux-gate.so.1 => (0x00858000)
libstdc++.so.6 => /usr/lib/i386-linux-gnu/libstdc++.so.6 (0x004dc000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x00aaf000)
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0x00675000)
/lib/ld-linux.so.2 (0x00d18000)
libgcc_s.so.1 => /lib/i386-linux-gnu/libgcc_s.so.1 (0x0040d000)
Working machine:
$ ldd a.out
linux-gate.so.1 => (0x00110000)
libhoard.so (0x00111000) <----------------- THERE IT IS!
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x03ba8000)
libm.so.6 => /lib/libm.so.6 (0x007a9000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00bf7000)
libc.so.6 => /lib/libc.so.6 (0x0063e000)
libdl.so.2 => /lib/libdl.so.2 (0x007d4000)
libpthread.so.0 => /lib/libpthread.so.0 (0x007db000)
/lib/ld-linux.so.2 (0x0061e000)
Here is some random version information:
Broken machine:
$ uname -srv
Linux 2.6.38-11-generic #50-Ubuntu SMP Mon Sep 12 21:18:14 UTC 2011
$ g++ --version
g++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
Working machine:
$ uname -srv
Linux 2.6.25.3-18.fc9.i686 #1 SMP Tue May 13 05:38:53 EDT 2008
$ g++ --version
g++ (GCC) 4.3.0 20080428 (Red Hat 4.3.0-8)
tl;dr version: Add -Wl,--no-as-needed to the link command.
After a series of experimentation and conversations with the OP, I've figured out what's going on.
In the latest version of Ubuntu, ld uses --as-needed by default. What that does is to remove references to libraries that are not explicitly required.
The way Hoard works is as an LD_PRELOAD library. i.e., you are not supposed to need to use functions in libhoard.so directly. Of course, you could link in libhoard directly if you wanted to...unless --as-needed is used, of course.
After discovering this, the solution is simple. Just add -Wl,--no-as-needed to the gcc linking command.
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