链接到不进行函数调用的库会产生什么影响?
我有一个程序的 make 文件,该程序使用以下行 -ldl 链接到 libdl.so。没有调用 dlopen 或任何相关函数。即使您不使用任何函数,以这种方式链接到该库会产生什么效果?
I have a make file for a program that links to libdl.so with the following line -ldl. There are no calls to dlopen or any of the related functions. What is the effect of linking to this library in this way even though you do not use any of the functions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您必须阅读链接器的文档。来自我的 Linux/ELF/GNU Binutils 系统上的
info ld
(强调):您可以通过在测试程序上运行
ldd
来检查自己。在一个简单的测试程序中,我得到:但是,如果我与
-ldl
链接,我得到:即使我的程序没有使用
libdl
。但是,如果我使用-Wl,--as-needed
运行 GCC,libdl
将不会被链接。根据我的测试,这仅在- Wl,--as-needed
在命令行中在-ldl
之前列出。有什么影响?这意味着即使您不使用共享库,您的二进制文件也无法在没有共享库的系统上运行。这也意味着如果您升级共享库并卸载旧的共享库,您的二进制文件将会损坏。这不是什么大问题,因为二进制兼容性无论如何都是一个问题,但我认为没有理由不为一般项目打开
-Wl,--as-needed
。You'll have to read the documentation for your linker. From
info ld
on my Linux/ELF/GNU Binutils system (emphasis added):You can check yourself by running
ldd
on a test program. On a simple test program, I get:However, if I link with
-ldl
, I get this:Even though
libdl
isn't used by my program. However, if I run GCC with-Wl,--as-needed
,libdl
will not be linked in. According to my tests, this only works if-Wl,--as-needed
is listed on the command line before-ldl
.What are the effects? It means that your binary won't run on systems without the shared library, even though you don't use it. It also means that your binary will break if you upgrade the shared library and uninstall the old one. It's not a big deal because binary compatibility is a bear anyway, but I see no reason not to turn on
-Wl,--as-needed
for projects in general.我编写了一个小型应用程序,它只使用 STL。它的大小为 8275 字节,无需链接到任何特定库:
现在,当我编译它并将其与 boost_thread 链接时,它会增长到 8290 字节:
请注意,没有我的代码对 boost_thread 的功能进行函数调用。但是,无论如何,boost_thread 都会作为我的应用程序的依赖项添加(正如您在ldd 的输出中看到的那样)。
I have coded a small application which uses nothing but STL. It has 8275 bytes of size without linking to any specific libraries:
Now, when I compile it and link it with boost_thread, it grows to 8290 bytes:
Note that there is no function call on my code to features of boost_thread. However, boost_thread is added anyway as a dependency of my application (as you can see on the output of ldd).
链接到共享库与链接静态库不同。 @Dietrich Epp 已经解释了主要差异,但还有另一个重要细节。共享库定义了函数
void _init()
和void _fini(void)
,它们在加载/卸载共享库时被调用;如果您没有自己定义它们,链接器将添加默认存根。如果您将程序链接到共享库,但不引用库中的任何符号(并且不添加 --as-needed 链接器标志),这些也会被调用。
Linking to a shared library is different than linking a static library. The main differences were explained already by @Dietrich Epp, but there's another important detail. Shared libraries define functions
void _init()
andvoid _fini(void)
which are called upon loading/unloading a shared library; if you don't define them yourself the linker will add default stubs.Those will be called also if you link your program against a shared library, but don't reference any symbol from the library (and don't add --as-needed linker flag).
大多数链接器会简单地从最终的二进制文件中省略未使用的对象,就像您一开始就没有链接到库一样。
Most linkers will simply omit the unused objects from the final binary, exactly as if you hadn't linked with the library in the first place.