作为背景,我是一个开源项目的开发人员,一个名为openframeworks的c ++库,它是不同库的包装器,如opengl,quicktime,freeImage等。在下一个版本中,我们'我添加了一个名为POCO的c ++库,它在某些方面类似于boost,因为它是java基础库类型功能的替代品。
我刚才注意到,在最新版本中我将POCO库添加为静态链接库,在编译过程中生成的.obj文件非常庞大 - 例如,几个.obj真正小的.cpp文件的文件各为2mb。整个编译的.obj文件大约是12mb左右。另一方面,生产的exes很小 - 300k到1mb。
相比之下,在code :: blocks中编译的同一个库会产生.exe文件,这些文件在exe上的大小大致相同 - 它们都相当小。
是否有链接发生的事情,以及我不理解的Visual Studio中的.obj进程?例如,它是否正在进行某种智能预链接或其他事情,这会增加.obj的大小?我已经尝试了一些设置,例如增量链接等,没有看到任何变化。
提前感谢任何尝试或见解的想法!
-zach
注意:非常感谢!我刚试过,dumpbin,它说“匿名对象”并没有返回有关该对象的信息。 this可能就是为什么......
注意2,在检查上面的链接后,删除LTCG(链接时间代码生成 - / GL).obj文件要小得多,而dumpbin可以理解它们。再次感谢!!
答案 0 :(得分:1)
我不是任何想象力的Visual Studio专家,几乎没有使用它,但我相信Visual Studio采用链接时优化,这可以使得到的代码运行得更快,但是可能会花费大量的空间。库。此外,它可能(我不知道内部)在实际链接阶段之前不会剥离调试信息。
我确信无论如何都会有人提供更好/更详细的答案。
答案 1 :(得分:1)
可能不同之处在于调试信息。
编译器将调试信息输出到.obj中,但链接器不会将该数据放入.exe或.dll中。它被丢弃或放入.pdb。
在任何情况下,都可以在.obj文件上使用Visual Studio DUMPBIN实用程序来查看其中的内容。
答案 2 :(得分:1)
目标文件需要包含足够的链接信息。在C ++中,这是基于名称的。如果两个目标文件使用相同的名称,则它们引用相同的对象(数据/函数/类)。这意味着所有目标文件必须包含可能由其他目标文件引用的所有对象的名称。但是,可执行文件需要从库外部可见的名称。如果是DLL,这意味着只导出名称。保存是双重的:名称较少,并且这些名称在DLL中只出现一次。
现代C ++库将使用名称空间。这些名称空间意味着对象名称变得更长,因为它们也包括封装名称空间的名称。
答案 3 :(得分:0)
编译后的库obj文件非常庞大,因为它们必须包含最终用户最终可能使用的所有函数,类和模板。
链接到您的库的可执行文件将更小,因为它们将仅包含它们运行所需的已编译代码。这通常是图书馆的一小部分。