why is gcc linking dynamically when -l is used?

Viewed 768

I did a "Hello World" program using the pthread library. I compile it this simple way:

$ gcc main.c -lpthread

According to gcc Documentation ("Options for Linking" section):

-llibrary [...] The linker searches a standard list of directories for the library, which is actually a file named liblibrary.a. The linker then uses this file as if it had been specified precisely by name. [...]

So, my understanding is: gcc is looking for libpthread.a . Given the .a ending, this should be a static library.

However, this is dynamically linked:

$ ldd a.out
        linux-vdso.so.1 =>  (0x00007fffde3c3000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fb345820000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb345456000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fb345a3d000)

What am I missing?

1 Answers

The documention of the -l|--library option in the GCC manual is misleading, in that it does not specify the behaviour of the option on systems that support shared libraries, or warn us that it does not do so.

The -l option is passed through to the linker, usually GNU ld (or drop-in alternative). The documentation of the option in the ld manual is superior and makes clear that a shared library will satisfy the -l option in preference to a static library.

-l namespec

--library=namespec

Add the archive or object file specified by namespec to the list of files to link. This option may be used any number of times. If namespec is of the form :filename, ld will search the library path for a file called filename, otherwise it will search > the library path for a file called libnamespec.a.

On systems which support shared libraries, ld may also search for files other than libnamespec.a. Specifically, on ELF and SunOS systems, ld will search a directory for a library called libnamespec.so before searching for one called libnamespec.a. (By convention, a .so extension indicates a shared library.) Note that this behavior does not apply to :filename, which always specifies a file called filename.

The linker will search an archive only once, at the location where it is specified on the command line. If the archive defines a symbol which was undefined in some object which appeared before the archive on the command line, the linker will include the appropriate file(s) from the archive. However, an undefined symbol in an object appearing later on the command line will not cause the linker to search the archive again.

...

(my emphasis)

Related