Visual Studio 使用 C++ 時混亂的版本編號

| | 0 Comments| 10:22
Categories:

這篇算是稍微來抱怨一下,在使用微軟的 Visual Studio 開發 C++ 專案的時候,可能會碰到、混亂的版本編號的狀況。

會有這個問題,主要是因為 Visual Studio 除了本身的整合開發環境(IDE)的版本編號之外,針對 Visual C++ 那邊也還有其他的版本編號方法,所以其實有的時候很容易造成混淆、讓開發者搞不清楚…

基本上,在使用 Visual Studio 開發 C++ 程式的時候,可能會看到的版本編號,主要會有下面幾種:

  • Visual Studio 的版本編號(17.10.2)
  • C++ 編譯器版本(19.40.33811)
  • Visual C++ Toolset 版本(14.40.33807)
  • MSVC Platform Toolset/建置工具(143)

單就理論來說,在開發 C++ 專案的時候,應該主要會去參考 C++ 標準版本(可以使用 __cplusplus 這個巨集),而不需要去管開發環境是使用什麼版本。

但是對於很多跨平台的專案來說,往往還是得去考慮到不同建置環境的支援,所以通常在建置的時候會有許多建置環境的偵測方法(例如 CMake),這時候就可能會去偵測 Visual Studio 的各種版本編號;而在這邊如果沒有寫得夠彈性的話,其實就很有可能會在改版的時候出問題。

而這篇,Heresy 則是來記錄一下,個人對於上述四種版本編號的認知。

Visual Studio 的版本編號(17.10.2)

首先,Visual Studio 現在應該算是每幾年會推出一個大版本,後面會加上推出的年份;例如 Visual Studio 2017Visual Studio 2019Visual Studio 2022 這樣子,目前大致上是以兩年為改版的週期,但是 2022 活得似乎比預期的久?

而不同的大版本,則會有不同的主版號,像是 Visual Studio 2019 就是 16、Visual Studio 2022 則是 17 這樣子(這部分可以參考維基百科);由於算是版本大改,所以有的時候對於既有專案會有相當程度的衝擊,不見得能直接升級到新版本。

在次版號的部分,微軟現在大致上是三個月會有一次比較大的更新,這個時候會增版號的數字就會增加;像是 Visual Studio 2022 最近的更新就是今年五月的 17.10;而由於次版號的更新通常會有功能變化、甚至是標準的支援變化,所以有的時候會造成相容性的問題。

之後,第三個小版號則就是針對這個版本進行問題修正,通常不會有新功能、也不會造成相容性問題了。

而以 Visual Studio 2022 來說,目前最新的版本就是 17.10.2。

C++ 編譯器的版本編號(19.40.33811)

雖然現在比較沒有那種感覺了,但是早期的 Visual Studio 某種意義上是很多軟體的集合,包括了 Visual Basic、Visual C++ 這樣子;沒弄錯的話,以前也還可以單獨購買、安裝 Visual C++。

再加上在微軟的 C/C++ 編譯器其實比 Visual C++ 來的更早就在發展了,所以就算是最初的 Visual C++ 1.0,他的 C++ 編譯器(cl.exe)也不是 1.0、而是 8.0。要確認 Visual C++ 編譯器的版本最簡單的方法就是在命令提示字元執行 cl、這樣就可以看到了;以現在 Visual Studio 2022 17.10.2 來說,他提供的 cl.exe 的版本是 19.40.33811。

而如果要在程式中判斷目前的 Visual C++ 版本的話,則可以透過 _MSC_VER 這個預先定義好的巨集來取得比較短的版本(四個數字、1940)、或是透過 _MSC_FULL_VER 這個巨集來取得完整的版本編號(不含小數點、194033811)(官方文件)。

