简体   繁体   中英

How do I know which libraries to link against?

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

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.

没有任何/琐碎的方法,但你可以通过使用像CMake或AutoConf这样的构建管理工具让自己变得更容易。

When you build Boost, you have the option of building static or dynamic versions of the libs that are compiled. It's been a while since I've built boost, but if I recall it builds both flavors if you just do the easy build.

This is covered in:

With respect to boost.python, the option between static or dynamic library linking is documented here:

The dynamic library is the safest and most-versatile choice:

  • A single copy of the library code is used by all extension modules built with a given toolset.3 The library contains a type conversion registry. Because one registry is shared among all extension modules, instances of a class exposed to Python in one dynamically-loaded extension module can be passed to functions exposed in another such module.

It might be appropriate to use the static Boost.Python library in any of the following cases:

  • You are extending python and the types exposed in your dynamically-loaded extension module don't need to be used by any other Boost.Python extension modules, and you don't care if the core library code is duplicated among them.

  • You are embedding python in your application and either:

    • You are targeting a Unix variant OS other than MacOS or AIX, where the dynamically-loaded extension modules can “see” the Boost.Python library symbols that are part of the executable.

    • Or, you have statically linked some Boost.Python extension modules into your application and you don't care if any dynamically-loaded Boost.Python extension modules are able to use the types exposed by your statically-linked extension modules (and vice-versa).

So, granted, this doesn't explain how you know what to link against in a generic sense. Just that one specific situation.

I think the confusion about how boost.python works and the different experiences people are commenting on with regards to linking might make a little more sense when you look through this lens at least.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM