Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I know which libraries to link against?

Tags:

c++

c

Is there a way (in Linux) to determine which libraries I must link a C/C++ program against? I do not want to miss a library, even in situations when undefined symbols would not be detected at program start. Also, I want to avoid unnecessary dependencies of course.

I formulated this question generally, but here is a specific, nontrivial example: Until recently, I thought that I need to link against libpython for Python modules which are developed with Boost.Python. However, this is not true: Write a module with Boost.Python; it might even use functions from the Python C API, not only Boost.Python. Linking against libboost_python is sufficient! This is not obvious at all—I did not find it documented, at least, and there are Boost.Python modules around which unnecessarily link against libpython. Also, this is hard to detect since libboost_python.so does not list libpython as a dependency as reported by ldd. (I believe that the Python library is loaded dynamically in this instance.)

[Added later: This is independent of Boost.Python. Also if the low-level Python C API is used, a Python module can be compiled and not be linked against libpython, and it will work. However, see the comments and answers below stating that one should link against libpython nonetheless.]

So, how could I have found out about the unnecessary linking systematically instead of using trial and error? What is a good general procedure, not only for this example?

[Added later: Here is what I learned from the comments to my question. The facts below were not clear to me when I posted this question, so I spell them out now, for the benefit of those visiting this discussion in the future, and even if these things are obvious to the helpful commenters. (Thanks!)

Resolving symbols works in a transitive manner in Linux (as pointed out by users MvG and millimoose). Suppose program A needs to resolve symbols from libB and libC. Suppose further that A is linked against libB and libB is linked against libC. Then A can be loaded and executed even if it does not directly refer to libC.

However, it is bad practice to rely on this transitivity, as commenters pointed out. In the case of Python modules written in C/C++, this means that one should link against libpython. For the general case, the goal should not be to identify the minimal list of libraries required for linking and execution—as my orignal question somehow insinuated—but really to provide the linker with the necessary libraries so that all symbols can be resolved directly.

Summarizing Salgar's answer, this information can normally only be obtained from the documentation of the libraries used. Additionally, the GCC linker flag -Wl,--as-needed is useful to identify libraries which are truly unnecessary.]

like image 863
Daniel Avatar asked Apr 04 '13 04:04

Daniel


1 Answers

There is no way of magically knowing which libraries to include, just like there is no way of magically knowing which headers to include.

There could be 10 different libraries, all which have functions with the same names, all doing completely different things. It's up to you to decide which one you want to use.

Generally that won't be the case, but it serves a point of demonstration.

Usually if you're using a boost library, or other similar library, they documentation will let you know which lib you need to link against.

As someone above stated above, you can over-include and use the flag --as-needed, but many people have problems, as generally when you link against a library, it is pulled in at startup time and all global variables from that library are initialised. Whether you need those global variables or not can be a confusing thing for the linker to work out.

In short though, the answer would generally be to read the documentation. Or to compile the code and see which linker errors you get, and then work from there to figure out which libraries you need.

like image 57
Salgar Avatar answered Sep 28 '22 18:09

Salgar