VS: Add Visual Studio 17 2022 generator

Fixes: #22339
This commit is contained in:
Brad King 2021-06-24 16:12:31 -04:00
parent b610b7a35c
commit c46b265839
18 changed files with 218 additions and 14 deletions

View File

@ -0,0 +1,61 @@
Visual Studio 17 2022
---------------------
.. versionadded:: 3.21
Generates Visual Studio 17 (VS 2022) project files.
.. warning::
This is experimental and based on "Visual Studio 2022 Preview 1.1".
As of this version of CMake, VS 2022 has not been released.
Project Types
^^^^^^^^^^^^^
Only Visual C++ and C# projects may be generated. Other types of
projects (JavaScript, Powershell, Python, etc.) are not supported.
Instance Selection
^^^^^^^^^^^^^^^^^^
VS 2022 supports multiple installations on the same machine.
The :variable:`CMAKE_GENERATOR_INSTANCE` variable may be set as a
cache entry containing the absolute path to a Visual Studio instance.
If the value is not specified explicitly by the user or a toolchain file,
CMake queries the Visual Studio Installer to locate VS instances, chooses
one, and sets the variable as a cache entry to hold the value persistently.
When CMake first chooses an instance, if the ``VS170COMNTOOLS`` environment
variable is set and points to the ``Common7/Tools`` directory within
one of the instances, that instance will be used. Otherwise, if more
than one instance is installed we do not define which one is chosen
by default.
Platform Selection
^^^^^^^^^^^^^^^^^^
The default target platform name (architecture) is that of the host
and is provided in the :variable:`CMAKE_VS_PLATFORM_NAME_DEFAULT` variable.
The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set, perhaps
via the :manual:`cmake(1)` ``-A`` option, to specify a target platform
name (architecture). For example:
* ``cmake -G "Visual Studio 17 2022" -A Win32``
* ``cmake -G "Visual Studio 17 2022" -A x64``
* ``cmake -G "Visual Studio 17 2022" -A ARM``
* ``cmake -G "Visual Studio 17 2022" -A ARM64``
Toolset Selection
^^^^^^^^^^^^^^^^^
The ``v142`` toolset that comes with VS 17 2022 Preview 1.1 is selected by
default. The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps
via the :manual:`cmake(1)` ``-T`` option, to specify another toolset.
.. |VS_TOOLSET_HOST_ARCH_DEFAULT| replace::
By default this generator uses the 64-bit variant on x64 hosts and
the 32-bit variant otherwise.
.. include:: VS_TOOLSET_HOST_ARCH.txt

View File

@ -91,6 +91,7 @@ Visual Studio Generators
/generator/Visual Studio 14 2015
/generator/Visual Studio 15 2017
/generator/Visual Studio 16 2019
/generator/Visual Studio 17 2022
Other Generators
^^^^^^^^^^^^^^^^

View File

@ -26,6 +26,10 @@ Presets
Generators
----------
* The :generator:`Visual Studio 17 2022` generator was added. This is
experimental and based on "Visual Studio 2022 Preview 1.1" because this
version of VS has not been released.
* The :ref:`Makefile Generators` and the :generator:`Ninja` generator
learned to add linker launcher tools along with the linker for ``C``,
``CXX``, ``OBJC``, and ``OBJCXX`` languages.

View File

