如何才能将我的大型程序链接起来?

时间:2010-07-22 10:31:51

标签: c++ visual-studio-2005 linker

我们的下一个产品已经变得太大,无法在运行32位Windows的计算机上进行链接。所有lib文件的总和超过2Gb,只能在64位Windows机器上链接。最终我们将超越这个边界,因为我们的软件往往增长而不是收缩,我们使用的是32位链接器(MS Visual Studio 2005):当我们的lib总数超过3Gb时,我们预计会遇到麻烦。

如何在不修剪代码的情况下减小.lib文件或.obj文件的大小?例如,我们使用了很多模板:有没有办法减少它们的占用空间?有没有办法找出导致膨胀检查.lib / .obj文件的原因?这可以自动化而不是通过眼睛检查吗? 2.5Gb是很多可以通过比较的文本。

外部约束阻止我们将其作为单个.exe以外的任何内容发布,因此DLL解决方案不可用。

9 个答案:

答案 0 :(得分:5)

我曾经参与过一个有几个MLoC的项目。虽然我们仍然会在32位机器上链接,但链接时间非常糟糕并且成为一个主要问题,因为开发人员只能在每个工作日完成十几个编辑 - 编译 - 测试周期。 (通过分布式编译很好地处理了编译时间。)

我们切换到动态链接。这增加了启动时间,但这可以通过延迟加载DLL来管理。

答案 1 :(得分:5)

首先,当然,请确保使用'Optimize for Size'选项进行编译。 如果你这样做,我不希望至少内联对代码大小做出重大贡献。编译器对每个内联候选者进行权衡,以确定与增加代码大小相比有多少(如果有的话)增加代码大小。如果你正在优化大小,编译器不会冒很大的代价。 (请注意,内联非常小的函数实际上可以减少代码大小)

其次,您考虑过unity builds了吗?这几乎完全消除了链接器,并且只有一个转换单元,重复工作要少得多,希望内存占用更小。

最后,我知道Visual Studio(或可能是Windows SDK)有一个64位编译器(也就是说,编译器本身就是一个64位应用程序,而不仅仅是一个生成64位代码的编译器)。考虑使用它。 (我不知道是否还有一个64位链接器)

我不知道链接器是在LARGEADDRESSAWARE标志设置的情况下构建的。如果是这样,在64位计算机上运行它将使进程消耗完整的4GB内存,而不是通常获得的2 GB内存。 (如果需要,您可以通过修改PE头来自己添加标志)

也许限制各种符号的联系也有帮助。如果您知道当前转换单元之外不需要符号,请将其放在匿名命名空间中。这可能允许编译器在将所有内容传递给链接器

之前减少未使用的符号

答案 2 :(得分:3)

尝试使用Symbol Sort程序向您显示代码中膨胀的主要位置。另外,只需查看原始.obj文件的大小,就可以合理地了解目标的位置。

答案 3 :(得分:2)

OMFG !!!!!那是huuuuuge!

除了我认为它太大而不合理之外......你不能使用动态链接来避免在编译时链接所有混乱,只在运行时链接什么是必要的(我的意思是,需要加载dll) ?

答案 4 :(得分:2)

是否需要成为一款大应用?

一种选择是将各种模块拆分成DLL并根据需要加载/卸载它们。

或者,您可以使用映射内存拆分多个应用程序并共享数据,管理DBMS甚至是简单的数据文件。

答案 5 :(得分:2)

首先,了解如何测量各种功能使用的大小。不要继续尝试使用替换模板或其他东西,因为你怀疑它会产生重大影响。

运行

dumpbin /HEADERS <somebinary>

找出二进制文件中哪些部分导致巨大的尺寸。你有一个庞大的调试目录部分吗?然后剥离符号。导入地址表大吗?检查表并找到您不需要的符号(模板的问题是模板实例化的符号往往非常大)。可以对异常目录,COM描述符目录等进行类似的分析。

答案 6 :(得分:0)

我认为没有任何一种工具可以为您提供您想要/需要的统计数据。使用带有dumpbin参数的.map文件或/SYMBOLS实用程序以及对创建日志的一些后处理可能会帮助您获得所需内容。

如果统计数据证实您怀疑模板膨胀,或者甚至没有确认,那么对源代码做几件事可能是个好主意:

  1. 尝试使用显式实例化并将模板定义移动到.cpp文件中。当然,只有当您使用有限且众所周知的一组类型/值作为模板的参数时,这才有效。
  2. 添加更多抽象和/或间接。因素代码不依赖于您的模板参数到他们自己的基类或自由函数中。如果您有多个模板类型参数,请查看是否无法将单个类模板拆分为多个基类而不重叠模板参数。 (见http://www2.research.att.com/~bs/SCARY.pdf。)
  3. 尝试使用pimpl成语;如果可以,请避免在头文件中实例化模板,仅在.cpp文件中实例化它们。
  4. 模板很好但有时普通的课程也可以;例如如果可以将它们作为参数传递给ctor,则避免将整数常量作为非类型模板参数传递。

答案 7 :(得分:0)

@hatcat和@jalf:确实有full set of 64bit tools。例如,您可以设置环境变量:

set PreferredToolArchitecture=x64

然后运行Visual Studio(来自de developer console)。

答案 8 :(得分:-1)

我非常怀疑你的实际代码是2GB;你很可能正在编译大量的信息。考虑将一些信息卸载到资源文件中,并将其作为单独步骤嵌入可执行文件中。

相关问题