vs增量链接、清单文件

/INCREMENTAL(增量链接)

 


/INCREMENTAL[:NO]
默认情况下,链接器以增量模式运行。若要重写默认增量链接,请指定 /INCREMENTAL:NO。

增量链接的程序在功能上等效于非增量链接的程序。不过,因为它是为后面的增量链接而准备的,所以增量链接的可执行 (.exe) 文件或动态链接库 (DLL):

大于非增量链接的程序,因为有代码和数据的填充。(填充允许链接器增加函数和数据的大小而不用重新创建 .exe 文件。)

可以包含跳转 thunk 以处理函数重定位到新地址。


为了确保最终发布版本不包含填充或 thunk,请非增量链接您的程序。

若要增量链接而不管默认值,请指定 /INCREMENTAL。选定该选项后,如果链接器无法增量链接,它就会发出警告,然后非增量链接程序。某些选项和情况重写 /INCREMENTAL。

大多数程序都可以增量链接。然而,某些更改太大,某些选项与增量链接不兼容。如果指定了任何下列选项,则 LINK 执行完全链接:

增量链接未被选定 (/INCREMENTAL:NO)

选定 /OPT:REF

选定 /OPT:ICF

选定 /ORDER

指定 /DEBUG 时暗含 /INCREMENTAL。

另外,如果发生以下任何情况,则 LINK 执行完全链接:

缺少增量状态 (.ilk) 文件。(LINK 将创建新的 .ilk 文件以为后面的增量链接作准备。)

对 .ilk 文件没有写入权限。(LINK 忽略 .ilk 文件并进行非增量链接。)

缺少 .exe 或 .dll 输出文件。

更改 .ilk、.exe 或 .dll 的时间戳。

更改 LINK 选项。大多数 LINK 选项在各生成间更改时导致完全链接。

添加或省略对象 (.obj) 文件。

更改用 /Yu /Z7 选项编译的对象。

打开此项目的“属性页”对话框。有关详细信息,请参见设置 Visual C++ 项目属性 。

单击“链接器”文件夹。

单击“常规”属性页。

修改“启用增量链接”属性。

 

 

否 (/MANIFEST:NO)

在VS 2005中建立Win32工程时(以VS 2005中文版为例),你可能会遇到这样的运行错误:“没有找到MSVCP80D.dll,因此这个应用程序未能启动。重新安装应用程序可能会修复此问题。”(还可能是其它几个类似的文件:MSVCR80D.dll、MSVCM80D.dll)。对于VS2005新手,可能遇到的第一个问题便是此问题。

一直使用VC6进行开发测试,最近准备把平台转移到VS2005(过些天就应该转VS2008了,呵呵)上来。于是,决定先把CppUnit转移到此平台上来。在VS2005中编译CppUnit所遇到的问题不多,虽然没VC6方便。但是在测试编译好的CppUnit库时却遇到了困难:把以前在VC6中写的AES移植过来(其使用了CppUnit进行单元测试),在运行时却遇到了如上错误。刚开始以为可能是CppUnit没有编译好,重新编译CppUnit多次,调整编译参数,但始终有此错误,并且此错误有时出现有时不出现,这更晕了,大量时间就这样浪费了。等我静下来,才觉得可能是VS 2005的原因,于是上网搜索此错误信息,终于找到了问题所在。 VS 2005在生成可执行文件时使用了一种新的技术,该技术生成的可执行文件会伴随生成一个清单文件(manifest file)(.manifest后缀文件)(其本质上是XML文档,你可以用文本编辑器打开看看),并在链接完成后将该清单文件嵌入到exe文件中(默认情况下)。而在FAT32文件系统中,在处理清单文件阶段,当增量链接时不能完成清单文件的更新(默认情况下),于是造成清单文件嵌入失败,从而使该exe文件运行时没有相应的清单文件而运行失败并提示如上错误。 解决方案很多,列举如下:
1. 由于这是在链接动态运行库出现的问题,所以你可以选择代码生成的连接方式为/MTd而非/MDd,不用这些DLL文件从而避免问题的出现。该方法有一个很显然的缺点:适用范围有限,并且也不是我等提倡的解决问题的方式,不推荐该方法。 2. 既然跟FAT32系统有关,那么我们可以选择在NTFS文件系统中开发从而避免该问题,此方法同上,也是采用的回避问题的方式,不为我等提倡。 3. 该方法仍与FAT32有关:在项目的“属性|配置属性|清单工具|常规”中的“使用FAT32解决办法”选择“是”(默认为“否”),重新生成项目即可解决问题。该方法是唯一真正针对问题所在而提出的解决方法,使清单工具可以正确更新。(此方法是官方解决方法,也比较方便,推荐) 4. 既然问题是在更新嵌入的清单文件时发生的,由于FAT32的原因而未能更新嵌入的清单文件,于是我们有如下两种解决方法:
(1)不启用增量链接。在项目的“属性|配置属性|链接器|常规”中的“启用增量链接”选择“否”。此方法阻断了问题产生的源头,其每次生成exe文件时都直接嵌入清单文件,而不是默认的根据时戳而决定是否更新清单文件。
(2)不嵌入清单文件。在项目的“属性|配置属性|清单工具|输入和输出”中的“嵌入清单”选择“否”,从而在生成exe文件时附随生成一个清单文件(默认情况下,其文件名为exe文件的全名加上“.manifest”),避免了嵌入清单文件可能失败的问题。在程序运行时,会用到该清单文件。显然,这种方式使可执行程序产生了更多的外部依赖,不推荐。
另外,还有一个不能称为方法的土办法:每次Build前手动删除*.ilk文件(增量链接文件)(当然可以在项目属性中写入删除命令,使其自动执行),不推荐该土办法。 最后,总结一下: 1. 此问题只在特定条件下才会出现:在FAT32文件系统中编译、默认设置(增量模式、不启用FAT32解决方案、嵌入清单文件)、非第一次生成可执行文件文件(即在增量连接、更新清单文件时)。 2. 解决方案1和4.1方便实用,推荐使用。

 

你可能感兴趣的:(vs,增量链接,清单文件)