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方便實用,推薦使用。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章