Reputation: 429
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.
Upvotes: 1
Views: 1221
Reputation: 61222
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.
Upvotes: 2