Application failed to run on Arch Linux with glibc package version 2.35-2 - glibc

The strange thing is that teh glibc package version 2.35-2 does not contain /usr/lib/libdl.so nor /usr/lib/libpthread.so
Here is strace:
chilkat/chilkat-9.5.0-x86_64-linux-gcc/lib/glibc-hwcaps/x86-64-v3/libdl.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)

libdl.so and libpthread.so are link editor input files, they are not used at run time. Instead, the sonames libdl.so.2 and libpthread.so.0 are used for run-time dynamic linking.
Starting with glibc 2.34, explicitly linking against libdl or libpthread is no longer needed (as all functions are provided by libc directly). Therefore, libdl.so and libpthread.so have been replaced by empty static archives libdl.a and libpthread.a, so that the linker arguments -ldl and -lpthread keep working.

Related

Statically linking any library causes libc to fail to be linked against

My system is an older NAS running 2.6.32. I have found that when using -static for any subsequent library, it will also try to statically link any other library that I might need.
When I add the -Wl,-Bdynamic flag first and then explicitly name those libraries using -lc, such as "-Wl,-Bdynamic -lc -lstdc++" then it works. So what happens is that libc and others fail to be statically linked.
The static libc on the system is called /opt/lib/libc_nonshared.a.
The contents of /opt/lib/libc.so is this:
OUTPUT_FORMAT(elf32-littlearm)
GROUP ( /lib/libc.so.6 /opt/lib/libc_nonshared.a )
The gcc version is 4.2.3. The current build command I am facing adds -dynamic at the end but this doesn't help much. When I add some static library directly using its .a name, and not using a -l flag, then there is no issue.
The problem seems to be that the dynamic library of libc came with the NAS, but the static version sits in /opt/lib.
I run:
gcc hamming.c -static -L. -L/opt/lib -l:matrix.a -o hamming
I get:
/opt/lib/gcc/arm-none-linux-gnueabi/4.2.3/../../../../arm-none-linux-gnueabi/bin/ld: cannot find -lc
collect2: ld returned 1 exit status
make: *** [hamming] Error 1
when I try to use static libc as is. Were I to perform a 'hack' to link libc_nonshared.a to libc.a, it suddenly does find it. But complains:
hamming.c:54: undefined reference to `malloc'
hamming.c:54: undefined reference to `memset'
And a zillion other errors of course. As mentioned above, /opt/libc.so contains the reference to both files (dynamic and static).
For libstdc++ only a .la file exists.
The -static linker flag does not take any argument. It is a boolean
flag that simply directs the linker to link no shared libraries, as
documented
-static
Do not link against shared libraries...
There is no need to explicitly direct the linker to link shared (dynamic)
libraries when it has a choice because that is the default bevaiour. If
you simply link, e.g.
gcc -o prog ... -lfoo ...
then the linker will link the first of libfoo.so (shared) or libfoo.a
(static) that it finds in any of the specified (-Ldir) or default
search directories, searched in commandline sequence. If it finds both
libfoo.so and libfoo.a in the same directory then it will choose
libfoo.so. Thus shared and static libraries may be freely intermixed
without any special options.
Specify -static only if you wish to link only static libraries.
If you wish to insist on linking a particular libfoo.a even when
libfoo.so is in the same directory and would be chosen by default,
use the explicit form of the -l option: -l:libfoo.a
Later
gcc hamming.c -static -L. -L/opt/lib -l:matrix.a -o hamming
This command is failing with:
ld: cannot find -lc
because the linker (ld) cannot find a static library libc.a in
any of the specified linker search directories (-L. -L/opt/lib) or
the default linker search directories. If you wish instead to link
/opt/lib/libc_nonshared.a then your command should be:
>gcc hamming.c -static -L. -L/opt/lib -l:matrix.a -lc_nonshared -o hamming
However, you have not explained why you want to link this program statically
(-static) in the first place, which is not the usual way and will require you to have installed
static versions of all libraries required for the linkage - both those
you explicitly link and the default libraries that gcc will add for C language
linkage (Standard C library, GCC runtime library).
Supposing you have a static library called (oddly) matrix.a (rather
than normally, libmatrix.a) that is located in /some/dir/, then the
normal way to compile and link your program would be:
gcc hamming.c -L/some/dir -l:matrix.a -o hamming
I suggest you start with that and deviate only as problems compel
you to.
The discovery of an /opt/lib/libc.so containing:
OUTPUT_FORMAT(elf32-littlearm)
GROUP ( /lib/libc.so.6 /opt/lib/libc_nonshared.a )
is misleading you. This is not your shared libc. A shared library
is a binary. This is a linker script, and it says that your shared libc
is in fact /lib/libc.so.6. The linker will almost certainly find and use it by default.

The program cannot find correct version of glibc/libstdc++, although it was statically linked

