当与共享库链接时,将添加到可执行文件中的内容
What is added to an executable when linking with a shared library?
如果我想创建一个与静态库链接的c++程序,那么最终的可执行文件将包含来自我的程序的代码和来自库的代码(我认为…!)但是我不完全确定当我链接到一个共享库时会发生什么。
假设我链接到一个名为libfoo.so
的库,通过在我的CMakeLists.txt
文件中指定target_link_libraries(${PROJECT_NAME} foo)
行。我假设最终的可执行文件将包含关于这个库的一些信息,但不包含完整的代码。其他信息是什么?此外,在用户的系统上,库是否必须完全称为libfoo.so
?
当您链接到动态库时,链接器将在程序的动态部分添加NEEDED
条目。然后,动态加载器将使用这些来定位库,并使用库来求解任何未定义的动态符号。
请注意,未定义的动态符号与期望找到它们的动态库之间没有联系。有时它们在另一个图书馆被发现,有趣的事情就会发生。
存储在NEEDED
表项中的特定名称取决于库在其动态部分中是否有SONAME
表项:
- 如果存在
SONAME
,则其内容将被复制到程序 的 - 如果没有
SONAME
,则存储linkker命令中使用的库的文件名。
NEEDED
中。可以使用以下命令检查库或程序的动态部分的内容:
$ objdump -p program
这在实践中是如何使用的?嗯,大多数(所有?)linux发行版使用以下方案,以及系统库(以libfoo.so
为例):
- 库被安装为
/usr/lib/libfoo.so.1.2
或其他版本。 - 是指向
/usr/lib/libfoo.so.1
和/usr/lib/libfoo.so
库的符号链接。 - 库的
SONAME
为libfoo.so.1
. - 设置路径
/usr/lib
为动态库路径。
这样,当您与-lfoo
链接时,它将找到libfoo.so
符号链接,但将SONAME
记录为libfoo.so.1
。当程序运行时,它会找到另一个符号链接并加载库。
使用这个技巧是为了您可以安装ABI兼容的改进的libfoo.so.1.3
和ABI不兼容的新libfoo.so.2.1
,并且旧程序将加载旧库,而新编译将使用新库。
还要注意环境变量LD_PRELOAD
、LD_LIBRARY_PATH
和其他影响运行时行为的变量。有关详细信息,请参阅man ld.so
- 如何将不同的可执行文件合并到一个窗口框架中进行编码?像浏览器一样
- 如何使 windows 命令提示符在C++可执行文件上显示返回值?
- CMake:如何将库 A 链接到库 B,然后将可执行文件链接到库 A
- 如何使字符串出现在编译的二进制可执行文件的开头?
- CMake 添加和删除宏定义以编译共享库/可执行文件
- 如何将图像文件夹添加到CMake项目以便在c ++可执行文件中使用这些图像?
- 将文件添加到C 可执行文件中
- 如何通过makefile添加CAP_NET_RAW功能到Linux上的C 可执行文件
- 可视化 将 c++ 可执行文件图标添加到预制件 5 构建脚本
- CMake添加(测试)可执行文件
- 使用大多数Java代码制作可执行文件,但可能添加了其他语言
- 将 Icon 添加到可执行文件 (Eclipse CDT Luna) 时出现问题:make: *** 没有规则来制作目标 'resources.o'
- 是否有方法将相对库路径添加到可执行文件以避免设置LD_library_path
- 在已编译的可执行文件的.text部分中增加或指定间隙,以手动添加程序集代码
- 如何添加Linux可执行文件到.gitignore
- 链接和添加可执行文件在CMAKE
- 当与共享库链接时,将添加到可执行文件中的内容
- 如何在没有资源编译器的情况下将自定义窗口的资源添加到可执行文件中?
- 在CMake中添加多个可执行文件
- 使用Eclipse时,如何在c++编译的可执行文件中添加图标?