libc.so
is a linker script, a small text file which looks like this (lines wrapped here for readability):
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf64-x86-64)
GROUP (
/lib/x86_64-linux-gnu/libc.so.6
/usr/lib/x86_64-linux-gnu/libc_nonshared.a
AS_NEEDED ( /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 )
)
It instructs the link editor (ld
, which is invoked while linking during build, i.e., not the dynamic linker) to look for symbols first in libc.so.6
, a shared object, then in libc_nonshared.a
if it cannot find it, and finally in the dynamic loader, ld-linux-x86-64.so.2
). This is used to implement certain features, for example in newer versions of glibc, the caller-senitive function pthread_atfork
(which must be linked statically, so it is placed in libc_nonshared.a
and not libc.so.6
). The linker script is usually invoked implicitly by the gcc
or g++
commands, but occasionally, you will see command lines which contain -lc
, and those pick up the libc.so
script (when linking dynamically).
The linker script is only used at build time. If you image contains development libraries such as libsqlite3-dev
, it is necessary to include libc6-dev
(or whatever the package is called that provides the libc.so
linker script) because libsqlite3-dev
is not usable for linking new programs and shared objects without glibc.