這邊的版本編號的歷史可以參考維基百科。他的進版方法從 Visual Studio 2015 開始和以前隨著 Visual Studio 的主板號進版不同,而是將主版號固定在 19、然後只調整次版號;而次版號的部分則是固定而兩個數字,「之前」都是在 Visual Studio 大改版的時候才會去動十位數,否則都只去調整個位數

如果不看小版本的話,大致上如下:

Visual Studio
Visual Studio 版本
C++ 版本
Visual Studio 2015
14
19.00
Visual Studio 2017
15
19.1x
Visual Studio 2019
16
19.2x
Visual Studio 2022
17
19.3x / 19.4x

也就是以前都可以拿 _MSC_VER 的前三個數字來判斷 Visual Studio 的版本,像是 191 就是 Visual Studio 2017、192 就是 Visual Studio 2019。

但是最近出現的麻煩,就是或許是因為 Visual Studio 2022 活得比預期的久(還是進版的比較快?),所以Visual Studio 2022 17.10 的時候,Visual C++ 的版本也進版到 19.40、打亂了前面講的判斷法則

現在變成 Visual Studio 2022 會有 193x 和 194x 兩種可能,所以如果按照以前的邏輯去判斷的話,就有可能將 Visual Studio 2022 17.10 誤判為下一代的 Visual Studio…一個實際的例子就是 NVIDIA CUDA 12.0 的版本判斷方法(之前的紀錄參考)。

Visual C++ Toolset 版本(14.40.33807)

除了 C++ 編譯器以 19 開頭的版本外,這邊還有另一個 MSVC Toolset 版本(維基百科是寫 runtime library);這部分應該是從 Visual C++ 推出後才開始有的,所以版本編號會比 C++ 編譯器來的小。

在早期這部分的版本編號是對應到 Visual Studio 的版本的,但是從 Visual Studio 2015 開始則是修改了版本的管理方法,變成把主版號固定在 14、並把次版號和 C++ 編譯器的次版號做連結;所以他的版本對應大致上會如下表:

Visual Studio
版本
C++ 版本
MSVC Toolset 版本
Visual Studio 2015
14
19.00
14
Visual Studio 2017
15
19.1x
14.1x
Visual Studio 2019
16
19.2x
14.2x
Visual Studio 2022
17
19.3x / 19.4x
14.3x / 14.4x

它的完整版本編號主要是在安裝的路徑,例如 Heresy 這邊 Visual Studio 2022 17.10 安裝的路徑就是「C:\Program Files\Microsoft Visual
Studio\2022\Enterprise\VC\Tools\MSVC\14.40.33807
」,可以看到版本編號是 14.40.33807。

老實說,個人覺得既然 Visual Studio 2015 開始都調整成和 C++ 的版本編號同步了,次版本編號基本上和 C++ 編譯器的版本編號是相同的,所以某種意義上已經沒有什麼獨立的意義了?那為什麼不乾脆把主板號直接跳到和 C++ 編譯器一樣的 19、讓兩者更同步算了啊…

總之,和 C++ 編譯器版本編號一樣,由於 Visual Studio 2022 17.10 把次版號改成 40 了,所以變成也打亂了某些把 143x 當成 Visual Studio 2022 的版本判斷機制…

像是 Boost C++ Libraries 的建置機制在升級到 17.10 後會變得沒辦法偵測到 Visual Studio 的開發環境(issue),這部分應該也是因為他的版本判斷前提就是把 toolset 版本 14.3 當作 Visual Studio 2022 為前提下去寫的(參考),

MSVC Platform Toolset/建置工具(143)

最後這項,個人不太確定到底算是什麼?他本身似乎沒有比較細的版本,而是根據前面講的、在 17.10 推出之前的 toolset 的編號規則,把 v141 當成 Visual Studio 2017、v142 當成 Visual Studio 2019、v143 當成 Visual Studio 2022。

他會出現在兩個地方,首先是在透過 Visual Studio Installer 安裝的時候,如果仔細去調整要安裝的項目的話,可以看到很多套件是和 C++ 有關、而且有不同版本的。

