为啥我的 Visual Studio .obj 文件比输出的 .exe 文件大?

Posted

技术标签:

【中文标题】为啥我的 Visual Studio .obj 文件比输出的 .exe 文件大?【英文标题】:why are my visual studio .obj files are massive in size compared to the output .exe?为什么我的 Visual Studio .obj 文件比输出的 .exe 文件大? 【发布时间】:2008-12-02 03:25:27 【问题描述】:

作为背景,我是一个开源项目的开发人员,一个名为 openframeworks 的 c++ 库,它是不同库的包装器,如 opengl、quicktime、freeImage 等。在下一个版本中,我们添加了一个名为 POCO 的 c++ 库,它在某些方面类似于 boost,因为它是 java 基础库类型功能的替代方案。

我刚刚注意到,在我将 POCO 库添加为静态链接库的最新版本中,编译过程中生成的 .obj 文件非常庞大 - 例如,有几个 .obj非常小的 .cpp 文件的文件大小为每个 2mb。整体编译的 .obj 文件大约 12mb 左右。另一方面,生成的 exe 文件很小 - 300k 到 1mb。

相比之下,在 code::blocks 中编译的同一个库生成的 .obj 文件在 exe 中的大小大致相同 - 它们都相当小。

Visual Studio 中的链接和 .obj 进程是否发生了我不理解的问题?例如,它是否在做某种智能预链接或其他增加 .obj 大小的事情?我已经尝试了一些设置,例如增量链接等,但没有看到任何变化。

提前感谢您提供任何尝试或见解的想法!

-扎克


注意:非常感谢!我刚试过,dumpbin,它说“匿名对象”并且不返回有关该对象的信息。 this 可能是原因......


注意 2,在查看了上面的链接后,删除 LTCG(链接时间代码生成 - /GL)后,.obj 文件要小得多,dumpbin 可以理解它们。再次感谢!!

【问题讨论】:

【参考方案1】:

无论如何我都不是 Visual Studio 专家,几乎没有使用过它,但我相信 Visual Studio 采用了链接时优化,这可以使生成的代码运行得更快,但会占用大量空间图书馆。此外,可能是(我不知道内部情况)调试信息直到实际链接阶段才被剥离。

我相信无论如何都会有人给出更好/更详细的答案。

【讨论】:

【参考方案2】:

可能区别在于调试信息。

编译器将调试信息输出到 .obj 中,但链接器不会将该数据放入 .exe 或 .dll 中。它要么被丢弃,要么被放入 .pdb。

在任何情况下,对 .obj 文件使用 Visual Studio DUMPBIN 实用程序来查看其中的内容。

【讨论】:

【参考方案3】:

目标文件需要包含足够的链接信息。在 C++ 中,这是基于名称的。如果两个对象文件使用相同的名称,则它们引用相同的对象(数据/函数/类)。这意味着所有对象文件必须包含可能被其他对象文件引用的所有对象的名称。然而,可执行文件需要从库外部可见的名称。在 DLL 的情况下,这意味着仅导出的名称。节省是双重的:名称更少,并且这些名称在 DLL 中只出现一次。

现代 C++ 库将使用命名空间。这些命名空间意味着对象名称变得更长,因为它们也包含了封装命名空间的名称。

【讨论】:

【参考方案4】:

编译后的库 obj 文件会很大,因为它们必须包含最终用户可能最终使用的所有函数、类和模板。

链接到您的库的可执行文件会更小,因为它们只包含运行所需的编译代码。这通常是库的一小部分。

【讨论】:

谢谢 - 澄清 obj 文件和 exe 是针对同一个项目的 - 即,我没有编译一个库,然后从该库编译一个 exe。我正在将几个 c++ 文件编译成一个 exe,与生成的 exe 相比,MSVC 生成的 obj 文件很大。

以上是关于为啥我的 Visual Studio .obj 文件比输出的 .exe 文件大?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的visual stdio 2010连错误程序也能编译成功。。。。

obj 和 bin 文件夹(由 Visual Studio 创建)用于啥?

为啥 Visual Studio 2012 找不到我的测试?

为啥 Visual Studio 会自动更改我的表单布局?

为啥 Visual Studio 无法解析我的 CSS 类名称?

在 Visual Studio 2017 中使用 3D Wavefront OBJ / STL