背景:今天傻逼逼地想用vs2010来编译一个vs2013的项目,其中这个项目用到了一个库(应该是用2013编译的)
在我浅薄的认知中,以为只是13支持的特性更多,如果没有用到一些2010编译器不支持的特性应该用10也是能跑的,
结果告诉我,我是那么的天真,其中还要跨越一个叫链接器这样的领域(然而我又不太懂这个编译器,只是稍微了解过)
结果就出现了c1900,参考了这个资料后,大概明白了原来还有ltcd这回事。。。
总结一下文章要点,详情请点入去看,这里就不直接帖过来了。
总结:
IL - Intermiate Language,有时也称Intermediate Representations,是编译链接code generation时使用内部语言。
LTCG (Link Time Code Generation)
主要原因:
链接时使用了某些用更新的编译器编译的LTCG的library。
解决方案:两种
1)更新当前使用的编译链接工具,使其与lib匹配。当然,这样编译出来的二进制文件可能会有所改变(优化可能不同),所以可能需要重新测试。
2)使用不带LTCG的library
普通的编译链接过程:
1) 预编译 preprocess
2)前端编译 (c1/c1xx) - 这一步将产生IL
3) 后端编译 (c2) - 这一步将使用IL,并产生真正的二进制码
4)链接 - 这一步将链接所有的obj/lib,合并PE的各个section,resolve symbol等等,然后产生最终的binary
可以注意到一点:C1900是一个编译错误,因为通常IL由编译器的前端产生,后端使用。但是我们是在链接阶段遇到,所以几乎可以肯定使用了LTCG。
LTCG - msdn.microsoft.com/library/CHS/vccore/html/vcgrfLTCGLinktimeCodeGeneration.asp
LTCG (Link Time Code Generation) 或者称WPO (Whole Program Optimization)
-
因为编译时通常只有当前模块的信息,而链接时可以获得整个程序的全貌,所以在链接时生成代码理论上可以获得更高的优化效果。LTCG的实现方式是将第三步
(c2)与第四步链接合并,也就是链接link.exe会调用c2.dll,使用IL,并且产生真正的二进制码。合并后的编译链接过程变为:
1)compile: cl.exe?/GL
2) link: link.exe /LTCG
而且,LTCG允许对单个模块进行优化--也就是说不必对所有的模块使用/GL,链接时只要检测到一个模块(obj/lib)是用/GL编译的,链接就会使用LTCG。
我们之所以会遇到这个错误,就是因为链接时使用的一个lib是使用'20060201' c2.dll /GL
进行的编译,含有只有'20060201'
c2.dll才能解释的IL,然而我们用的build环境是'20050411'版本,link.exe调用的是'20050411'的c2.dll。
具体操作:首先判断使用的lib是否是LTCG库,然后把其编译成非LTCG库即可:
1.检查:
使用link -dump -disasm <yourlib.lib>可以检验是否使用了/GL。普通的lib dump出来会看到汇编代码,而含有IL的lib不会
检验一个文件是否是LTCG lib库的方法:打开命令行,进入到link.exe文件所在的路径,输入命令link -dump -disasm <yourlib.lib>,如下所示
C:Program FilesMicrosoft Visual Studio 10.0VCin>link -dump -disasm E:WorkspaceCloudPubTrunk\__InternalLibsjepglib8c64.lib
如果不是LGCT lib,则输出显示如下汇编代码:
Summary
1C .bss
58BCC .debug$S
12C0 .debug$T
8D0 .drectve
22D4 .pdata
2B20 .rdata
3198F .text
3A58 .xdata
如果是,则输出显示
TYPE:library
亲测命令可用:
2.编译:
编译方法:设置项目-->属性-->配置属性-->常规-->项目默认值-->全程序优化选择“无全程序优化”