What is the difference between LDADD and LIBADD? - c++

I'm trying to setup an automake project that uses a mix of libtool libraries and exectuables, and I'm having a hard time grokking the automake documentation, esp. as relates to telling the compiler to link against.
So can someone explain the differences between LDADD and LIBADD?
Things like:
when is one used over the other,
which one takes -lname_of_library style values vs. direct filenames,
etc.
Whenever I try to read the relevant documentation, it seems like it assumes that I know things that I don't.

Use the LIBADD primary for libraries, and LDADD for executables. If you were building a libtool library libfoo.la, that depended on another library libbar.la, you would use:
libfoo_la_LIBADD = libbar.la
If you had other non-libtool libraries, you would also add these with -L and -l options:
libfoo_la_LIBADD = libbar.la -L/opt/local/lib -lpng
Typically, you would use the configure script to find these extra libraries, and use AC_SUBST to pass them with:
libfoo_la_LIBADD = libbar.la $(EXTRA_FOO_LIBS)
For a program, just use LDADD :
myprog_LDADD = libfoo.la # links libfoo, libbar, and libpng to myprog.
Sometimes the boundaries are a bit vague. $(EXTRA_FOO_LIBS) could have been added to myprog_LDADD. Adding dependencies to a libtool (.la) library, and using libtool do all the platform-specific linker magic, is usually the best approach. It keeps all the linker metadata in the one place.

As mentioned in one of the books, LDADD is ADDitional linker(LD) items - i.e. items that are added when performing linking. This would be, for example, when producing programs. LDADD can specify:
libtool files e.g. lib/libfudge.la
libraries e.g. -lm, or
full paths to libraries e.g. /lib/libmagicalwonderland.a
link flags & libraries e.g. -L/opt/lib -lmagical
They are in order of preference - Using the last two is just asking for trouble as they're pointing at things that may or may not be present.
LIBADD is to specify ADDitional LIBraries to use. This is used when building a library to specify that additional libraries are needed in order to build or make use of the library. You'll see it specified as something like libfred_la_LIBADD =. It can be used to specify libtool libraries, or system libraries and will place these libraries into the resulting libtool .la for the library so when it comes to linking against the library you get all the appropriate libraries brought along.
You should only specify libraries to link, so, for example, my library libfred.la depends on some math routines i.e. it depends on libm. When I'm specifying the additional libraries for the library, I state:
libfred_la_LIBADD = -lm
This dependency is encoded when I build the library, and gets passed on to consumers of the library as well.
The rule of thumb is:
LIBADD for things that are being added to a library
LDADD for things that are being added to a program

Related

Search order in LD_LIBRARY_PATH

A shared object library required by my program is present in two paths under LD_LIBRARY_PATH, but only one of the two should be loaded by my program because of version compatibility issue. For example, if LD_LIBRARY_PATH is path1:path2 and the shared library libxxx.so is in both path1 and path2, will path1/libxxx.so be loaded or path2/libxxx.so be loaded when I run the program?
Also I would appreciate it if anyone has a better solution than reordering the paths in LD_LIBRARY_PATH. After searching on the internet I saw some solution using rpath but didn't quite understand how that works.
The directories get searched in the order they appear in LD_LIBRARY_PATH.
Keep in mind that the loader also looks elsewhere, not just LD_LIBRARY_PATH, which may or may not be a factor.
Since you asked for a "better solution", here are two:
Get this broken shared library built correctly
There is a well-established mechanism and convention for versioning shared libraries so that different versions of the same shared library get loaded. A program that needs a particular version of a shared library will load the one that it needs.
In fact, it's a safe bet that you already have a bunch of different versions of multiple shared libraries installed, due to applications in your Linux distribution that need different versions of the same shared library.
This is nothing more complicated than not using the same name for incompatible versions of the same shared library. There is a well-defined convention for naming actual shared library filenames, that work together with the linker in order to make this happen (the -soname link option, see your linker documentation for more information).
Don't use LD_LIBRARY_PATH
It is possible to link an executable and embed in the executable itself a pathname to search, first and foremost, for any shared libraries, either before or after LD_LIBRARY_PATH.
Remove all directories from LD_LIBRARY_PATH.
Use the -rpath, with/without --enable-new-dtags or --disable-new-dtags option when linking your executable. The correct set of options depends on your specific details, and specific versions of your linker. See your linker documentation for more information. You mentioned you tried to find information on this in Google, but all that Google will do is, perhaps, refer you to the same documentation that you already have: the manual pages for the linker. That's the best source for complete information on using this or any other linker option.
The best solution depends on your specific circumstances; whether you're building the executable, and/or shared libraries, how easy/hard it is to change whatever you're building; or whether you're not building anything at all, just black boxes that need to be executed.

