Xennex81
Xennex81

Reputation: 429

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.

Upvotes: 1

Views: 1221

Answers (1)

Mike Kinghan
Mike Kinghan

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

Related Questions