如果我想创建一个与静态库链接的C ++程序,那么最终的可执行文件将包含我程序中的代码和库中的代码(我认为......!)。但是,当我与共享库链接时,我不确定会发生什么。
假设我通过在libfoo.so
文件中指定行CMakeLists.txt
来链接名为target_link_libraries(${PROJECT_NAME} foo)
的库。我假设最终的可执行文件将包含有关此库的一些信息,但不包含完整的代码。这是什么其他信息?此外,是否必须在用户的系统上正确调用库{?1}?
答案 0 :(得分:6)
链接到动态库时,链接器将在程序的动态部分中添加NEEDED
条目。然后动态加载器将使用它们来定位库并使用库来解决任何未定义的动态符号。
请注意,未定义的动态符号与期望找到它们的动态库之间没有任何关联。有时他们会在另一个图书馆找到,有趣的事情可能会发生。
NEEDED
条目中存储的特定名称取决于库的动态部分中是否有SONAME
条目:
SONAME
,则其内容将被复制到程序的NEEDED
SONAME
,将存储链接器命令中使用的库的文件名。您可以使用以下方法检查库或程序的动态部分的内容:
$ 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