以「MSVC v14x – VS 2022 C++  x64/x86 建置工具」來說,就可以看到這邊可以針對不同版本做選擇:

 

在更新的時候預設都會安裝「最新」的版本、並把舊版移除;如果為了相容性問題,其實是可以手動回來安裝舊版本的。

這邊可以看到,就算是安裝 Visual Studio 2022,還是可以使用 Visual Studio 2017 / 2019 的建置工具,這時候就是 v141 / v142。

而 Visual Studio 2022 目前看來似乎是打算統一維持 v143,就算是 17.10 已經把 toolset 進版到 14.40,這邊顯示的版本也還是 v143…(所以以這個角度來看,好像也不能怪 Boost 的建置條件寫得有問題了…)

如果在安裝多個版本的狀況下,在 C++ 的專案屬性裡面,就可以做對應的修改。像是如果有 v142、v143 這種比較大的版本變更的話(相當於切換對應的 Visual Studio 版本),在專案屬性的「一般」裡面,就可以選擇對應的「平台工具組」:

而如果是同一個大版本的話,則是在「進階」裡面可以選擇要使用的「MSVC 工具組版本」:

 

這邊也可以看到 Visual C++ Toolset 的完整版本編號。


所以,基本上如果要認真看待 Visual Studio 的 C++ 建置環境版本的話,看來會有四個種版本編號,彼此其實算是「大致上」一一對應的;下面就是以 2022 為主、比較簡單的列表:

Visual Studio
版本
C++
Toolset
建置工具
Visual Studio 2015
14.x
19.00
14.00
140
Visual Studio 2017
15.x.x
19.1x
14.1x
141
Visual Studio 2019
16.x.x
19.2x
14.2x
142
Visual Studio 2022
17.0.x
19.30
14.30
143
17.1.x
19.31
14.31
17.2.x
19.32
14.32
17.3.x
19.33
14.33
17.4.x
19.34
14.34
17.5.x
19.35
14.35
17.6.x
19.36
14.36
17.7.x
19.37
14.37
17.8.x
19.38
14.38
17.9.x
19.39
14.39
17.10.x
19.40
14.40

基本上,Visual Studio 2022 的主板號問題不大,算是好理解。

從 Visual Studio 2015 開始,C++ 編譯器和 Toolset 的主板號就固定是 19/14(到底為什麼不調整成一樣啦),然後次版號的部分兩者則是相同的、都隨著 Visual Studio 的更新來調整。

在 17.10 前,基本上次版號的第一個數字可以對應回 Visual Studio 的版本,所以可以透過 _MSC_VER 的前三個字元來判斷 Visual Studio 的版本,像是 193 就是 Visual Studio 2022。

所以前面提到的,Boost C++ Libraries 和 NVIDIA CUDA 基本上就是透過這類的機制來判斷 Visual Studio 版本的;甚至包括微軟 Visual Studio 自己的建置工具的版本,個人覺得也是連動到 toolset 的版本的前三個字元。

但是在 Visual Studio 2022 17.10 更新後,由於 C++ 編譯器和 C++ Toolset 的次版號從 3x 變成 40 了,所以導致這些判斷機制都出包了…這也導致了這次更新感覺和第三方函式庫、工具可能會有比較多的相容性問題。


會寫這篇的原因,主要是因為除了之前《Visual Studio 2022 17.10 在 C++ 專案的問題》碰到的問題外,最近又碰到想要建置 Boost C++ Libraries 卻碰到 b2 完全抓不到 Visual Studio 的建置環境的問題…

一查下去才發現這個問題可能之後還會在其他函式庫也碰到,所以這邊才想說來稍微仔細研究、紀錄一下了。

感想呢…版本編號規則真的要想好啊! XD


參考:MSVC Toolset Minor Version Number 14.40 in VS 2022 v17.10

Leave a Reply

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *