Linux:C/C++标准库静态链接与动态链接

Linux: C/C++ standard library static vs dynamic linking

本文关键字:链接 静态 动态 标准 C++ Linux      更新时间:2023-10-16

可能在任何操作系统上都可以静态或动态编译C++标准库。在Windows上,我总是喜欢静态构建,因为它有助于避免在特定的Windows版本、版本和service pack等上安装或未安装不同版本的库时出现"dll地狱"问题。静态链接使软件更具可移植性,减少了对最终用户操作系统的依赖(我甚至看到了最终用户可以在system32中的一些DLL上制作SHIFT+DEL的例子,他无法解释为什么,或者当用户声称我的应用程序包含病毒时,因为它试图从微软官方网站下载动态链接的先决条件…)所以,根据我的经验,在Windows上静态链接通常比动态链接更好。然而,我是Linux的新手,有人能分享他的经验吗?我的问题是:如果我们忽略了动态链接可以节省内存的事实,那么Linux上优先选择哪种链接(动态链接还是静态链接);硬盘空间,如果我们计划使用自动安装程序来分发软件(硬盘空间和内存现在已经足够便宜了,所以没有理由牺牲创建真正好的便携式安装程序所需的工作时间来赢得一些兆字节的RAM或硬盘空间)。动态/静态链接是否存在特定于Linux的问题?

在Linux上,通常有一个包管理器,可以确保只安装一个版本的库。所以通常没有dll地狱,动态链接也没有问题。动态链接是Linux上的标准方式。

我认为答案取决于您如何分发软件。

如果您为特定的Linux发行版和版本打包软件,通常首选动态链接。您知道要在系统上查找哪些库,并且可以指定依赖项。

然而,如果你想将软件分发为在"任何"系统上运行的Linux二进制文件(例如各种游戏或Matlab等软件),你最终会遇到与windows相同的dll(或.so)地狱问题。您不知道系统上有哪些库的哪个版本。因此,您必须静态地提供自己的.so文件或链接。

使用动态链接的全部目的是减少可执行文件的大小和内存使用。如果你忽略了这一点,可谈的就太少了。

另一方面,您提到了节省内存和磁盘空间。节省磁盘空间是必要的,因为当你想导出你的应用程序时,你不能把2Gb的应用程序放在互联网上下载(例如openCV库大约是2.1GB)。解决方案是动态链接它们,只加载那些你需要的模块。这也实现了高效的多任务处理(只创建模块的一个副本,整个程序使用相同的副本)。特别:

例如,媒体播放器应用程序最初可能是附带的使用编解码器支持mp3文件格式。如果媒体播放器是静态链接的,则不会可以动态更新它以支持不同的文件格式,而不需要替换整个应用程序。动态链接意味着包含最新编解码器的共享库,其中包括一些增强功能和错误修复,可以在运行时由动态链接器动态加载到内存中以替换原始共享库。共享库也可以由多个应用程序共享。例如,两个不同的媒体播放器都可以使用包含相同内容的相同共享库编解码器。这可能意味着运行应用程序的设备需要更少物理内存,具体取决于动态链接器的大小。

第三,在linux中,除了/bin/ash.static之外,所有东西都是动态链接的,whic也有其动态版本/bin/ash,但这不应该阻止您在linux中进行静态链接。当使用gcc时,链接在默认情况下是动态的。我想你应该使用"-static"标志来静态链接库

@Vitaliy很高兴你提出了这个问题。这里需要注意的重要一点是,智能链接和共享(或动态)库的创建是互斥的,也就是说,如果启用智能链接,则关闭共享库的创建。

智能链接将代码分解为小代码块,并加载它们的依赖项。因此,如果您多次调用依赖项,就会多次加载它。这提供了非常好的执行时间,但编译时间非常高,尤其是对于大型单元。因此,存在一定的权衡。