Locating which methods in C/C++ libraries to link against on *NIX

In the past, what has worked for me when I'm very lazy (for both Linux and Windows) was to just boldly use "grep -r" in each possible lib paths (i.e. /lib, /lib64, /usr/lib, etc) which I know the libs resides at, to see if I can guess which libs are the probable candidates to link against and make sure to add the "-L" paths and "-l" lib files.
For most of MSDN documented libraries, usually, Microsoft is nice enough to indicate which DLL's to link against, but for Linux it's a little more work (i.e. I need to possibly use search engine on multiple sites). For example, let's take ntohl(), which MSDN kindly shows static .lib and dynamic .dll files I can link against (it would be nice to know the paths, but that I can 'find' later). If I 'man 3 ntohl' for example, the best it can tell me is that I need to #include arpa/inet.h, but I'd still have to find out (for me, grep) which lib to link against (perhaps ntohl() is not a good example since it's usually part of libc.so, but please bear with me, the point is, I had to grep to find out it's on libc.so).
Q: What are the right (practiced) ways to locate methods of C/C++ libraries that will accurately tell me which binary files has the implementations for the method I want to link against?
NOTE: Please disregard the versions (i.e. libc-2.19.so vs libc-xx.so) and arch/target (i386-linux-gnu vs x86_64-linux-gnu), which is not as important as locating the correct lib files which has the actual implementations for linking.
Typically, unless otherwise specified, all functions come from the default C or C++ library that the compiler will link with by default.
Otherwise, the expectation is that the manual page for the library function will explicitly indicate that a non-default library must be linked with. For example, the manual page for pthread_create(3) tells you that linking with -lpthread is required.
Of course, one has to be dependent on third party libraries providing adequate documentation, either by supplying traditional manual pages, with linking instructions of this manner, or via some other documentation. Quite often, the library's website will have documentation that explains how to use the library.
Linux is not controlled by a monolithic entity that imposes uniform documentation requirements.
Many packages use pkg-config or their own version like mysql_config.
You can add the flags to the compiler using those tools:
g++ $(pkg-config somelib --cflags) -o prog prog.cpp $(pkg-config somelib --libs)
Otherwise I use the package manager to tell be what libraries are contained in a given package and where they get installed to.
To discover what libraries are available through pkg-config use:
pkg-config --list-all
Use man pkg-config for more information.

Boost Logger Static Linking: Not Working

I have a Qt application that uses the boost logger library. I want to make it a standalone. However, after I managed the libraries for static linking, the application is still dependent on boost libraries.
The libraries that I included are:
..../boost_1_61_0_b1/stage/lib/libboost_regex.a
..../boost_1_61_0_b1/stage/lib/libboost_log_setup.a
..../boost_1_61_0_b1/stage/lib/libboost_thread.a
..../boost_1_61_0_b1/stage/lib/libboost_log.a
..../boost_1_61_0_b1/stage/lib/libboost_system.a
..../boost_1_61_0_b1/stage/lib/libboost_filesystem.a
The application compiles( after countless attempts). However, when I use ldd tool, it shows boost libraries on the dependency list.
Note: I have to define BOOST_ALL_DYN_LINK. Otherwise, it doesn't link.
Is there any way not to use this macro and overcome the dependency problem ? If not, what solutions do you suggest to circumvent this problem?
By default on modern UNIX-like systems gcc links with shared libraries by default. In order to force static linking you can either add -static to your linking command line (see the docs) or make sure gcc doesn't find the shared libraries but only finds the static libraries (e.g. move the shared libraries to a separate directory while you're linking your project). Note that -static will make all libraries linked statically, including libstdc++.
Alternatively, you can specify the static libraries directly, without the -l switch. You will have to use the full path to the libraries though, so instead of
gcc ... -lboost_log ...
you would write
gcc ... ..../boost_1_61_0_b1/stage/lib/libboost_log.a ...
In any case, you should not define BOOST_ALL_DYN_LINK because this macro means exactly the opposite - that you intend to link with Boost shared libraries.

