VisualStudio 目前在 C++ 的部分,可以針對程式,建置出 32 位元(x86)和 64 位元(x64)的程式。
不過實際上,微軟有提供 32 位元以及 64 位元的建置工具、兩者都可以建置出 x86 以及 x64 的程式。也就是說,使用 32 位元的建置工具不但可以建置出 x86 的程式,也可以建置出 x64 的程式;同樣的,64 位元的建置工具,也可以建置出 x86 / x64 的程式。
而微軟目前基本上針對 VisualStudio 的 IDE 圖形介面,基本上都還是僅有 32 位元的版本、並沒有 64 位元的版本。
另外,微軟在透過 IDE 來建置的時候,就算是要建置 x64 的程式,預設也都是會去使用 32 位元的建置工具、來建置 x64 的程式(x86_x64 Cross Tools)。
大部分的情況,其實這樣的建置方法並不會有什麼問題。
但是 Heresy 這邊其實從好一陣子前、某次升級 VisualStudio 後就開始碰過一個奇怪的問題,那就是 Debug 模式下都沒問題,但是 Release 模式,就會出現:
fatal error C1002: 編譯器於第二編譯階段堆積空間不足
這樣的錯誤,而且每次回報的錯誤位置都還不一樣…
而這邊也有根據官方文件(連結)的建議,去拆分檔案,但是好像也沒什麼幫助?所以最後,也只能先擱置了。
前一陣子,微軟推出了新版的 VisualStudio 2019,在玩的時候才發現現在導致這個錯誤的訊息似乎變得更明確了!
LINK : 32 位元連結器 (C:Program Files (x86)Microsoft Visual Studio2019EnterpriseVCToolsMSVC14.16.27023binHostX86x64link.exe) 的堆積空間不足。即將重新啟動與 64 位元連結器的連結 LINK : 無法在 %PATH% 上放置 64 位元連結器,而會繼續使用目前的連結; 請考慮切換為 64 位元連結器
有了這段訊息,這也才確認,應該是需要的記憶體超過 32 位元的連結器所能負擔的範圍造成的。(事後確認,大概要 8GB 左右的記憶體… orz)
附註:後來發現 VisualStudio 2017 不知道什麼時候也有這段了。
而微軟在 VisualStudio 2010 的年代,就有一篇《連結器的嚴重錯誤︰ LNK1102︰ 記憶體不足》,在描述這個問題了。
經過測試,如果透過「Developer Command Prompt」執行
set PreferredToolArchitecture=x64
後,在執行「devenv」來開啟 VisualStudio 的話,的確是可以解決這個問題。
但是,這樣的使用並不方便,所以還是需要去找個方法,來讓 VisualStudio 在開啟的時候,不需要特別的手段。
後來,則是在《How to make Visual Studio use the native amd64 toolchain》這篇,找到了解決的參考。
加入 PreferredToolArchitecture
如果是單一專案要修改的話,比較快的方法,就是直接用純文字檔編輯器開啟對應的 .vcxproj 檔,找到:
<Import Project="$(VCTargetsPath)Microsoft.Cpp.Default.props" />
後,在這一行下面加上:
<PropertyGroup> <PreferredToolArchitecture>x64</PreferredToolArchitecture> </PropertyGroup>
這樣理論上就可以了。
修改專案的 VC++ 路徑
選擇專案後,點選滑鼠右鍵、選「屬性」後,可以叫出專案的屬性頁。
點選左邊的「VC++ 目錄」後,在右邊會列出目前所使用的系統環境路徑。
選擇 x64 平台後,在「可執行檔目錄」中,可以看到應該會有一個「$(VC_ExecutablePath_x64)」,他指向的是使用 32 位元環境來建置 x64 程式的建置工具資料夾(註 1)。
而這邊,把它改成「$(VC_ExecutablePath_x64_x64)」後,就可以讓 VisualStudio 使用 64 位元的環境來建置了。
如果專案多,又希望以後可以快速切換的話,一個可以考慮的方法,就是使用 VisualStudio 的「專案屬性工作表」(Property Sheets、參考)。
「專案屬性工作表」是 VisualStudio 中,用來把多個專案共通的參數抽出來,額外記錄在一個檔案(副檔名一般是 .props)的機制;透過這個機制,可以減少新的專案的重複設定,而在要修改環境的時候,也可以一次針對大量專案做修改,算是相當方便的。
要使用的話,基本上就是要先開啟「屬性管理員」(選單的「檢視」裡),然後在對應的專案中,點選右鍵後選「加入新的專案屬性工作表」;之後把專案的樹狀結構展開後,就可以看到底下有剛新增的專案屬性工作表了。
而這份工作表,之後也可以透過「加入現有屬性工作表」,來讓其他的專案使用。如此一來,以後設定有變動,只要修改這個檔案就可以了~
使用 PreferredToolArchitecture
這邊要做的修改,則是在「使用者巨集」中,加入一個新的巨集,名稱是「PreferredToolArchitecture」,值則是「x64」,另外似乎是要勾選下方的「設定此巨集做為建置環境中的環境變數」。
雖然按照 StackOverflow 上的說法是這樣就可以了,但是 Heresy 這邊測試的結果,似乎是因為處理順序的關係,這樣修改的話這個巨集是沒辦法發揮效用的。
解決方法,是使用純文字編輯器,去修改現有的專案檔(.vcxproj),找到
<Import Project="x64.props" />
後(x64.props 是前面建立出來屬性工作表),把這些(理論上會有多個)都刪除,然後找到
<Import Project="$(VCTargetsPath)Microsoft.Cpp.Default.props" />
把它改成
<Import Project="$(VCTargetsPath)Microsoft.Cpp.Default.props" />
<Import Project="x64.props" />
透過這個方法,理論上是可以運作的。
但是,如果專案多的話,每個專案都得這樣手動修改,其實還是相當地麻煩就是了…
修改專案的 VC++ 路徑
修改起來比較方便的做法,目前看來是透過屬性工作表,來修改 VC++ 的路徑。
這邊的修改方法,是在屬性工作表的「VC++ 目錄」裡面,把「可執行檔目錄」修改為:
$(VC_ExecutablePath_x64_x64);$(ExecutablePath)
這樣的修改方法,基本上就是繼承系統提供的既有路徑資料($(ExecutablePath)),然後在前面多加一個「$(VC_ExecutablePath_x64_x64)」,讓他有更高的優先序。
如此一來,應該就可以只透過屬性工作表來解決了~
不過要注意的是,如果專案同時要建置 x86 和 x64 環境的話,兩者的屬性工作表示要分開的,否則會用錯工作路徑。
附註:
-
以 VisualStudio 2019 企業版來說,建置工具都放在「C:Program Files (x86)Microsoft Visual Studio2019EnterpriseVCToolsMSVC14.20.27508bin」這個目錄下(版本數字可能會變動)。
底下第一層目錄的「Hostx86」代表的是 32 位元的建置環境,「Hostx64」代表的則是 64 位元的建置環境;下一層的「x86」和「x64」則是代表要建置出什麼平台的程式。
VisualStudio 預計「在 32 位元環境下建置出 x64 程式」的路徑就是「Hostx86x64」。 -
要確認是否有修改成功,一個方法是在專案的屬性頁裡面,在「C/C++」的「命令列」中的「其他選項」,加入「/Bv」這個參數。
這樣在編譯的過程,他就會顯示所使用的編譯工具的完整路徑了。