I am trying to link my program statically with glibc, because version of the glibc on the target machine is pretty much unpredictable. I used linker flags -static-libgcc and -static-libstdc++ and it worked fine. The executable is big, but I can live with it. Unfortunately, when I run my executable on the target machine (it is named 'mytest' in the example below) I get the following error:
./mytest: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by libboost_log.so.1.53.0)
./mytest: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by libboost_log.so.1.53.0)
./mytest: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by libboost_log.so.1.53.0)
./mytest: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by libboost_date_time.so.1.53.0)
./mytest: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by libboost_thread.so.1.53.0)
If I do 'strings' on mytest, it gives me
$ strings mytest | grep GLIBC
GLIBC_2.9
GLIBC_2.7
GLIBC_2.8
GLIBC_2.3.2
GLIBC_2.2.5
GLIBCXX_3.4.15
GLIBCXX_3.4.11
GLIBCXX_3.4.14
GLIBCXX_3.4.9
GLIBCXX_3.4
What means, I think, that the static linking was working ok. Why does the loader still tries to look for my functions in shared glibc and libstdc++? What am I doing wrong?
Thanks!
I am trying to link my program statically with glibc, because version of the glibc on the target machine is pretty much unpredictable. I used linker flags -static-libgcc and -static-libstdc++ and it worked fine.
That didn't affect the version of glibc (libc), which is different from libgcc and libstdc++. With these flags, you still have produced a dynamically-linked executable, which is expected to not work on an older distribution.
You can link your executable with -static flag, and that should give you a completely static executable.
Update:
After re-reading your question; your problem is not with glibc. Your problem is that you are linking with libboost_log.so, which itself depends on libstdc++.so.6.
The answer then is to link with libboost*.a instead of libboost*.so. You can try to achieve it this way:
g++ $(OBJS) -static-libgcc -static-libstdc++ -Wl,-Bstatic -lboost_log ... \
-Wl,-Bdynamic
(It is very important to have the trailing -Wl,-Bdynamic.)
Linking with -static-libgcc and -static-libstdc++ will only work for those libraries. It looks like you are also linking against the boost libraries (likely dynamically) which then link against libgcc and libstdc++.
Try running the following:
ldd mytest
It should show "not a dynamic executable". If it shows anything else, it means it is dynamically linked against other libraries. It doesn't always work so easily, but try adding -static to the compilation line as well to take care of remaining libraries.

What is the difference between /lib/i386-linux-gnu/libc.so.6, /lib/x86_64-linux-gnu/libc.so.6 and /usr/lib/x86_64-linux-gnu/libc.so?

