Skip to content

Commit 091adfa

Browse files
committed
feat(Vcvars): Add support for VC toolset version selection via -vcvars_ver
Introduce `Vcvars_PLATFORM_TOOLSET_VERSION`, passed to `vcvarsall.bat` using the `-vcvars_ver=...` argument when `Vcvars_FIND_VCVARSALL` is TRUE. By default: - If `CMAKE_VS_PLATFORM_TOOLSET_VERSION` is set, its value (e.g., 14.28.29910) is used directly. - Otherwise, a default value (e.g., 14.3) is derived from `Vcvars_MSVC_VERSION` using a known mapping. Adds `Vcvars_ConvertMsvcVersionToVcToolsetVersion()` and corresponding test coverage for all known MSVC versions.
1 parent ff97035 commit 091adfa

File tree

3 files changed

+143
-1
lines changed

3 files changed

+143
-1
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ jobs:
2727
expected-msvc-version: 1949 # Visual Studio 17 2022
2828
expected-batch-filename: "vcvars64.bat"
2929
expected-wrapper-filename: "vcvars64_wrapper.bat"
30+
expected-platform-toolset-version: "14.3"
3031

3132
name: Tests on ${{ matrix.os }}
3233
steps:
@@ -49,6 +50,7 @@ jobs:
4950
-DEXPECTED_MSVC_VERSION:STRING=${{ matrix.expected-msvc-version }} `
5051
-DEXPECTED_BATCH_FILENAME:STRING=${{ matrix.expected-batch-filename }} `
5152
-DEXPECTED_WRAPPER_FILENAME:STRING=${{ matrix.expected-wrapper-filename }} `
53+
-DEXPECTED_PLATFORM_TOOLSET_VERSION:STRING=${{ matrix.expected-platform-toolset-version }} `
5254
-S src/tests `
5355
-B build
5456

FindVcvars.cmake

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,21 @@ These variables can be used to choose which "vcvars" batch script is looked up.
4040
4141
Default is FALSE.
4242
43+
.. variable:: Vcvars_PLATFORM_TOOLSET_VERSION
44+
45+
The version of the Visual C++ toolset passed to ``vcvarsall.bat``
46+
via the ``-vcvars_ver=`` argument.
47+
48+
If not explicitly set, this variable is initialized as follows:
49+
50+
* If :variable:`CMAKE_VS_PLATFORM_TOOLSET_VERSION` is defined, its full value
51+
(e.g., ``14.28.29910``) is used directly.
52+
* Otherwise, a simplified version (e.g., ``14.3``) is derived from
53+
:variable:`Vcvars_MSVC_VERSION` using a known mapping provided by
54+
:command:`Vcvars_ConvertMsvcVersionToVcToolsetVersion`.
55+
56+
Only used when :variable:`Vcvars_FIND_VCVARSALL` is ``TRUE``.
57+
4358
4459
This will define the following variables:
4560
@@ -109,6 +124,24 @@ This module also defines the following functions
109124
The name of the variable to be set with the Visual Studio version.
110125
111126
127+
.. command:: Vcvars_ConvertMsvcVersionToVcToolsetVersion
128+
129+
Converts an MSVC version number (e.g., ``1931``) to its corresponding
130+
Visual C++ toolset version (e.g., ``14.3``).
131+
132+
The result is suitable for use in the ``-vcvars_ver=`` argument
133+
passed to ``vcvarsall.bat``.
134+
135+
This function currently returns toolset versions with only a single
136+
digit after the decimal point. For more specific control (e.g.,
137+
``14.28.29910``), use :variable:`CMAKE_VS_PLATFORM_TOOLSET_VERSION`
138+
or set :variable:`Vcvars_PLATFORM_TOOLSET_VERSION` explicitly.
139+
140+
::
141+
142+
Vcvars_ConvertMsvcVersionToVcToolsetVersion(<msvc_version> <output_var>)
143+
144+
112145
.. command:: Vcvars_FindFirstValidMsvcVersion
113146
114147
The `Vcvars_FindFirstValidMsvcVersion()` function identifies the first MSVC version from a list of candidates that has an associated and discoverable `vcvars` batch script::
@@ -293,6 +326,40 @@ function(Vcvars_ConvertMsvcVersionToVsVersion msvc_version output_var)
293326
set(${output_var} ${vs_version} PARENT_SCOPE)
294327
endfunction()
295328

329+
function(Vcvars_ConvertMsvcVersionToVcToolsetVersion msvc_version output_var)
330+
if(NOT msvc_version MATCHES ${_Vcvars_MSVC_VERSION_REGEX})
331+
message(FATAL_ERROR "msvc_version is expected to match `${_Vcvars_MSVC_VERSION_REGEX}`")
332+
endif()
333+
if(msvc_version IN_LIST Vcvars_TOOLSET_143_MSVC_VERSIONS) # VS 2022
334+
set(vc_toolset_version "14.3")
335+
elseif(msvc_version IN_LIST Vcvars_TOOLSET_142_MSVC_VERSIONS) # VS 2019
336+
set(vc_toolset_version "14.2")
337+
elseif(msvc_version IN_LIST Vcvars_TOOLSET_141_MSVC_VERSIONS) # VS 2017
338+
set(vc_toolset_version "14.1")
339+
elseif(msvc_version IN_LIST Vcvars_TOOLSET_140_MSVC_VERSIONS) # VS 2015
340+
set(vc_toolset_version "14.0")
341+
elseif(msvc_version IN_LIST Vcvars_TOOLSET_120_MSVC_VERSIONS) # VS 2013
342+
set(vc_toolset_version "12.0")
343+
elseif(msvc_version IN_LIST Vcvars_TOOLSET_110_MSVC_VERSIONS) # VS 2012
344+
set(vc_toolset_version "11.0")
345+
elseif(msvc_version IN_LIST Vcvars_TOOLSET_100_MSVC_VERSIONS) # VS 2010
346+
set(vc_toolset_version "10.0")
347+
elseif(msvc_version IN_LIST Vcvars_TOOLSET_90_MSVC_VERSIONS) # VS 2008
348+
set(vc_toolset_version "9.0")
349+
elseif(msvc_version IN_LIST Vcvars_TOOLSET_80_MSVC_VERSIONS) # VS 2005
350+
set(vc_toolset_version "8.0")
351+
elseif(msvc_version IN_LIST Vcvars_TOOLSET_71_MSVC_VERSIONS) # VS 2003
352+
set(vc_toolset_version "7.1")
353+
elseif(msvc_version IN_LIST Vcvars_TOOLSET_70_MSVC_VERSIONS) # VS 2002
354+
set(vc_toolset_version "7.0")
355+
elseif(msvc_version IN_LIST Vcvars_TOOLSET_60_MSVC_VERSIONS) # VS 6.0
356+
set(vc_toolset_version "6.0")
357+
else()
358+
message(FATAL_ERROR "failed to convert msvc_version [${msvc_version}] to VC toolset version. It is not a known version number.")
359+
endif()
360+
set(${output_var} ${vc_toolset_version} PARENT_SCOPE)
361+
endfunction()
362+
296363
function(Vcvars_GetVisualStudioPaths msvc_version msvc_arch output_var)
297364

298365
if(NOT msvc_version MATCHES ${_Vcvars_MSVC_VERSION_REGEX})
@@ -452,6 +519,22 @@ if(NOT DEFINED Vcvars_MSVC_VERSION)
452519
unset(_msvc_version)
453520
endif()
454521

522+
if(NOT DEFINED Vcvars_PLATFORM_TOOLSET_VERSION)
523+
if(DEFINED CMAKE_VS_PLATFORM_TOOLSET_VERSION)
524+
set(Vcvars_PLATFORM_TOOLSET_VERSION ${CMAKE_VS_PLATFORM_TOOLSET_VERSION})
525+
# Display message only once in config mode
526+
if(NOT DEFINED Vcvars_BATCH_FILE)
527+
_vcvars_message(STATUS "Setting Vcvars_PLATFORM_TOOLSET_VERSION to '${Vcvars_PLATFORM_TOOLSET_VERSION}' as CMAKE_VS_PLATFORM_TOOLSET_VERSION was '${CMAKE_VS_PLATFORM_TOOLSET_VERSION}'")
528+
endif()
529+
elseif(DEFINED Vcvars_MSVC_VERSION)
530+
Vcvars_ConvertMsvcVersionToVcToolsetVersion(${Vcvars_MSVC_VERSION} Vcvars_PLATFORM_TOOLSET_VERSION)
531+
# Display message only once in config mode
532+
if(NOT DEFINED Vcvars_BATCH_FILE)
533+
_vcvars_message(STATUS "Setting Vcvars_PLATFORM_TOOLSET_VERSION to '${Vcvars_PLATFORM_TOOLSET_VERSION}' as Vcvars_MSVC_VERSION was '${Vcvars_MSVC_VERSION}'")
534+
endif()
535+
endif()
536+
endif()
537+
455538
if(NOT DEFINED Vcvars_BATCH_FILE AND DEFINED Vcvars_MSVC_VERSION)
456539
Vcvars_FindFirstValidMsvcVersion(
457540
"${Vcvars_MSVC_ARCH}"
@@ -474,17 +557,21 @@ endif()
474557
if(Vcvars_BATCH_FILE)
475558

476559
set(_vcvarsall_arch )
560+
set(_vcvarsall_vcvars_ver )
477561
if(Vcvars_FIND_VCVARSALL)
478562
if(Vcvars_MSVC_ARCH STREQUAL "64")
479563
set(_vcvarsall_arch "x64")
480564
elseif(Vcvars_MSVC_ARCH STREQUAL "32")
481565
set(_vcvarsall_arch "x86")
482566
endif()
567+
if(DEFINED Vcvars_PLATFORM_TOOLSET_VERSION)
568+
set(_vcvarsall_vcvars_ver "-vcvars_ver=${Vcvars_PLATFORM_TOOLSET_VERSION}")
569+
endif()
483570
endif()
484571
set(_in "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/Vcvars_wrapper.bat.in")
485572
get_filename_component(_basename ${Vcvars_BATCH_FILE} NAME_WE)
486573
set(_out "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/${_basename}_wrapper.bat")
487-
file(WRITE ${_in} "call \"@Vcvars_BATCH_FILE@\" @_vcvarsall_arch@
574+
file(WRITE ${_in} "call \"@Vcvars_BATCH_FILE@\" @_vcvarsall_arch@ @_vcvarsall_vcvars_ver@
488575
%*
489576
")
490577
configure_file(${_in} ${_out} @ONLY)
@@ -507,6 +594,7 @@ find_package_handle_standard_args(Vcvars
507594
Vcvars_LAUNCHER
508595
Vcvars_MSVC_VERSION
509596
Vcvars_MSVC_ARCH
597+
Vcvars_PLATFORM_TOOLSET_VERSION
510598
FAIL_MESSAGE
511599
"Failed to find vcvars scripts for Vcvars_MSVC_VERSION [${Vcvars_MSVC_VERSION}] and Vcvars_MSVC_ARCH [${Vcvars_MSVC_ARCH}]"
512600
)

tests/CMakeLists.txt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ foreach(var_name IN ITEMS
77
EXPECTED_MSVC_VERSION
88
EXPECTED_BATCH_FILENAME
99
EXPECTED_WRAPPER_FILENAME
10+
EXPECTED_PLATFORM_TOOLSET_VERSION
1011
)
1112
if(NOT DEFINED ${var_name})
1213
message(FATAL_ERROR "Variable ${var_name} is not specified using -D${var_name}=<value>")
@@ -34,6 +35,7 @@ set(expected_vars
3435
EXPECTED_MSVC_VERSION
3536
EXPECTED_BATCH_FILENAME
3637
EXPECTED_WRAPPER_FILENAME
38+
EXPECTED_PLATFORM_TOOLSET_VERSION
3739
)
3840
foreach(var_name IN LISTS expected_vars)
3941
if(NOT DEFINED ${var_name})
@@ -54,6 +56,7 @@ foreach(var_suffix IN ITEMS
5456
FIND_VCVARSALL
5557
MSVC_ARCH
5658
MSVC_VERSION
59+
PLATFORM_TOOLSET_VERSION
5760
)
5861
if(DEFINED REQUESTED_${var_suffix} AND NOT FUNCTIONS_ONLY_COMPONENT_REQUESTED)
5962
set(Vcvars_${var_suffix} ${REQUESTED_${var_suffix}})
@@ -128,6 +131,7 @@ endfunction()
128131
set(output_vars
129132
Vcvars_MSVC_ARCH
130133
Vcvars_MSVC_VERSION
134+
Vcvars_PLATFORM_TOOLSET_VERSION
131135
Vcvars_BATCH_FILE
132136
Vcvars_LAUNCHER
133137
)
@@ -141,6 +145,7 @@ message(STATUS "")
141145
check_var_equals("Vcvars_FOUND" "TRUE")
142146

143147
check_function_defined("Vcvars_ConvertMsvcVersionToVsVersion")
148+
check_function_defined("Vcvars_ConvertMsvcVersionToVcToolsetVersion")
144149
check_function_defined("Vcvars_GetVisualStudioPaths")
145150
check_function_defined("Vcvars_FindFirstValidMsvcVersion")
146151

@@ -198,16 +203,43 @@ check_msvc_version_to_vs_version_convert(Vcvars_VS71_MSVC_VERSIONS "7.1")
198203
check_msvc_version_to_vs_version_convert(Vcvars_VS7_MSVC_VERSIONS "7.0")
199204
check_msvc_version_to_vs_version_convert(Vcvars_VS6_MSVC_VERSIONS "6.0")
200205

206+
function(check_msvc_version_to_vc_toolset_version_convert msvc_versions_var expected_vc_toolset_version)
207+
foreach(msvc_version IN LISTS ${msvc_versions_var})
208+
Vcvars_ConvertMsvcVersionToVcToolsetVersion("${msvc_version}" output_var)
209+
if(NOT "${output_var}" STREQUAL "${expected_vc_toolset_version}")
210+
message(FATAL_ERROR "Vcvars_ConvertMsvcVersionToVcToolsetVersion failed for msvc_version [${msvc_version}]
211+
current_value [${output_var}]
212+
expected_value [${expected_vc_toolset_version}]
213+
")
214+
endif()
215+
endforeach()
216+
endfunction()
217+
218+
check_msvc_version_to_vc_toolset_version_convert(Vcvars_VS17_MSVC_VERSIONS "14.3")
219+
check_msvc_version_to_vc_toolset_version_convert(Vcvars_VS16_MSVC_VERSIONS "14.2")
220+
check_msvc_version_to_vc_toolset_version_convert(Vcvars_VS15_MSVC_VERSIONS "14.1")
221+
check_msvc_version_to_vc_toolset_version_convert(Vcvars_VS14_MSVC_VERSIONS "14.0")
222+
check_msvc_version_to_vc_toolset_version_convert(Vcvars_VS12_MSVC_VERSIONS "12.0")
223+
check_msvc_version_to_vc_toolset_version_convert(Vcvars_VS11_MSVC_VERSIONS "11.0")
224+
check_msvc_version_to_vc_toolset_version_convert(Vcvars_VS10_MSVC_VERSIONS "10.0")
225+
check_msvc_version_to_vc_toolset_version_convert(Vcvars_VS9_MSVC_VERSIONS "9.0")
226+
check_msvc_version_to_vc_toolset_version_convert(Vcvars_VS8_MSVC_VERSIONS "8.0")
227+
check_msvc_version_to_vc_toolset_version_convert(Vcvars_VS71_MSVC_VERSIONS "7.1")
228+
check_msvc_version_to_vc_toolset_version_convert(Vcvars_VS7_MSVC_VERSIONS "7.0")
229+
check_msvc_version_to_vc_toolset_version_convert(Vcvars_VS6_MSVC_VERSIONS "6.0")
230+
201231
if(FUNCTIONS_ONLY_COMPONENT_REQUESTED)
202232
check_var_not_defined("Vcvars_FIND_VCVARSALL")
203233
check_var_not_defined("Vcvars_MSVC_ARCH")
204234
check_var_not_defined("Vcvars_MSVC_VERSION")
235+
check_var_not_defined("Vcvars_PLATFORM_TOOLSET_VERSION")
205236
check_var_not_defined("Vcvars_LAUNCHER")
206237
check_var_not_defined("Vcvars_LAUNCHER")
207238
else()
208239
check_var_equals("Vcvars_FIND_VCVARSALL" "${EXPECTED_FIND_VCVARSALL}")
209240
check_var_equals("Vcvars_MSVC_ARCH" "${EXPECTED_MSVC_ARCH}")
210241
check_var_equals("Vcvars_MSVC_VERSION" "${EXPECTED_MSVC_VERSION}")
242+
check_var_equals("Vcvars_PLATFORM_TOOLSET_VERSION" "${EXPECTED_PLATFORM_TOOLSET_VERSION}")
211243

212244
check_file_exists("Vcvars_BATCH_FILE")
213245
check_filename_matches("Vcvars_BATCH_FILE" "${EXPECTED_BATCH_FILENAME}")
@@ -292,6 +324,7 @@ add_find_vcvars_test(
292324
-DEXPECTED_BATCH_FILENAME:STRING=${EXPECTED_BATCH_FILENAME}
293325
-DEXPECTED_WRAPPER_FILENAME:STRING=${EXPECTED_WRAPPER_FILENAME}
294326
-DEXPECTED_FIND_VCVARSALL:BOOL=FALSE
327+
-DEXPECTED_PLATFORM_TOOLSET_VERSION:BOOL=${EXPECTED_PLATFORM_TOOLSET_VERSION}
295328
)
296329

297330
add_find_vcvars_test(
@@ -305,6 +338,7 @@ add_find_vcvars_test(
305338
-DEXPECTED_BATCH_FILENAME:STRING=vcvars64.bat
306339
-DEXPECTED_WRAPPER_FILENAME:STRING=vcvars64_wrapper.bat
307340
-DEXPECTED_FIND_VCVARSALL:BOOL=FALSE
341+
-DEXPECTED_PLATFORM_TOOLSET_VERSION:BOOL=${EXPECTED_PLATFORM_TOOLSET_VERSION}
308342
)
309343

310344
add_find_vcvars_test(
@@ -318,6 +352,7 @@ add_find_vcvars_test(
318352
-DEXPECTED_BATCH_FILENAME:STRING=vcvars32.bat
319353
-DEXPECTED_WRAPPER_FILENAME:STRING=vcvars32_wrapper.bat
320354
-DEXPECTED_FIND_VCVARSALL:BOOL=FALSE
355+
-DEXPECTED_PLATFORM_TOOLSET_VERSION:BOOL=${EXPECTED_PLATFORM_TOOLSET_VERSION}
321356
)
322357

323358
add_find_vcvars_test(
@@ -331,6 +366,7 @@ add_find_vcvars_test(
331366
-DEXPECTED_BATCH_FILENAME:STRING=${EXPECTED_BATCH_FILENAME}
332367
-DEXPECTED_WRAPPER_FILENAME:STRING=${EXPECTED_WRAPPER_FILENAME}
333368
-DEXPECTED_FIND_VCVARSALL:BOOL=FALSE
369+
-DEXPECTED_PLATFORM_TOOLSET_VERSION:BOOL=${EXPECTED_PLATFORM_TOOLSET_VERSION}
334370
)
335371

336372
add_find_vcvars_test(
@@ -344,6 +380,7 @@ add_find_vcvars_test(
344380
-DEXPECTED_BATCH_FILENAME:STRING=vcvarsall.bat
345381
-DEXPECTED_WRAPPER_FILENAME:STRING=vcvarsall_wrapper.bat
346382
-DEXPECTED_FIND_VCVARSALL:BOOL=ON
383+
-DEXPECTED_PLATFORM_TOOLSET_VERSION:BOOL=${EXPECTED_PLATFORM_TOOLSET_VERSION}
347384
)
348385

349386
add_find_vcvars_test(
@@ -357,5 +394,20 @@ add_find_vcvars_test(
357394
-DEXPECTED_BATCH_FILENAME:STRING=${EXPECTED_BATCH_FILENAME}
358395
-DEXPECTED_WRAPPER_FILENAME:STRING=${EXPECTED_WRAPPER_FILENAME}
359396
-DEXPECTED_FIND_VCVARSALL:BOOL=OFF
397+
-DEXPECTED_PLATFORM_TOOLSET_VERSION:BOOL=${EXPECTED_PLATFORM_TOOLSET_VERSION}
360398
)
361399

400+
add_find_vcvars_test(
401+
NAME "set-toolset"
402+
OPTIONS
403+
# Requested
404+
-DREQUESTED_FIND_VCVARSALL:BOOL=ON
405+
-DREQUESTED_PLATFORM_TOOLSET_VERSION:STRING=14.2
406+
# Expected
407+
-DEXPECTED_MSVC_ARCH:STRING=${EXPECTED_MSVC_ARCH}
408+
-DEXPECTED_MSVC_VERSION:STRING=${EXPECTED_MSVC_VERSION}
409+
-DEXPECTED_BATCH_FILENAME:STRING=vcvarsall.bat
410+
-DEXPECTED_WRAPPER_FILENAME:STRING=vcvarsall_wrapper.bat
411+
-DEXPECTED_FIND_VCVARSALL:BOOL=ON
412+
-DEXPECTED_PLATFORM_TOOLSET_VERSION:BOOL=14.2
413+
)

0 commit comments

Comments
 (0)