Why isn't boost build preferring the static library? - boost

I am using boost.build.
In one of the steps "g++" -o "testbed/bin/gcc-5.3.0/debug/link-static/get_tag34_tag34_processed" -Wl,--start-group "testbed/bin/gcc-5.3.0/debug/link-static/get_tag34_tag34_processed.o" "/usr/local/lib64/librabbitmq.a" "/usr/lib64/libmysqlcppconn-static.a" "/apps/boost/root/bin.v2/libs/date_time/build/gcc-5.3.0/debug/link-static/libboost_date_time.a" -Wl,-Bstatic -lz -lbz2 -Wl,-Bdynamic -Wl,--end-group -g -lSimpleAmqpClient -lcrypto -ldl -lmysqlcppconn -lpthread -lrdkafka -lrdkafka++ -lssl
I am trying to link to a kafka library.
In the system directory there is the .so and .a /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/librdkafka++.so and /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/librdkafka++.a. However it is preferring the .so.
How do I fix that?

Use full path for .a file. So instead of
-lrdkafka
use
"/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/librdkafka++.a"
(notice lack of '-l')
Alternatively, delete .so. :)
This is not boost.build behavior, this is how gcc and ld work:
-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.

Related

The -l option in GCC

I have just begun reading the book Advanced Programming in Unix Environment and try to compile the first example code, just the same as in this question.
Although the problem for the compilation is solved using the command,
gcc -o myls myls.c -I SCADDRESS/include/ -L SCADDRESS/lib/ -lapue
I looked it up in the GCC manual, but what does the GCC option -lxxx mean? Where xxx stands for the base name of a header file (in this case, it's apue.h). According to the manual, xxx should be some library files, either end with .so for shared object files, or with .a for static libraries.
This is documented in ยง2.13 "Options for Linking" in the GCC manual:
-llibrary
Search the library named library when linking.
It makes a difference where in the command you write this option; the
linker searches processes libraries and object files in the order they
are specified. Thus, `foo.o -lz bar.o' searches library `z'
after file `foo.o' but before `bar.o'. If `bar.o' refers
to functions in `z', those functions may not be loaded.
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.
The directories searched include several standard system directories
plus any that you specify with `-L'.
Normally the files found this way are library files--archive files
whose members are object files. The linker handles an archive file by
scanning through it for members which define symbols that have so far
been referenced but not defined. But if the file that is found is an
ordinary object file, it is linked in the usual fashion. The only
difference between using an `-l' option and specifying a file name is that `-l' surrounds library with `lib' and `.a'
and searches several directories.
The -l option tells GCC to link in the specified library. In this case, the library is apue, and that it happens to line up with the name of a header file is just how the apue coders designed their project.
In reality, the -l option has nothing to do with header files. Like cas says in the comments, read the man page; it'll give you much more information.

Linking to so library in gcc

I will start by saying that I am new to gcc and makefiles. I have a .so file on the desktop (~/Desktop) called lib.so. I want to link my program (called myProgram) to it. What I wrote in my makefile is:
g++ myProgram.o -L ~/Desktop -l lib -o myProgram
When I run make I get an error:
/usr/bin/ld: cannot find -llib
I also tried -l lib.so and got the same error.
What is the correct way to link?
Two solutions:
Rename the file to libsomething.so, then use -l something. The linker automatically wraps the name with lib prefix and .so suffix (or .a suffix for static libraries).
Use the option -l :lib.so. When you prefix the name with :, the linker uses the name as given.
These are explained in the ld man page.

Two ways of linking to static libraries

Here are a couple of ways to use functions from a static library, built with ar (i.e. libSOMTEHING.a):
ld -o result myapp.o -Lpath/to/library -lname
ld -o result myapp.o path/to/library/libname.a
Since we omit any dynamic libraries from the command line, this should build a static executable.
What are the differences? For example, are the whole libraries linked in the executable, or just the needed functions? In the second example, does switching the places of the lib and the object file matter?
(PS: some non-GNU ld linkers require all options like -o to be before the first non-option filename, in which case they'd only accept -L... -lname before myapp.o)
In the first line, a search for a dynamic library (libname.so) occurs before the static library (libname.a) within a directory. Also, the standard lib path is also searched for libname.*, not just /path/to/library.
From "man ld"
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.)
The second line forces the linker to use the static library at path/to/lib.
If there is no dynamic library built (libname.so), and the only library available is path/to/library/libname.a, then the two lines will produce the same "result" binary.

cannot specify root sdk directory with syslibroot when linking

I have a few static libraries I want to link with ld. My libraries are in the directories /Users/rlt/p4/lib/ and /Users/rlt/p4/usr2/lib. I want to pass in the relative paths of these directories w.r.t /Users/rlt/p4 and use the -syslibroot to point to this directory. The documentation for ld says that this option will prepend a pre-fix to all search paths. However, the following command gives me directory not found errors for both paths I specify:
ld -syslibroot /Users/rlt/p4 -L/lib -L/usr2/lib -lA -lB -lC
This gives me could not find /lib and /usr2/lib. I tried using -Lusr2/lib and -Llib with same results. What am I missing?
-syslibroot does not prepend its argument string to arbitrary paths. It will only add it to the paths which are consistent with the sdk directory structure.

What are the --start-group and --end-group command line options?

What is the purpose of those command line options? Please help to decipher the meaning of the following command line:
-Wl,--start-group -lmy_lib -lyour_lib -lhis_lib -Wl,--end-group -ltheir_lib
Apparently it has something to do with linking, but the GNU manual is quiet what exactly grouping means.
It is for resolving circular dependences between several libraries (listed between -( and -)).
Citing Why does the order in which libraries are linked sometimes cause errors in GCC? or man ld http://linux.die.net/man/1/ld
-( archives -) or --start-group archives --end-group
The archives should be a list of archive files. They may be either explicit file names, or -l options.
The specified archives are searched repeatedly until no new undefined references are created. Normally, an archive is searched only once in the order that it is specified on the command line. If a symbol in that archive is needed to resolve an undefined symbol referred to by an object in an archive that appears later on the command line, the linker would not be able to resolve that reference. By grouping the archives, they all be searched repeatedly until all possible references are resolved.
Using this option has a significant performance cost. It is best to use it only when there are unavoidable circular references between two or more archives.
So, libraries inside the group can be searched for new symbols several time, and you need no ugly constructs like -llib1 -llib2 -llib1
PS archive means basically a static library (*.a files)

Resources