I installed Matlab in my Linux Mint 14 Nadia (a uname -a shows: Linux Ideapad-Z570 3.5.0-17-generic #28-Ubuntu SMP Tue Oct 9 19:31:23 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux) and when calling it from the command line I would get a: "/lib64/libc.so not found".
I followed the help on mathworks by making a link in /lib64 as:
ln -s /lib/x86_64-linux-gnu/libc.so.6 .
That solved the issue.
Now, if I do a locate of this library I get:
locate "libc.so"
/lib/i386-linux-gnu/libc.so.6
/lib/x86_64-linux-gnu/libc.so.6
/usr/lib/x86_64-linux-gnu/libc.so
I will be compiling with gcc in this computer and I would like to have full 64bit compilations. What does exactly mean to have all these different libc.so libraries? which one will the gnu compiler be using? do I need to do anything different with gcc to compile for 64 bits?
I would also love to optimize as much as I can for my new i7 core!!!
/lib/i386-linux-gnu/libc.so.6
This is is 32-bit version of the library.
/lib/x86_64-linux-gnu/libc.so.6
This is the 64-bit version of the library.
Both are usually symbolic links to the actual library file, which will usually be named according to the glibc release number, for example libc-2.15.so
/usr/lib/x86_64-linux-gnu/libc.so
This is not a library, but a linker script file, which refers to the above symlinks.
Why do we need all these:
First, regardless of libc version installed, the linker will always search for libc.so, because the compiler driver will always pass to the linker the -lc options. The name libc stays the same and denotes to most recent version of the library.
The symlinks libc.so.6 are named after the soname of the library, which, more or less corresponds to the ABI version of the library. The executables, linked against libc.so in fact contain runtime dependencies on libc.so.6.
If we imagine the someday a grossly ABI incompatible libc is released, it's soname could be named libc.so.7, for example and this version coukld coexists with the older libc.so.6 version, thus executables linked against one or the other can coexist in the same system,
And finally, the name libc-2.15.so refers to the libc release, when you install a new libc package, the name will change to libc-2.16.so. Provided that it is binary compatible with the previous release, the libc.so.6 link will stay named that way and the existing executables will continue to work.
To find which one to use, you have to first find the order that ld (the linker) uses to find libraries, like so:
ld --verbose | grep SEARCH
For me it gave me this output:
SEARCH_DIR("/usr/x86_64-unknown-linux-gnu/lib64"); SEARCH_DIR("/usr/x86_64-unknown-linux-gnu/lib"); SEARCH_DIR("/usr/lib"); SEARCH_DIR("/usr/local/lib");
This means that on my computer, ld looks in these directories, in order:
/usr/x86_64-unknown-linux-gnu/lib64
/usr/x86_64-unknown-linux-gnu/lib
/usr/lib
/usr/local/lib
So if libc was in /usr/x86_64-unknown-linux-gnu/lib64, and libc was also in /usr/lib, it would use the /usr/x86_64-unknown-linux-gnu/lib64 version, because it was listed first.
The symlink you created will have no effect whatsoever on GCC. The 32-bit version is only used when you compile using the -m32 GCC flag. GCC will not attempt to generate 32-bit binaries unless you specifically tell it to (by using that flag.)

preparing lapack dll with mingw

I downloaded lapack 3.3.0 version and mingw (with all libraries) after that I succeded to make blas.dll by gfortran --shared -o blas.dll blas\src\*.f -O
I could not succeeded to make lapack.dll by gfortran --shared -o lapack.dll src\*.f blas.dll -O
I got the following error
gfortran: error: CreateProccess: No such file or directory
Note: I set path to mingw/bin and also copied dlamch.f and slamch.f from install directory to src directory.
:: instructions got from this site
http://www.codingday.com/compile-lapack-and-blas-as-dll-on-windows/
What should I do
I donwloaded lapack and can reproduce the error.
As is indicated in the comments on the page you referred to, you might be running into a problem with the command line being too long for the shell to handle. Try first compiling all source files, and then linking them, in two separate steps.
gfortran -c src/*.f -O
gfortran -shared -o lapack.dll *.o blas.dll
When I did this the CreateProcess error went away, but unfortunately some undefined reference errors popped up next. It appears there are references to a couple of blas functions which aren't included in the blas sources accompanying lapack (I think they might be C functions).

How to link to a specific version of the standard library (with gcc)

I've installed GCC 3.4 to /opt/gcc-3.4, and I'm using it to compile legacy code which is incompatible with GCC 4. This also means old versions of the C(++) standard libraries, binutils, and utility libraries.
It works fine for some libraries, but fails when compiling libtiff, because it picks up the system libraries in /usr/lib (see output below). This might be an autotools/configure issue, but I'm not sure. I can't find a configure switch or environment variable, and I'd rather not modify my system /usr/lib/libc.so .
So how to make sure it links to the standard library in /opt/gcc-3.4.4/lib, and ignores /lib and /usr/lib completely?
Output of make (excerpt):
libtool: link: g++ -shared -nostdlib /usr/lib/crti.o /opt/gcc-3.4.3/lib/gcc/i686-pc-linux-gnu/3.4.3/crtbeginS.o .libs/tif_stream.o -Wl,--whole-archive ../port/.libs/libport.a -Wl,--no-whole-archive -Wl,-rpath -Wl,/home/jason/d0src34/prereq/tiff-3.9.4/libtiff/.libs -Wl,-rpath -Wl,/opt/gcc-3.4.3/lib -Wl,-rpath -Wl,/home/jason/d0src34/prereq/usr/lib -Wl,-rpath -Wl,/opt/gcc-3.4.3/lib ../libtiff/.libs/libtiff.so -L/usr/lib /usr/lib/libjpeg.so -lz -L/opt/gcc-3.4.3/lib/gcc/i686-pc-linux-gnu/3.4.3 -L/opt/gcc-3.4.3/lib/gcc/i686-pc-linux-gnu/3.4.3/../../.. /opt/gcc-3.4.3/lib/libstdc++.so -L/home/jason/Downloads/gcc-3.4.3/build/i686-pc-linux-gnu/libstdc++-v3/src -L/home/jason/Downloads/gcc-3.4.3/build/i686-pc-linux-gnu/libstdc++-v3/src/.libs -L/home/jason/Downloads/gcc-3.4.3/build/gcc -lm -lc -lgcc_s /opt/gcc-3.4.3/lib/gcc/i686-pc-linux-gnu/3.4.3/crtendS.o /usr/lib/crtn.o -Wl,-soname -Wl,libtiffxx.so.3 -o .libs/libtiffxx.so.3.9.4
/home/jason/d0src34/prereq/usr/bin/ld:/usr/lib/libc.so: file format not recognized; treating as linker script
/home/jason/d0src34/prereq/usr/bin/ld:/usr/lib/libc.so:5: parse error
I've found a (hackish) answer to my own question:
I've been using binutils 2.15, because later versions have an incompatibility with GCC 3.4. In more recent versions, the format of /usr/lib/libc.so has changed, and the old binutils can't parse it.
I temporarily commented out the last line (with "GROUP"), and my code compiled:
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf32-i386)
/* GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux.so.2 ) ) */
However, I'm not really satisfied, since I can hardly tell other people who want to use the code to edit their system files. Also, I'm not sure if I've linked it to the correct glibc version, since the system /usr/lib is still in the search path, so I can't tell for sure if the binaries will work on other systems.

Resources