Linking dependencies of a shared library

I was working with SFML, I compiled a little test program and added the linkage option -lsfml-audio. Then, I used ldd ./program to see the dynamic libraries it was linking to. Surprisingly, there were a lot, none of them had I manually selected in my makefile, nor using pkg-config --libs.
I started reading about shared libraries, and made a little example to solve my doubts. However, I have this question:
why some libraries need you to add the dependencies in your makefile
(either manually or using a script like pkg-config) and other
libraries automatically link their dependencies?
When you're creating your dynamic library, is just as easy as adding the proper -ldependency options in the g++ -shared ... command to avoid the user the hassle of manually adding the dependencies later on. Why many of the available libraries don't do that?
I guess it must be related to the ability of fine tuning which libraries get linked and such.
Shared libraries will generally link in their dependencies. However, static libraries are not capable of doing so. pkg-config --libs often includes all dependencies (direct and indirect) so that you can switch to static compilation by simply adding -static without having to add additional library dependencies as well.
Note that these excess direct dependencies are considered unwanted in some cases (eg, debian tries to avoid them in packaged binaries, as they make library soname transitions more traumatic than necessary). You can instruct the linker to strip direct dependencies from the final executable that aren't needed with the -Wl,--as-needed flag.

How to optionally depend on a shared object with gcc?

First, I don't know if there is a solution to my problem at all.
I have the following situation:
I have developed a framework library that depends on several other libraries for specific hardware access, etc.
Until now this framework library was only statically linked against.
For the executable that uses the framework library only the dependencies of code that is actually used by the executable have to be linked. (If I don't access a specific hardware at all I don't have to depend on its associated libraries.)
Now I need to also make a shared object of the framework library. Also the dependencies are available as shared libraries, so there is no need for any static linking.
The problem I have now:
When building an application that links dynamically to the framework library I have to either link all dependencies dynamically to the framework library or the application. (Otherwise I get undefined references complaints from ld)
My questions:
Is there any way to ignore certain shared object dependencies if I know that my application will not use any code of the framework library that depends on this shared object?
Is there any way to do this without or with minimal code changes? (linker / compiler switches)
I also need the static linking as described in the original situation to still work.
Additional Info:
Operating system: Linux (Debian Lenny)
Compiler: gcc-4.3
You can, but you basically have to do all of the dynamic library handling yourself. i.e. dlopen the library, and then look up the symbols you need directly with dlsym.
It will make your code more complicated, how much depends on the interface you've got into the libraries.
From man ld
--as-needed
--no-as-needed
This option affects ELF DT_NEEDED tags for dynamic libraries mentioned on the command line after the --as-needed option. Normally,
the linker will add a DT_NEEDED tag for each dynamic library mentioned on the command line, regardless of whether the library is
actually needed. --as-needed causes a DT_NEEDED tag to only be emitted for a library that satisfies a symbol reference from regular
objects which is undefined at the point that the library was linked, or, if the library is not found in the DT_NEEDED lists of other
libraries linked up to that point, a reference from another dynamic library. --no-as-needed restores the default behaviour.
I haven't used it myself but sounds like what you're looking for.
g++ -o your_app -Wl,--as-needed -lframework -la -lb -lc -Wl,--no-as-needed
Edit (suggested by Hanno)
--warn-unresolved-symbols
If the linker is going to report an unresolved symbol (see the option --unresolved-symbols) it will normally generate an error.
This option makes it generate a warning instead.