@ -20,5 +20,8 @@ Known version numbers are::
1910-1919 = VS 15.0 (v141 toolset)
1920-1929 = VS 16.0 (v142 toolset)
..
1930-1939 = VS 17.0 (v143 toolset)
See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` and
:variable:`MSVC_TOOLSET_VERSION` variable.

View File

@ -171,6 +171,22 @@ bool GetValue(cmExecutionStatus& status, cmsys::SystemInformation& info,
if (vsSetupAPIHelper.GetVSInstanceInfo(value)) {
cmSystemTools::ConvertToUnixSlashes(value);
}
} else if (key == "VS_17_DIR") {
// If generating for the VS 17 IDE, use the same instance.
cmGlobalGenerator* gg = status.GetMakefile().GetGlobalGenerator();
if (cmHasLiteralPrefix(gg->GetName(), "Visual Studio 17 ")) {
cmGlobalVisualStudioVersionedGenerator* vs17gen =
static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg);
if (vs17gen->GetVSInstance(value)) {
return true;
}
}
// Otherwise, find a VS 17 instance ourselves.
cmVSSetupAPIHelper vsSetupAPIHelper(17);
if (vsSetupAPIHelper.GetVSInstanceInfo(value)) {
cmSystemTools::ConvertToUnixSlashes(value);
}
#endif
} else {
std::string e = "does not recognize <key> " + key;

View File

@ -1277,6 +1277,8 @@ const char* cmGlobalVisualStudio10Generator::GetToolsVersion() const
return "15.0";
case cmGlobalVisualStudioGenerator::VS16:
return "16.0";
case cmGlobalVisualStudioGenerator::VS17:
return "17.0";
}
return "";
}

View File

@ -104,6 +104,8 @@ const char* cmGlobalVisualStudioGenerator::GetIDEVersion() const
return "15.0";
case cmGlobalVisualStudioGenerator::VS16:
return "16.0";
case cmGlobalVisualStudioGenerator::VS17:
return "17.0";
}
return "";
}
@ -170,6 +172,15 @@ void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout)
fout << "# Visual Studio Version 16\n";
}
break;
case cmGlobalVisualStudioGenerator::VS17:
// Visual Studio 17 writes .sln format 12.00
fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n";
if (this->ExpressEdition) {
fout << "# Visual Studio Express 17 for Windows Desktop\n";
} else {
fout << "# Visual Studio Version 17\n";
}
break;
}
}

View File

@ -38,7 +38,8 @@ public:
/* VS13 = 130 was skipped */
VS14 = 140,
VS15 = 150,
VS16 = 160
VS16 = 160,
VS17 = 170
};
virtual ~cmGlobalVisualStudioGenerator();

View File

@ -79,6 +79,8 @@ static unsigned int VSVersionToMajor(
return 15;
case cmGlobalVisualStudioGenerator::VS16:
return 16;
case cmGlobalVisualStudioGenerator::VS17:
return 17;
}
return 0;
}
@ -101,6 +103,9 @@ static const char* VSVersionToToolset(
return "v141";
case cmGlobalVisualStudioGenerator::VS16:
return "v142";
case cmGlobalVisualStudioGenerator::VS17:
// FIXME: VS 2022 Preview 1 uses v142. Will it be v143 later?
return "v142";
}
return "";
}
@ -118,6 +123,7 @@ static const char* VSVersionToAndroidToolset(
return "Clang_3_8";
case cmGlobalVisualStudioGenerator::VS15:
case cmGlobalVisualStudioGenerator::VS16:
case cmGlobalVisualStudioGenerator::VS17:
return "Clang_5_0";
}
return "";
@ -219,6 +225,7 @@ cmGlobalVisualStudioVersionedGenerator::NewFactory15()
}
static const char vs16generatorName[] = "Visual Studio 16 2019";
static const char vs17generatorName[] = "Visual Studio 17 2022";
// Map generator name without year to name with year.
static const char* cmVS16GenName(const std::string& name, std::string& genName)
@ -235,6 +242,20 @@ static const char* cmVS16GenName(const std::string& name, std::string& genName)
return p;
}
static const char* cmVS17GenName(const std::string& name, std::string& genName)
{
if (strncmp(name.c_str(), vs17generatorName,
sizeof(vs17generatorName) - 6) != 0) {
return 0;
}
const char* p = name.c_str() + sizeof(vs17generatorName) - 6;
if (cmHasLiteralPrefix(p, " 2022")) {
p += 5;
}
genName = std::string(vs17generatorName) + p;
return p;
}
class cmGlobalVisualStudioVersionedGenerator::Factory16
: public cmGlobalGeneratorFactory
{
@ -299,6 +320,70 @@ cmGlobalVisualStudioVersionedGenerator::NewFactory16()
return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory16);
}
class cmGlobalVisualStudioVersionedGenerator::Factory17
: public cmGlobalGeneratorFactory
{
public:
std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
const std::string& name, bool /*allowArch*/, cmake* cm) const override
{
std::string genName;
const char* p = cmVS17GenName(name, genName);
if (!p) {
return std::unique_ptr<cmGlobalGenerator>();
}
if (!*p) {
return std::unique_ptr<cmGlobalGenerator>(
new cmGlobalVisualStudioVersionedGenerator(
cmGlobalVisualStudioGenerator::VS17, cm, genName, ""));
}
return std::unique_ptr<cmGlobalGenerator>();
}
void GetDocumentation(cmDocumentationEntry& entry) const override
{
entry.Name = std::string(vs17generatorName);
entry.Brief = "Generates Visual Studio 2022 project files. "
"Use -A option to specify architecture.";
}
std::vector<std::string> GetGeneratorNames() const override
{
std::vector<std::string> names;
names.push_back(vs17generatorName);
return names;
}
std::vector<std::string> GetGeneratorNamesWithPlatform() const override
{
return std::vector<std::string>();
}
bool SupportsToolset() const override { return true; }
bool SupportsPlatform() const override { return true; }
std::vector<std::string> GetKnownPlatforms() const override
{
std::vector<std::string> platforms;
platforms.emplace_back("x64");
platforms.emplace_back("Win32");
platforms.emplace_back("ARM");
platforms.emplace_back("ARM64");
return platforms;
}
std::string GetDefaultPlatformName() const override
{
return VSHostPlatformName();
}
};
std::unique_ptr<cmGlobalGeneratorFactory>
cmGlobalVisualStudioVersionedGenerator::NewFactory17()
{
return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory17);
}
cmGlobalVisualStudioVersionedGenerator::cmGlobalVisualStudioVersionedGenerator(
VSVersion version, cmake* cm, const std::string& name,
std::string const& platformInGeneratorName)
@ -339,6 +424,11 @@ bool cmGlobalVisualStudioVersionedGenerator::MatchesGeneratorName(
return genName == this->GetName();
}
break;
case cmGlobalVisualStudioGenerator::VS17:
if (cmVS17GenName(name, genName)) {
return genName == this->GetName();
}
break;
}
return false;
}
@ -446,6 +536,7 @@ cmGlobalVisualStudioVersionedGenerator::GetAndroidApplicationTypeRevision()
return "2.0";
case cmGlobalVisualStudioGenerator::VS15:
case cmGlobalVisualStudioGenerator::VS16:
case cmGlobalVisualStudioGenerator::VS17:
return "3.0";
}
return "";

View File

@ -21,6 +21,7 @@ class cmGlobalVisualStudioVersionedGenerator
public:
static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory15();
static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory16();
static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory17();
bool MatchesGeneratorName(const std::string& name) const override;
@ -68,5 +69,7 @@ private:
friend class Factory15;
class Factory16;
friend class Factory16;
class Factory17;
friend class Factory17;
mutable cmVSSetupAPIHelper vsSetupAPIHelper;
};

View File

@ -75,6 +75,7 @@ void cmVisualStudioGeneratorOptions::FixExceptionHandlingDefault()
case cmGlobalVisualStudioGenerator::VS14:
case cmGlobalVisualStudioGenerator::VS15:
case cmGlobalVisualStudioGenerator::VS16:
case cmGlobalVisualStudioGenerator::VS17:
// by default VS puts <ExceptionHandling></ExceptionHandling> empty
// for a project, to make our projects look the same put a new line
// and space over for the closing </ExceptionHandling> as the default

View File

@ -2201,7 +2201,9 @@ std::unique_ptr<cmGlobalGenerator> cmake::EvaluateDefaultGlobalGenerator()
"\\Setup\\VC;ProductDir", //
";InstallDir" //
};
if (cmVSSetupAPIHelper(16).IsVSInstalled()) {
if (cmVSSetupAPIHelper(17).IsVSInstalled()) {
found = "Visual Studio 17 2022";
} else if (cmVSSetupAPIHelper(16).IsVSInstalled()) {
found = "Visual Studio 16 2019";
} else if (cmVSSetupAPIHelper(15).IsVSInstalled()) {
found = "Visual Studio 15 2017";
@ -2505,6 +2507,8 @@ void cmake::AddDefaultGenerators()
{
#if defined(_WIN32) && !defined(__CYGWIN__)
# if !defined(CMAKE_BOOT_MINGW)
this->Generators.push_back(
cmGlobalVisualStudioVersionedGenerator::NewFactory17());
this->Generators.push_back(
cmGlobalVisualStudioVersionedGenerator::NewFactory16());
this->Generators.push_back(

View File

@ -209,9 +209,12 @@ if(BUILD_TESTING)
if(CMAKE_HOST_WIN32 AND COMMAND cmake_host_system_information)
set(info_vs15 "VS_15_DIR")
set(info_vs16 "VS_16_DIR")
set(info_vs17 "VS_17_DIR")
set(vs_versions)
if(WIN32)
if(NOT CMAKE_VERSION VERSION_LESS 3.14)
if(NOT CMAKE_VERSION VERSION_LESS 3.21.20210624)
set(vs_versions vs15 vs16 vs17)
elseif(NOT CMAKE_VERSION VERSION_LESS 3.14)
set(vs_versions vs15 vs16)
elseif(NOT CMAKE_VERSION VERSION_LESS 3.8)
set(vs_versions vs15)
@ -2459,6 +2462,9 @@ if(BUILD_TESTING)
if(vs16 AND CMake_TEST_ANDROID_VS16)
add_test_VSAndroid(vs16 "Visual Studio 16 2019" "ARM")
endif()
if(vs17 AND CMake_TEST_ANDROID_VS17)
add_test_VSAndroid(vs17 "Visual Studio 17 2022" "ARM")
endif()
if (APPLE)
if (CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")

View File

@ -313,7 +313,7 @@ function(run_EnvironmentGenerator)
unset(ENV{CMAKE_GENERATOR_PLATFORM})
endif()
# Instance is available since VS 2017.
if(RunCMake_GENERATOR MATCHES "Visual Studio (15|16).*")
if(RunCMake_GENERATOR MATCHES "Visual Studio 1[567].*")
set(ENV{CMAKE_GENERATOR_INSTANCE} "invalid")
# Envvar shouldn't affect existing build tree
run_cmake_command(Envgen-instance-existing ${CMAKE_COMMAND} -E chdir ..

View File

@ -3,7 +3,7 @@ include(RunCMake)
set(RunCMake_GENERATOR_PLATFORM "")
run_cmake(NoPlatform)
if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio ([89]|1[012456])( 20[0-9][0-9])?$")
if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio ([89]|1[0124567])( 20[0-9][0-9])?$")
set(RunCMake_GENERATOR_PLATFORM "x64")
run_cmake(x64Platform)
else()
@ -17,7 +17,7 @@ set(RunCMake_TEST_OPTIONS -A "Test Platform" -A "Extra Platform")
run_cmake(TwoPlatforms)
unset(RunCMake_TEST_OPTIONS)
if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio ([89]|1[012456])( 20[0-9][0-9])?$")
if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio ([89]|1[0124567])( 20[0-9][0-9])?$")
set(RunCMake_TEST_OPTIONS -DCMAKE_TOOLCHAIN_FILE=${RunCMake_SOURCE_DIR}/TestPlatform-toolchain.cmake)
run_cmake(TestPlatformToolchain)
unset(RunCMake_TEST_OPTIONS)

View File

@ -1,6 +1,6 @@
include(RunCMake)
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[012456]")
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[0124567]")
run_cmake(VsNormal)
include("${RunCMake_BINARY_DIR}/VsNormal-build/defaults.cmake" OPTIONAL)
message(STATUS "VsNormal: platform='${VsNormal_Platform}' toolset='${VsNormal_Toolset}'")
@ -9,7 +9,7 @@ endif()
set(RunCMake_GENERATOR_TOOLSET "")
run_cmake(NoToolset)
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[012456]")
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[0124567]")
set(RunCMake_GENERATOR_TOOLSET "Test Toolset")
run_cmake(TestToolset)
set(RunCMake_GENERATOR_TOOLSET "Test Toolset,cuda=0.0")
@ -43,7 +43,7 @@ if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[012456]")
set(RunCMake_GENERATOR_TOOLSET "${VsNormal_Toolset},customFlagTableDir=does_not_exist")
run_cmake(BadToolsetCustomFlagTableDir)
endif()
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[2456]")
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[24567]")
set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64")
run_cmake(TestToolsetHostArchBoth)
set(RunCMake_GENERATOR_TOOLSET ",host=x64")
@ -58,7 +58,7 @@ if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[012456]")
run_cmake(BadToolsetHostArch)
set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64,host=x86")
run_cmake(BadToolsetHostArchTwice)
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[56]")
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[567]")
set(RunCMake_GENERATOR_TOOLSET "VCTargetsPath=Test Path")
run_cmake(TestToolsetVCTargetsPathOnly)
set(RunCMake_GENERATOR_TOOLSET "Test Toolset,version=Test Toolset Version")
@ -109,7 +109,7 @@ set(RunCMake_TEST_OPTIONS -T "Test Toolset" -T "Extra Toolset")
run_cmake(TwoToolsets)
unset(RunCMake_TEST_OPTIONS)
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[012456]|Xcode")
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[0124567]|Xcode")
set(RunCMake_TEST_OPTIONS -DCMAKE_TOOLCHAIN_FILE=${RunCMake_SOURCE_DIR}/TestToolset-toolchain.cmake)
run_cmake(TestToolsetToolchain)
unset(RunCMake_TEST_OPTIONS)

View File

@ -1,7 +1,7 @@
message(STATUS "CMAKE_VS_PLATFORM_TOOLSET='${CMAKE_VS_PLATFORM_TOOLSET}'")
message(STATUS "CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE='${CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE}'")
if(CMAKE_GENERATOR MATCHES "Visual Studio 1[6]")
if(CMAKE_GENERATOR MATCHES "Visual Studio 1[67]")
cmake_host_system_information(RESULT is_64_bit QUERY IS_64BIT)
if(is_64_bit)
if(NOT "${CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE}" STREQUAL "x64")

View File

@ -1,7 +1,7 @@
cmake_minimum_required (VERSION 2.8.12)
project(VSExternalInclude)
if(${CMAKE_GENERATOR} MATCHES "Visual Studio 1[012456]")
if(${CMAKE_GENERATOR} MATCHES "Visual Studio 1[0124567]")
set(PROJECT_EXT vcxproj)
else()
set(PROJECT_EXT vcproj)
@ -55,7 +55,7 @@ add_dependencies(VSExternalInclude lib2)
# and the sln file can no longer be the only source
# of that depend. So, for VS 10 make the executable
# depend on lib1 and lib2
if(${CMAKE_GENERATOR} MATCHES "Visual Studio 1[012456]")
if(${CMAKE_GENERATOR} MATCHES "Visual Studio 1[0124567]")
add_dependencies(VSExternalInclude lib1)
endif()