【问题标题】:Why linking to a LIB significantly increases binary's size为什么链接到 LIB 会显着增加二进制文件的大小
【发布时间】:2015-11-04 08:45:17
【问题描述】:

假设我有一个模块(DLL / EXE),它定义了具有 N 个对象的特定流程,编译/链接后,模块的大小为 X。

如果我决定将该模块分解为一个主可执行文件和一个辅助 LIB 文件,并准确计算我之前描述的 N 个对象,那么可执行文件的整体大小会保持不变吗?

我知道在链接期间,编译器决定将 LIB 的哪些部分复制到可执行文件中,所以我希望可执行文件的整体大小小于或等于可执行文件。

我已将 LIB 项目定义为优先大小而不是速度和最小大小 (O1)。

为了清楚起见,我决定在 LIB(全局函数)中实现一个小 HelloWorld 函数,并从主可执行文件中删除对 LIB 对象的任何引用,并执行以下命令

#include "../LibObject/Function.h"
void main()
{
     HelloWorld();
}

可执行文件的整体大小一直保持在我调用原始对象时的大小,怎么样?

【问题讨论】:

  • 您是否在问为什么当您将一些东西移入静态库时您的可执行文件没有变小?如果是这样……为什么会这样?为什么链接器能够从库中删除比从普通目标文件中更多的代码?
  • 另外,您的问题标题是“为什么二进制大小会增加”,而实际问题似乎是在问“为什么二进制大小不会变小”。虽然这些不是相互排斥的,但您能澄清一下吗?
  • 现在在 DLL 中的代码必须链接到 EXE。所以当然EXE永远不会变小。最好的希望是 EXE 将小于原始 EXE 和 DLL 的组合大小。
  • @melak47,我会同意你的第二种解释,我认为整体大小最终会减小。如果我使用库中的单个全局函数而不是主对象,它的长度应该减少。

标签: c++ visual-studio static-libraries compiler-optimization static-linking


【解决方案1】:

静态库几乎在所有方面都只是对象模块的集合(将它们视为.zip.obj);无论您是单独传递所有目标文件还是在静态库中一起传递所有目标文件(如果可能,以相同方式执行死函数消除),链接器没有真正的区别,因此您看到相同效果的事实带有或不带有中间库步骤的可执行文件大小完全符合预期。

【讨论】:

    【解决方案2】:

    您正在向前声明该类,但没有定义它,这实际上没有意义。如果它是在头文件中定义的,那么您不需要转发声明它。如果它是您正在创建的类,那么仅仅向前声明它是不够的。您需要定义类。你似乎跨过了栅栏。

        namespace Ramy{
        namespace TEST {
            namespace standard{
                class StandardAnalyzer;
            }
        }
    }
    

    是前向声明。它只是告诉编译器该类存在,它没有告诉编译器有关它的任何信息。编译器需要一个类定义。

    那么,它是在 Ramy 库中定义的类还是您自己创建的类?取决于你的答案。

    这是因为当您将程序与库链接时会增加大小。 该库包含主程序所需的函数、依赖项。

    【讨论】:

    • 我不确定我是否遵循您的回答,链接后前向减速如何影响整体尺寸
    • 我刚刚解释了在哪里使用库和影响大小。我解释了静态链接和共享链接的工作原理以及使用位置。
    【解决方案3】:

    lib 文件总是会增加可执行文件的大小,因为当您调用 .h 文件时,您正在使用您的应用程序执行预处理器。

    【讨论】:

    • 即使实现不在静态库中,您也会包含相同的头文件。
    • 这种解释完全没有意义。半句话,它有以下错误:“运行时的预处理器”、“预处理器计入可执行文件大小”、“.h 文件是可执行文件的一部分”和“.h 文件被调用”。
    猜你喜欢
    • 1970-01-01
    • 2019-02-16
    • 2021-11-24
    • 1970-01-01
    • 1970-01-01
    • 2021-07-03
    • 2010-12-07
    • 1970-01-01
    • 2015-03-14
    相关资源
    最近更新 更多