Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Questions on GCC linker

Apologize because for the moment I don't have the environment to experiment and sort out the following questions myself:

1) Let's say I have four library files: libmylib_super.a and libmylib_super.so, mylib_dumb.a and mylib_dumb.so. While specifying libraries to link to, what are the differences between the following approaches:

A) -l:libmylib_super.a
B) -llibmylib_super
C) -lmylib_super
D) -lmylib_dumb

2) Definition of -static from man page:

On systems that support dynamic linking, this prevents linking with the shared libraries. On other systems, this option has no effect.

Does this linker option have anything to do with question #1? Or... by any chance will they interfere with each other?

Thanks.

--- edited 2009-12-28 ---

I just got my environment up and experimenting a bit, by linking to Boost date_time library. Say I have three library files: libboost_date_time-mt-d.a, libboost_date_time-mt-d.so.1.41.0, libboost_date_time-mt-d.so -> libboost_date_time-mt-d.so.1.41.0 (sym link).

A.1) -l:libboost_date_time-mt-d.a ==> linking OK, binary works even without the library file.
A.2) -l:libboost_date_time-mt-d.a with -static ==> linking error /usr/bin/ld: cannot find -lm

C.1) -lboost_date_time-mt-d ==> linking OK, binary works but requires the shared library file.
C.2) -lboost_date_time-mt-d with -static ==> linking error /usr/bin/ld: cannot find -lm

Any idea about the error in A.2 and C.2?

Additionally, while running the program in C.1, it seems searching the shared library file with name libboost_date_time-mt-d.so.1.41.0 but not the libboost_date_time-mt-d.so. Wouldn't that be inconvenient if the program is running on a system without the exact version of library? What could be the practical way to handle the version while using shared library?

like image 618
shiouming Avatar asked Dec 27 '09 11:12

shiouming


1 Answers

According to the manual,

A) searches the library path for a file exactly named libmylib_super.a (the search first for a shared library behavior doesn't apply)

B) searches the library path for a file named liblibmylib_super.so first then liblibmylib_super.a or only searches for a file named liblibmylib_super.a if -static is used -- note it's the linker that adds the lib prefix and the file extension

C) searches the library path for a file named libmylib_super.so first then libmylib_super.a or only searches for a file named liblibmylib_super.so if -static is used

D) see C)

Note that B) won't work because it's the linker that should add the lib prefix to the library name.

Note that D) won't work because your mylib_dumb doesn't follow the naming convention.

See the GNU Linker Manual:

-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.

See the -( option for a way to force the linker to search archives multiple times.

You may list the same archive multiple times on the command line.

This type of archive searching is standard for Unix linkers. However, if you are using ld on AIX, note that it is different from the behaviour of the AIX linker.

like image 193
Gregory Pakosz Avatar answered Dec 22 '22 01:12

Gregory Pakosz