【问题标题】:Linux: C/C++ standard library static vs dynamic linking [duplicate]Linux:C/C++ 标准库静态与动态链接 [重复]
【发布时间】:2014-03-19 12:41:35
【问题描述】:

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

【问题讨论】:

  • 通过打包来部署您的软件(例如,Debian 或 Ubuntu 的 .deb 软件包)。
  • @BasileStarynkevitch 静态链接它比为每个发行版打包更容易。

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


【解决方案1】:

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

【讨论】:

  • 由于这个确切原因,您的可执行文件无法在其他发行版上运行。
  • @MaximYegorushkin:它可能适用于提供相同包管理系统的发行版。
  • Linux 上的理想方式是无论如何都提供源代码。
  • 告诉 Steam :)
【解决方案2】:

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

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

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

【讨论】:

  • 让我补充一点,共享库也可以使用 dl 库(与 -ldl 链接)以编程方式加载。因此,很容易首先在程序中检查一些所需的库版本是否可用,然后加载这个库,或者向用户显示通知,准确地告诉他缺少什么,以便他可以弹出他的包管理器并安装该库。
  • 确实如此,但独立分发的二进制文件可能会与包管理器中可能不再可用的旧版本库链接。
【解决方案3】:

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

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

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

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

【讨论】:

  • 我明白了,但是使用静态链接智能链接器,包括 MSVC++ 和 GCC 提供的链接器,只会链接真正需要的目标文件,因此如果使用 all OpenCV的函数,否则会小很多。
  • @Vitaliy 我刚刚注意到了这一点。请看下面我的回答。在撰写答案时,我是社区的新手,所以没有足够的积分来发表评论,所以我回复了你一个答案。
【解决方案4】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-06
    • 1970-01-01
    • 2017-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多