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

时间:2014-02-19 09:28:59

标签: c++ c linux shared-libraries static-libraries

可能在任何操作系统上都可以静态或动态地编译C ++ / C标准库。在Windows上我总是喜欢静态构建,因为它有助于避免在特定的Windows版本,版本和服务包等上安装或不安装不同版本库的“dll hell”问题。静态链接使软件更便携,更少依赖于什么最终用户使用了他的操作系统(我甚至看到了最终用户可以在SHIFT+DEL中对某些DLL进行system32的示例,他无法解释原因,或者用户声称我的应用包含病毒,因为它试图从官方微软网站下载动态链接的先决条件...)因此,在我的经验中,静态链接通常比动态链接更好。 但是,我是Linux新手,所以有人可以分享他的经验吗?我的问题是:如果我们忽略了动态的一个允许节省内存的事实,那么在Linux上提供什么样的链接(动态或静态)?硬盘空间,如果我们计划用自动安装程序分发软件(硬盘空间和内存现在足够便宜,所以没有理由牺牲创建真正好的便携式安装程序赢得所需的工作时间几兆字节的RAM或硬盘空间)。动态/静态链接是否存在任何特定于Linux的问题?

4 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:3)

我说答案取决于你如何分发软件。

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

但是,如果您想将软件作为在“任何”系统上运行的Linux二进制文件(例如各种游戏或Matlab等软件)进行分发,您最终会遇到相同的dll(或.so)地狱问题就像在窗户上一样您不知道系统上哪些库的哪个版本。因此,您必须提供自己的.so文件或静态链接。

答案 2 :(得分:2)

看到使用动态链接的重点是减少可执行文件的大小和内存使用量。如果你忽略了那么谈论的话就太少了。

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

  

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

第三,在linux中一切都是动态链接的,除了/bin/ash.static还有它的动态版本/ bin / ash,但这不应该阻止你从linux中的静态链接。 当使用gcc时,链接默认是动态的。我猜你应该使用“-static”标志来静态链接库

答案 3 :(得分:0)

@Vitaliy很好,你提到了这一点。这里需要注意的重要事项是智能链接和共享(或动态)库的创建是互斥的,也就是说,如果你打开智能链接,那么创建共享库已被关闭。

智能链接将代码分解为小代码块并加载它们的依赖项。 因此,如果您多次调用依赖项,则会多次加载它。 这给出了非常好的执行时间,但是编译时间非常长,特别是对于大型单元。所以有一定的权衡。