Linker fatal error: LNK1102: out of memory

现象

在持续集成流水线中用msbuild编译32位的程序偶先报错:Linker fatal error: LNK1102: out of memory。

一般解决方法

谷歌之后找到了微软的官方文章,里面写了产生这个问题的原因和解决方法:https://support.microsoft.com/en-us/help/2891057/linker-fatal-error-lnk1102-out-of-memory
解释:大概意思就是,link的时候申请的堆空间太大了,exe虚拟地址空间都不够了,推荐设置PreferredToolArchitecture=x64来使用64位的编译工具。
但是改了各种地方:
(1)环境变量
(2)$(VCTargetsPath)\Microsoft.Cpp.Default.props里面加上PreferredToolArchitecture属性并设置为x64
(3)在经常出错的vcxproj中加上PreferredToolArchitecture属性并设置为x64。
都不好使,郁闷

我的解决方法

最后发现,在我们的持续集成流水线中我们是这样设置msbuild环境的:

%comspec% /k ““C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat”” x86

查看这个批处理:
Linker fatal error: LNK1102: out of memory
发现了很多不同的工具集架构,他们的区别如下:

  • x86:编译器为x86版本,输出文件为x86。
  • amd64_x86:编译器为amd64版本,输出文件为x86。
  • amd64:编译器为amd64版本,输出文件为amd64。
  • x86_amd64:编译器为x86版本,输出文件为amd64。

结合上面两点,突然意识到vcvarsall.bat批处理后面的参数就决定了我使用哪个工具集,所以就算我再怎么设置PreferredToolArchitecture=x64最后在编译的时候也没用(这种情况应该是对直接用devenv.exe有用)

最后设置vcvarsall.bat后面的参数为amd64_x86就好使了,代表我需要用64位的工具输出x86的制品,防止链接的时候申请空间溢出。