【问题标题】:g++ produces big binaries despite small project尽管项目很小,但 g++ 会产生大的二进制文件
【发布时间】:2010-12-21 15:09:44
【问题描述】:

这可能是一个常见的问题。事实上,我想我几年前就问过了……但我不记得答案了。

问题是:我有一个由 6 个源文件组成的项目。所有这些都不超过 200 行代码。它使用许多 STL 容器、stdlib.h 和 iostream。现在可执行文件的大小约为 800kb.... 我想我不应该静态链接库。如何用 GCC 做到这一点?而在 Eclipse CDT 中呢?

编辑: 当我回应我想要的东西时,我认为这是需要澄清的情况。我想知道的是为什么这么小的程序体积那么大,和静态、共享库有什么关系以及它们的区别。如果这是一个太长的故事,请随时给文档指点。谢谢

【问题讨论】:

  • @kurast 它是 c++ 的 gcc 编译器
  • @gotch4 eclipse CDT 使用与makefile 非常相似的结构;我会在谷歌上搜索如何使用 makefile 动态链接,然后右键单击项目,选择属性,然后查看 C/C++ BuildC/C++ General 以获得相同的选项。
  • 膨胀可能是使用 STL 造成的。

标签: c++ g++ shared-libraries eclipse-cdt


【解决方案1】:

如果你给 g++ 动态库名称,并且不传递 -static 标志,它应该动态链接。

要减小大小,您当然可以strip 二进制文件,并将-Os(优化大小)优化标志传递给g++

【讨论】:

    【解决方案2】:

    使用 -O3 和 -s 标志生成最优化的二进制文件。另请参阅link 了解更多信息。

    如果您正在为 Windows 构建,请考虑使用 Microsoft 编译器。它总是在该平台上生成最小的二进制文件。

    【讨论】:

    • 有任何数据来支持它总是产生最小二进制文件的说法吗?我发现在某些情况下,英特尔编译器在生成的对象大小方面比 MSVC 做得好得多。 (当然,小并不意味着几乎任何意义上的“更好”,因为更好的优化通常会占用更多空间)
    【解决方案3】:

    Eclipse 应该默认动态链接,除非您在 makefile 中的链接器上设置了静态标志。

    回应您的编辑:

    -当您静态链接时,可执行文件包含您链接到的每个库的完整副本。
    - 当您动态链接时,可执行文件仅包含对链接库的引用和挂钩,这是非常少的代码量。

    【讨论】:

    • 我没有...我猜它在文件中包含了我正在使用的整个 STL 容器...
    【解决方案4】:

    可执行文件必须包含的不仅仅是您的代码。

    至少,在程序启动之前,它包含一些启动代码、设置环境并在必要时加载任何外部库。

    如果您已静态链接运行时库,您还可以将其包含在可执行文件中。否则,您只会得到一个小存根,它大到足以将系统调用重定向到外部运行时。

    根据编译器设置,它可能还包括大量调试信息和其他非必要数据。如果启用了优化,那也可能会增加代码大小。

    真正的问题是为什么这很重要? 800KB 仍然可以轻松放入软盘! 其中大部分是一次性成本。这并不意味着如果您编写两倍的代码,它将占用 1600KB。更有可能的是,它需要 810KB 或类似的大小。

    不用担心一次性启动成本。

    【讨论】:

      【解决方案5】:

      要记住的一点是,即使您与 C++ 库动态链接,使用 STL 也会导致在您的可执行文件中包含额外的代码。这是因为 STL 是一堆 模板,在您编写和编译代码之前不会真正编译它们。由于库无法预测您可能在容器中存储的内容,因此库无法包含容器特定用途的代码。算法和 STL 中的所有其他内容也是如此。

      我并不是说这绝对是您的可执行文件比您预期的要大得多的原因。但这可能是一个因素。

      【讨论】:

        【解决方案6】:

        大小通常会导致静态库链接到您的应用程序中。

        您可以通过编译到 RELEASE 版本来减小编译后的二进制文件的大小,并优化二进制文件的大小。

        可执行文件大小的另一个来源是库。你说你不使用外部库,除了 STD,所以我相信你在你的可执行文件中包含了 C 运行时,即静态链接。所以检查动态链接。

        IMO 你不应该真的担心这个,但如果你真的很偏执,请检查:Smallest x86 ELF Hello World

        【讨论】:

          【解决方案7】:

          使用 Visual C++ 6.0 它支持 Windows 95 到 Windows 7。 并且可以编译为 x86 平台,但仅适用于 Windows。 因此,如果您是 Windows 用户,请坚持使用除 GCC 之外的 Windows 编译器,这实际上是 sux。大多数说 Visual C++ 是 sux 的人是因为他们是反微软者。 还记得使用“Visual C++ 6.0”,如果您使用较新的版本,您可能无法在 Windows 95 上运行您的文件。我已经测试了所有这些东西,这就是我说的原因。 GCC 生成最大的二进制文件,但 Visual C++ 没有,英特尔编译器可以使用来节省 30% 以上的空间,但它需要英特尔处理器,除非性能会很糟糕。 您需要记住的另一件事是,当您使用模板时,虽然您会看到小线条 当您编译时,这些函数将被扩展,因此结果是生成更大的二进制文件。 如果您需要较小的二进制文件,我建议您使用 C,因为 C 实际上被广泛使用,但不是 OO 事实上 C 比 C++ 更容易使用 这确实有意义,然后是 C++ 示例

          cout

          第二个说打印字段 %s 表示您键入一个字符串,因此很容易。 :P

          【讨论】:

          • 为什么我只能投反对票一次?它没有回答这个问题,它是漫无边际的,其中的一部分肯定是错误的。噗。
          • 我希望 stackoverflow 有一个“最好的最坏的”页面。
          猜你喜欢
          • 2012-12-04
          • 2023-03-07
          • 2019-05-23
          • 2021-08-24
          • 1970-01-01
          • 2011-10-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多