在 VisualStudio IDE 使用 64 位元 C++ 原生編譯環境


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 Studio\2019\Enterprise\VC\Tools\MSVC\14.16.27023\bin\HostX86\x64\link.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 環境的話,兩者的屬性工作表示要分開的,否則會用錯工作路徑。


附註:

  1. 以 VisualStudio 2019 企業版來說,建置工具都放在「C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.20.27508\bin」這個目錄下(版本數字可能會變動)。
    底下第一層目錄的「Hostx86」代表的是 32 位元的建置環境,「Hostx64」代表的則是 64 位元的建置環境;下一層的「x86」和「x64」則是代表要建置出什麼平台的程式。
    VisualStudio 預計「在 32 位元環境下建置出 x64 程式」的路徑就是「Hostx86\x64」。

  2. 要確認是否有修改成功,一個方法是在專案的屬性頁裡面,在「C/C++」的「命令列」中的「其他選項」,加入「/Bv」這個參數。
    這樣在編譯的過程,他就會顯示所使用的編譯工具的完整路徑了。

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google photo

您的留言將使用 Google 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.