vintner only ever downloads one compiler generation, but real-world
.vcxproj files are pinned to whichever PlatformToolset they were last
saved under - v142 (VS2019) for anything not actively maintained is
extremely common. MSBuild checks toolset "installed-ness" (MSB8020) by
testing whether MSBuild/Microsoft/VC/v<schema>/Platforms/<arch>/
PlatformToolsets/<toolset>/ exists on disk - a plain file lookup our
downloaded MSBuild package only satisfies for the exact generation it
shipped. `install` now symlinks every historical numeric PlatformToolset
name (v90 through v143) onto whichever real toolset directory is
actually present, so any of them resolves transparently; Toolset.props/
.targets don't hardcode a version number, so aliasing is correct, not
just a workaround.
Three more MSBuild property/environment issues came with it, all found
building a real years-old project against the one modern toolchain
vintner installs:
- VCInstallDir_<N>/VCToolsInstallDir_<N> needed a third numbering
source (PlatformToolset short names from Microsoft.VCToolsVersion.
v<N>.default.props) alongside the existing MSBuild schema-version and
known-toolset lists, so the env-var-driven half of toolset resolution
covers the same names the on-disk alias does.
- VCToolsVersion must be a real version string: left unset, it falls
back to a literal placeholder that then hits an unconditional
version-string comparison elsewhere in Microsoft.CppBuild.targets
(MSB4184). Setting it to the real installed version in turn requires
CheckMSVCComponents=false, since CheckVCToolsetVersion (MSB8052)
otherwise rejects an aliased PlatformToolset whenever its numeric
generation doesn't match VCToolsVersion's - exactly the case aliasing
creates on purpose. Everything else CheckMSVCComponents gates is
diagnostic-only (MFC/ATL/Spectre presence warnings), so disabling it
costs nothing else.
- WindowsTargetPlatformVersion needed to become an explicit /p: global
property on the msbuild command line, not just an env var: legacy
.vcxproj files commonly hardcode this in a PropertyGroup, and an
explicit project assignment always wins over an inherited environment
variable of the same name. A command-line global property is the one
thing a project file can't override. Only injected when the caller
hasn't already pinned it themselves.