链接共享库时添加到可执行文件的内容是什么?

时间:2022-09-18 12:34:45

If I want to create a C++ program that links with a static library, then the final executable will contain both the code from my program, and the code from the library (I think...!). But I'm not entirely sure as to what happens when I link with a shared library.

如果我想创建一个与静态库链接的C ++程序,那么最终的可执行文件将包含我程序中的代码和库中的代码(我认为......!)。但是我不确定当我与共享库链接时会发生什么。

Suppose I link with a library called libfoo.so, by specifying in my CMakeLists.txt file the line target_link_libraries(${PROJECT_NAME} foo). I'm assuming that the final executable will contain some information about this library, but not the full code. What is this other information? And furthermore, does the library have to be called exactly libfoo.so on the user's system?

假设我链接到一个名为libfoo.so的库,通过在我的CMakeLists.txt文件中指定target_link_libraries($ {PROJECT_NAME} foo)行。我假设最终的可执行文件将包含有关此库的一些信息,但不包含完整的代码。这是什么其他信息?而且,库是否必须在用户的系统上完全被称为libfoo.so?

1 个解决方案

#1


6  

When you link to a dynamic library, the linker will add a NEEDED entry in the dynamic section of the program. Then the dynamic loader will use these to locate the library and use the library to solve any undefined dynamic symbol.

链接到动态库时,链接器将在程序的动态部分中添加NEEDED条目。然后动态加载器将使用它们来定位库并使用库来解决任何未定义的动态符号。

Note that there is no connection between the undefined dynamic symbols and the dynamic libraries where they are expected to be found. Sometimes they are found in another library and interesting things may happen.

请注意,未定义的动态符号与期望找到它们的动态库之间没有任何关联。有时他们会在另一个图书馆找到,有趣的事情可能会发生。

The particular name stored in the NEEDED entry depends on whether the library has a SONAME entry in its dynamic section:

存储在NEEDED条目中的特定名称取决于库是否在其动态部分中具有SONAME条目:

  • If there is a SONAME, then its contents will be copied to the NEEDED of the program
  • 如果有SONAME,则其内容将被复制到程序的NEEDED

  • If there is no SONAME, the the file name of the library as used in the linker command will be stored.
  • 如果没有SONAME,将存储链接器命令中使用的库的文件名。

You can check the contents of the dynamic section of a library or program with:

您可以使用以下命令检查库或程序的动态部分的内容:

$ objdump -p program

How is this used in practice? Well, most (all?) linux distributions use the following scheme, with the system libraries (take libfoo.so):

这在实践中如何使用?那么,大多数(所有?)linux发行版使用以下方案,系统库(采取libfoo.so):

  • The library is installed as /usr/lib/libfoo.so.1.2 or whatever version it is.
  • 该库安装为/usr/lib/libfoo.so.1.2或其任何版本。

  • The are symbolic links to that library named /usr/lib/libfoo.so.1 and /usr/lib/libfoo.so.
  • 这是名为/usr/lib/libfoo.so.1和/usr/lib/libfoo.so的库的符号链接。

  • The SONAME of the library is libfoo.so.1.
  • 库的SONAME是libfoo.so.1。

  • The path /usr/lib is set as as dynamic library path.
  • 路径/ usr / lib设置为动态库路径。

That way, when you link with -lfoo it will find the symlink libfoo.so, but will record the SONAME as libfoo.so.1. And when the program is run it will find the other symlink and load the library.

这样,当您与-lfoo链接时,它将找到符号链接libfoo.so,但会将SONAME记录为libfoo.so.1。当程序运行时,它将找到另一个符号链接并加载库。

This trick is used so that you can install an ABI compatible, improved libfoo.so.1.3 and an ABI incompatible newer libfoo.so.2.1, and old program will load the old library while new compilations will use the new library.

使用此技巧,以便您可以安装ABI兼容,改进的libfoo.so.1.3和ABI不兼容的新libfoo.so.2.1,旧程序将加载旧库,而新编译将使用新库。

Also note that the environment variables LD_PRELOAD, LD_LIBRARY_PATH and others affect the runtime behaviour. For more details, you can read man ld.so

另请注意,环境变量LD_PRELOAD,LD_LIBRARY_PATH等会影响运行时行为。有关更多详细信息,请阅读man ld.so

#1


6  

When you link to a dynamic library, the linker will add a NEEDED entry in the dynamic section of the program. Then the dynamic loader will use these to locate the library and use the library to solve any undefined dynamic symbol.

链接到动态库时,链接器将在程序的动态部分中添加NEEDED条目。然后动态加载器将使用它们来定位库并使用库来解决任何未定义的动态符号。

Note that there is no connection between the undefined dynamic symbols and the dynamic libraries where they are expected to be found. Sometimes they are found in another library and interesting things may happen.

请注意,未定义的动态符号与期望找到它们的动态库之间没有任何关联。有时他们会在另一个图书馆找到,有趣的事情可能会发生。

The particular name stored in the NEEDED entry depends on whether the library has a SONAME entry in its dynamic section:

存储在NEEDED条目中的特定名称取决于库是否在其动态部分中具有SONAME条目:

  • If there is a SONAME, then its contents will be copied to the NEEDED of the program
  • 如果有SONAME,则其内容将被复制到程序的NEEDED

  • If there is no SONAME, the the file name of the library as used in the linker command will be stored.
  • 如果没有SONAME,将存储链接器命令中使用的库的文件名。

You can check the contents of the dynamic section of a library or program with:

您可以使用以下命令检查库或程序的动态部分的内容:

$ objdump -p program

How is this used in practice? Well, most (all?) linux distributions use the following scheme, with the system libraries (take libfoo.so):

这在实践中如何使用?那么,大多数(所有?)linux发行版使用以下方案,系统库(采取libfoo.so):

  • The library is installed as /usr/lib/libfoo.so.1.2 or whatever version it is.
  • 该库安装为/usr/lib/libfoo.so.1.2或其任何版本。

  • The are symbolic links to that library named /usr/lib/libfoo.so.1 and /usr/lib/libfoo.so.
  • 这是名为/usr/lib/libfoo.so.1和/usr/lib/libfoo.so的库的符号链接。

  • The SONAME of the library is libfoo.so.1.
  • 库的SONAME是libfoo.so.1。

  • The path /usr/lib is set as as dynamic library path.
  • 路径/ usr / lib设置为动态库路径。

That way, when you link with -lfoo it will find the symlink libfoo.so, but will record the SONAME as libfoo.so.1. And when the program is run it will find the other symlink and load the library.

这样,当您与-lfoo链接时,它将找到符号链接libfoo.so,但会将SONAME记录为libfoo.so.1。当程序运行时,它将找到另一个符号链接并加载库。

This trick is used so that you can install an ABI compatible, improved libfoo.so.1.3 and an ABI incompatible newer libfoo.so.2.1, and old program will load the old library while new compilations will use the new library.

使用此技巧,以便您可以安装ABI兼容,改进的libfoo.so.1.3和ABI不兼容的新libfoo.so.2.1,旧程序将加载旧库,而新编译将使用新库。

Also note that the environment variables LD_PRELOAD, LD_LIBRARY_PATH and others affect the runtime behaviour. For more details, you can read man ld.so

另请注意,环境变量LD_PRELOAD,LD_LIBRARY_PATH等会影响运行时行为。有关更多详细信息,请阅读man ld.so