這篇算是稍微來抱怨一下,在使用微軟的 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 2017、Visual Studio 2019、Visual 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
」,可以看到版本編號是 14.40.33807。
Studio\2022\Enterprise\VC\Tools\MSVC\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