summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2021-03-12 13:01:54 (GMT)
committerBrad King <brad.king@kitware.com>2021-03-12 13:36:45 (GMT)
commit30c835428fffbf91191ebb1150d7fec00803523c (patch)
tree7ef8665102eaae79f7a8a67850f387caa27bf515
parent58a50a3a0aa814c0fb00720cb8fc9edb2cf72344 (diff)
downloadCMake-30c835428fffbf91191ebb1150d7fec00803523c.zip
CMake-30c835428fffbf91191ebb1150d7fec00803523c.tar.gz
CMake-30c835428fffbf91191ebb1150d7fec00803523c.tar.bz2
VS: Accept and translate '-T version=' values with three components
The VS 16.8 and VS 16.9 toolset versions differ only in their third component. The `vcvarsall` option `-vcvars_ver=` accepts a three component version, so accept this format for VS toolset selection too. Issue: #21922
-rw-r--r--Help/release/3.19.rst8
-rw-r--r--Help/variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION.rst12
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.cxx37
3 files changed, 57 insertions, 0 deletions
diff --git a/Help/release/3.19.rst b/Help/release/3.19.rst
index 1d55f1e..49c6793 100644
--- a/Help/release/3.19.rst
+++ b/Help/release/3.19.rst
@@ -432,3 +432,11 @@ Changes made since CMake 3.19.0 include the following.
``CMakePresets.json`` or ``CMakeUserPresets.json`` files.
This was mistakenly allowed by the implementation in CMake 3.19.0 through
CMake 3.19.5, and was not documented.
+
+3.19.7
+------
+
+* With :ref:`Visual Studio Generators` for VS 2017 and higher, the
+ :variable:`CMAKE_GENERATOR_TOOLSET` field ``version=`` now accepts
+ three-component MSVC toolset versions such as ``14.28.29910``.
+ See the :variable:`CMAKE_VS_PLATFORM_TOOLSET_VERSION` variable.
diff --git a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION.rst b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION.rst
index b058278..c4369ee 100644
--- a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION.rst
+++ b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION.rst
@@ -19,3 +19,15 @@ its ``Microsoft.VCToolsVersion.*.props`` file names.
VS 16.9's toolset may also be specified as ``14.28.16.9`` because
VS 16.10 uses the file name ``Microsoft.VCToolsVersion.14.28.16.9.props``.
+
+Three-Component MSVC Toolset Versions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. versionadded:: 3.19.7
+
+The ``version=`` field may be given a three-component toolset version
+such as ``14.28.29910``, and CMake will convert it to the name used by
+MSBuild ``Microsoft.VCToolsVersion.*.props`` files. This is useful
+to distinguish between VS 16.8's ``14.28.29333`` toolset and VS 16.9's
+``14.28.29910`` toolset. It also matches ``vcvarsall``'s ``-vcvars_ver=``
+behavior.
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
index 4e2464b..fb518a2 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
@@ -4,6 +4,9 @@
#include <cmext/string_view>
+#include "cmsys/FStream.hxx"
+#include "cmsys/Glob.hxx"
+
#include "cmAlgorithms.h"
#include "cmDocumentationEntry.h"
#include "cmLocalVisualStudio10Generator.h"
@@ -439,6 +442,40 @@ cmGlobalVisualStudioVersionedGenerator::FindAuxToolset(
this->GetVSInstance(instancePath);
cmSystemTools::ConvertToUnixSlashes(instancePath);
+ // Translate three-component format accepted by "vcvarsall -vcvars_ver=".
+ cmsys::RegularExpression threeComponent(
+ "^([0-9]+\\.[0-9]+)\\.[0-9][0-9][0-9][0-9][0-9]$");
+ if (threeComponent.find(version)) {
+ // Load "VC/Auxiliary/Build/*/Microsoft.VCToolsVersion.*.txt" files
+ // with two matching components to check their three-component version.
+ std::string const& twoComponent = threeComponent.match(1);
+ std::string pattern =
+ cmStrCat(instancePath, "/VC/Auxiliary/Build/"_s, twoComponent,
+ "*/Microsoft.VCToolsVersion."_s, twoComponent, "*.txt"_s);
+ cmsys::Glob glob;
+ glob.SetRecurseThroughSymlinks(false);
+ if (glob.FindFiles(pattern)) {
+ for (std::string const& txt : glob.GetFiles()) {
+ std::string ver;
+ cmsys::ifstream fin(txt.c_str());
+ if (fin && std::getline(fin, ver)) {
+ // Strip trailing whitespace.
+ ver = ver.substr(0, ver.find_first_not_of("0123456789."));
+ // If the three-component version matches, translate it to
+ // that used by the "Microsoft.VCToolsVersion.*.txt" file name.
+ if (ver == version) {
+ cmsys::RegularExpression extractVersion(
+ "VCToolsVersion\\.([0-9.]+)\\.txt$");
+ if (extractVersion.find(txt)) {
+ version = extractVersion.match(1);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
if (cmSystemTools::VersionCompareGreaterEq(version, "14.20")) {
props = cmStrCat(instancePath, "/VC/Auxiliary/Build."_s, version,
"/Microsoft.VCToolsVersion."_s, version, ".props"_s);