11 September 2013

一个VS2008的链接错误

前两天在熟悉和调试一个第三方库的时候,出现了一个关于静态库的链接错误。

    ......
    Linking Executable - ...
    fatal error C1900:?IL mismatch between 'P1' version '20060201' and 'P2' version '20050411'
    ......

第一次见到哦~,上网一顿狂查。好吧。。在另一篇帖子里面见到了比较完整的描述 - 原帖地址

究其原因是因为在编译静态库的时候加入了/GL的选项。 那么这个选项又是干啥的?好吧。。引用MSDN的解释 -/GL

全程序优化允许编译器用有关程序中所有模块的信息执行优化。 如果不执行全程序优化,则基于每个模块 (compiland) 执行优化。

默认情况下,权全程序优化是关闭的,因此必须显式地启用它。 但是,也可以用 /GL- 显式地禁用它。

使用有关所有模块的信息,编译器能够:

    跨越函数边界优化寄存器的使用。

    更好地跟踪对全局数据的修改,允许减少加载和存储的数目。

    更好地跟踪可能由取消指针引用所修改的项组,减少加载和存储的数目。

在模块中内联某个函数,即使该函数在另一个模块中定义。

用 /GL 生成的 .obj 文件将不可用于 EDITBIN 和 DUMPBIN 等链接器实用工具。

如果用 /GL 和 /c 编译程序,应使用 /LTCG 链接器选项创建输出文件。

/ZI 无法与 /GL 一起使用。

以后的 Visual C++ 版本可能无法读取用当前版本中的 /GL 生成的文件格式。 不应提供由用 /GL 生成的 .obj 文件组成的 .lib 文件,除非您永远愿意为希望用户使用的所有 Visual C++ 版本提供 .lib 文件的副本。

用 /GL 生成的 .obj 文件和预编译的头文件不应该用于生成 .lib 文件,除非将在生成 /GL .obj 文件的同一计算机上链接此 .lib 文件。 链接时需要 .obj 文件的预编译头文件中的信息。

有关可用优化和全程序优化的限制的更多信息,请参见 /LTCG。 /GL 还使得按配置优化可用,请参见 /LTCG。 按配置优化进行编译时,如果希望函数按配置优化排序,则必须使用 /Gy 或隐含使用 /Gy 的编译器选项进行编译。

在 Visual Studio 开发环境中设置此链接器选项

有关如何在开发环境中指定 /GL 的信息,请参见 /LTCG(链接时代码生成)。

以编程方式设置此链接器选项

请参见 WholeProgramOptimization。

这里罗列的/GL的编译选项可以带来的好处,都是和在编译期无法看到其他链接所需的单元有关的。这里的对跨越函数边界的优化寄存器的使用应该是值对于外部引用了编译单元内部大函数的情况。

那么添加了这个选项以后,又由于编译器版本不同,对于IL的解释和规则是不同的。从而造成了这个问题,没办法啦。碰到这种问题要么同步编译器,要么使用机器码版本的静态库,也就是去掉/GL选项。