我是C++小組的軟件開發測試工程師。正如許多博客文(例如,Felix Huang最近的這篇博客, Andreea Issac 的這篇博客,還有我之前的這篇博客)所介紹的那樣,這一個版本的主要升級之處就是C++ 構建系統(build system)從原先基于VCBuild的構建系統,遷移到基于MSBuild的構建系統,而C + +項目系統也是建立在MSBuild構建系統之上。由此也帶來了一系列的變化。我們的目標是讓用戶盡可能地平穩升級,在升級過程中,你仍可能會遇到一些限制、已知的問題或是在設計上的變化。這篇文章的目的主要也是為了在你升級到Visual Studio 2010的過程中,能給你一些指導,解釋一些問題。
如何升級?
Visual Studio 2010支持來自VC6、Visual Studio 2002、Visual Studio 2003、Visual Studio 2005和Visual Studio 2008的升級。同Visual Studio的早期版本一樣,你可以選擇通過IDE的轉換向導或者是命令行工具(Devenv/upgrade)來完成升級。
以下是升級過程中的一些建議:
1) 把升級環境與構建環境設置成相同的
升級過程中會嘗試加載一些文件,另外還會評估一些值。如果你的項目中所使用的值不是在項目文件中自己定義的,例如在環境變量中定義的值,那就需要在升級之前事先設置好這些環境變量。如果這些環境變量設置不當,則可能會因為無法對值進行評估而出現警告或錯誤。
2) 在升級之前確保你已經安裝了必要的平臺
在一臺沒有可用平臺的機器上對項目進行轉換,可能會導致轉換錯誤。例如,如果你想在Visual Studio Professional SKU中對安騰平臺的一個項目進行轉換,由于它不支持安騰平臺,你就會看到像下面這樣的轉換出錯信息:
Failed to upgrade 'Debug|
這是因為轉換過程需要那些平臺的屬性值才能成功進行。你可以通過查看以下目錄獲悉已安裝了哪些平臺:%ProgramFiles%\MSBuild\Microsoft.cpp\V4.0\Platforms (或者查看x64平臺下的 %ProgramFiles(x86)%\MSBuild\Microsoft.cpp\V4.0\Platforms )。
3) 如果可能的話,使用本地的多定向支持來對Visual Studio 2008工具集進行構建
在Visual Studio 2010中,我們新增了本地的多定向支持(Multi-Targeting),通過使用新的基于MSBuild的項目系統,你可以在Visual Studio 2010的IDE中為Visual Studio 2008工具集構建目標。關于這一特性,你可以看看這篇博客。我們建議用戶,特別是擁有大型代碼庫的用戶,在升級時先利用這一特性在Visual Studio 2010中構建Visual Studio 2008工具集的程序。這樣,當你在升級過程中碰到問題,就可以把那些跟項目系統或構建系統相關的問題與工具的問題區別開來。這將會讓你更加平滑地升級到Visual Studio 2010 工具集。
一旦升級完成,屬性表文件(.Visual Studio props)就會被轉換成新的格式(.props)。同樣,項目文件(.vcproj)也會被轉換為新的格式(.vcxproj)。值得注意的是,新的項目文件會與舊的項目文件同時生成。在轉換過程中還產生了一種新的文件類型(.filter .vcxproj),該過濾器文件包含用來顯示解決方案的資源管理器文件夾信息。該過濾器信息原本是項目文件的一部分,然而這種變化是必要的,因為只要項目文件發生變化,MSBuild就會請求重新構建。通過在一個單獨的文件中保存過濾器信息,就可以在避免重新構建整個項目的情況下修改過濾器。
注意:升級過程不會轉換.user文件。因此,你的調試和部署設置在轉換后將不會被保留。
在Visual Studio 2010中,一個新的命令行升級工具 VCUpgrade.exe也被加入了進來。此命令行工具,適合在只有一個項目的情況下進行升級,因為它無法把解決方案文件作為輸入,并將其解析成項目文件。VCUpgrade.exe位于 $(Visual Studio InstallDir)\ common7 \ Tools目錄下,該工具也將附帶在WinSDK的下一個版本中,這樣用戶就可以在沒有Visual Studio IDE的情況下用命令行對WinSDK中的項目文件進行升級。
升級過程中的警告
以下是轉換過程中,你可能會遇到的一些常見警告:
1) 鏈接器輸出目錄
在升級時你可能會看到的一個警告是MSB8012:$(TargetPath)和鏈接器的OutputFile屬性的值不匹配:
- MSB8012: $(TargetExt) ('.dll') does not match the Linker's OutputFile property value 'C:\foo\Debug\MFCActiveX.ocx' ('.ocx') in project configuration 'Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetExt) property value matches the value specified in %(Link.OutputFile). - MSB8012: $(TargetPath) ('C:\foo\Debug\MFCActiveX.dll') does not match the Linker's OutputFile property value 'C:\foo\Debug\MFCActiveX.ocx' ('C:\foo\Debug\MFCActiveX.ocx') in project configuration 'Debug|Win32'. This may cause your project to build incorrectly. To correct this, please make sure that $(TargetPath) property value matches the value specified in %(Link.OutputFile).
Link.OutputFile是在屬性頁中Linker-> General -> Output File 這一項中定義的值。默認情況下,它的值是$(OutDir)$(TargetName)$(TargetExt),與$(TargetPath)相同。當我們把一個應用程序從之前的版本轉換過來時,并沒有辦法可以很好地解析出Link.OutputFile被$(TargetName)和$(TargetExt)的值,因為不同的用戶可能用不同的方法對其進行了賦值。為了解決這一點,我們決定在轉換過程中保留Linker.OutputFile中的值。在轉換之后,$(TargetName)將默認為$(ProjectName),$(TargetExt)將默認為該類應用程序的默認擴展名:動態庫文件為.dll,靜態庫為.lib,應用程序則為.exe,而Link.OutputFile值則將被保留。如果Link.OutputFile與$(TargetPath)不同,警告MSB8012會被記錄在轉換日志中。在構建應用程序時你也會看到同樣的警告。
$(OutDir),$(TargetName)和$(TargetExt)在“常規”屬性頁中分別對應“Output Directory”,“Target Name”,“Target Extension”。你可以手動更改這些屬性的值,這樣你就不會再看到警告了。
-如果你的項目生成了導入庫(Linker -> Advanced -> Import Library),而且鏈接器的輸出目錄不是默認目錄,那么你可能還需要更改導入庫的輸出文件夾。否則,生成的導入庫所在的目錄就可能會與鏈接器的輸出不同。
-調試。轉換后命令被設為默認的$(TargetPath)。你可能需要做一些改動,這樣當按下F5 (Debugging)或 Ctrl + F5 (Start without debugging)之后才能加載正確的可執行程序。
2) 屬性表的排序
如果你的應用程序有屬性表,那么在轉換過程中你可能會遇到下面的警告中:
- All user macros reported below for configuration 'Debug|Win32' are used before their definition, which can cause undesirable build results; this is not supported in this release. You can resolve this by changing the inclusion order of the consuming property sheets and making sure they come after the property sheets defining the user macros. - MSB4211: C:\foo\PropertySheet\foo.props; The property "MyIncludePath" is being set to a value for the first time, but it was already consumed at "C:\foo\PropertySheet\bar.props".
該警告歸因于MSBuild對其屬性的評估方式:MSBuild按順序依次評估其屬性值。如果在派生的屬性表中定義的屬性在父屬性表中被使用,那么其值就會被設為空。然而,VCBuild采用的是延遲評估方式。這樣,即使是在派生屬性表中定義的屬性也可以在父屬性表中使用。若要解決此問題,請按照警告消息改變屬性表中的順序,從而確保屬性在定義后才被使用。
升級后的行為變化
盡管底層的構建系統已經發生了改變,但我們仍盡力讓用戶在遷移到Visual Studio 2010后有相同的使用體驗。另外,我們還采取了一些措施來改進構建體驗或是迎合MSBuild的某些特定要求。因此,一旦你遷移到Visual Studio 2010,就可能就會注意到以下一些變化。
1) 從“解決方案依賴”到“項目到項目的引用”
如果在一個舊版本Visual Studio版本下進行編譯的C++程序被轉換到Visual Studio 2010后,解決方案級定義的項目依賴關系便會被轉化成項目到項目的引用(project to project references)。這一變化確保了C + +項目依賴關系能夠在項目文件中被捕獲。下面就是一個項目到項目的引用在項目文件中的樣子:
在項目文件中存放依賴關系有幾個優點。首先,用戶可以在不用解決方案的情況下構建一個項目,相關的項目會自動被構建。第二,它為那些擁有巨大的代碼樹又可能不會使用解決方案文件的用戶提供了方便。 此外,許多客戶都有好幾個解決方案文件,每個文件都包含項目的不同子集。通過這種方式就可以讓用戶避免為每個解決方案設置依賴關系。另一個重要因素就是,使用項目到項目的引用使得構建過程更加可靠,尤其是在多核的環境下。這與Visual Studio早期版本的情況也是一致的。
-如果某個C#程序依賴于一個C++程序,并且這一依賴只使用了解決方案依賴關系表示,那么現在的這種轉換并不會把解決方案依賴關系轉換成項目到項目的引用。你可能會碰到因為不正確的構建順序而導致的構建錯誤,尤其是使用命令行直接進行MSBuild構建的時候。要解決該問題,你得為C#和C++程序手動設置項目到項目的引用。
-在Visual Studio 2010中設置新的構建依賴關系時,通常都要用項目到項目的引用替代解決方案依賴。
原文轉自:http://www.anti-gravitydesign.com