gpt4 book ai didi

c++ - 如何将标准库静态链接到我的 C++ 程序?

转载 作者:可可西里 更新时间:2023-11-01 17:00:49 25 4
gpt4 key购买 nike

我正在使用带有 GNU GCC 编译器的 Code::Blocks IDE(v13.12)。

  • 我想让链接器为我的程序链接所需运行时库的静态版本,我该怎么做?
  • 我已经知道我的可执行文件大小会增加,你能告诉我其他的缺点吗?
  • 在 Visual C++ Express 中这样做怎么样?
  • 最佳答案

    由于还没有其他人提出答案,我会尝试一下。不幸的是,我不知道 Code::Blocks IDE,所以我的回答只是部分的。

    1 如何使用 GCC 创建静态链接的可执行文件

    这不是特定于 IDE 的,但通常适用于 GCC(和许多其他编译器)。假设您在 main.cpp 中有一个简单的“hello, world”程序。 (除标准库和运行时库外,没有外部依赖项)。您可以通过以下方式编译并静态链接它:

  • 编译main.cppmain.o (输出文件名是隐式的):

    $ g++ -c -Wall main.cpp
    -c告诉 GCC 在编译步骤后停止(不运行链接器)。 -Wall打开大多数诊断消息。如果新手程序员多用多一些,多关注一下,本站的很多问题就不会被问到了。 ;-)
  • 友情链接 main.o (可以列出多个目标文件)静态拉入标准库和运行时库并将可执行文件放入文件 main :

    $ g++ -o main main.o -static

    不使用 -o main切换,GCC 会将最终的可执行文件放在名称不太好的文件中 a.out (曾经最终代表“组装输出”)。

  • 尤其是在开始时,我强烈建议“手动”做这样的事情,因为这将有助于更好地理解构建工具链。

    事实上,上述两个命令可以合并为一个:

    $ g++ -Wall -o main main.cpp -static

    任何合理的 IDE 都应该有用于指定此类编译器/链接器标志的选项。

    2 静态链接的优缺点

    原因 静态链接:
  • 您有一个文件,可以将其复制到任何具有兼容架构和操作系统的机器上,并且无论安装什么版本的库,它都可以正常工作。
  • 您可以在共享库不可用的环境中执行程序。例如,将静态链接的 CGI 可执行文件放入 chroot() jail 可能有助于减少 Web 服务器上的攻击面。
  • 由于不需要动态链接,程序启动可能会更快。 (我确信在某些情况下,情况正好相反,尤其是在共享库已经为另一个进程加载的情况下。)
  • 由于链接器可以对函数地址进行硬编码,因此函数调用可能会更快。
  • 在安装了多个版本的公共(public)库(例如 LAPACK)的系统上,静态链接可以帮助确保始终使用特定版本,而无需担心设置 LD_LIBRARY_PATH正确。显然,这也是一个缺点,因为现在您不能在不重新编译的情况下再选择库。如果您总是想要相同的版本,为什么一开始要安装多个?

  • 原因 反对 静态链接:
  • 正如您已经提到的,可执行文件的大小可能会急剧增加。这当然在很大程度上取决于您链接的库。
  • 如果多个进程同时需要共享库,操作系统可能足够聪明,只将共享库的文本部分加载到 RAM 中一次。通过静态链接,您会失去这种优势,并且系统可能会更快地耗尽内存。
  • 您的程序不再从库升级中获利。系统管理员不是简单地用(希望 ABI 兼容的)更新版本替换一个共享库,而是必须重新编译并重新安装使用它的每个程序。这是我认为最严重的缺点。

    例如考虑 OpenSSL 库。当 Heartbleed 漏洞在今年早些时候被发现并修复时,系统管理员可以安装 OpenSSL 的补丁版本并在补丁发布后的一天内重新启动所有服务以修复漏洞。也就是说,如果他们的服务针对 OpenSSL 动态链接。对于那些静态链接的软件,最后一个修复需要数周时间,而且我很确定仍然有专有的“一体机”软件在使用中,直到现在还没有修复日。
  • 您的用户无法即时替换共享库。例如,torsocks脚本(和相关库)允许用户替换(通过设置 LD_PRELOAD 适本地)网络系统库通过 Tor 网络路由他们的流量。这甚至适用于开发人员从未想过这种可能性的程序。 (这是否安全以及一个好主意是否是一个不相关的争论的主题。)另一个常见的用例是通过替换 malloc 来调试或“强化”应用程序。以及类似的专门版本。

  • 在我看来,除了非常特殊的情况外,静态链接的缺点在所有情况下都超过了优点。根据经验: 如果可以,则动态链接,如果必须,则静态链接。

    附录

    Alf已经指出(见评论),有一个特殊的 GCC 选项可以有选择地静态链接 C++ 标准库,而不是静态链接整个程序。来自 GCC manual :

    -static-libstdc++

    When the g++ program is used to link a C++ program, it normally automatically links against libstdc++. If libstdc++ is available as a shared library, and the -static option is not used, then this links against the shared version of libstdc++. That is normally fine. However, it is sometimes useful to freeze the version of libstdc++ used by the program without going all the way to a fully static link. The -static-libstdc++ option directs the g++ driver to link libstdc++ statically, without necessarily linking other libraries statically.

    关于c++ - 如何将标准库静态链接到我的 C++ 程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26103966/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com