diff --git a/Help/generator/Visual Studio 18 2026.rst b/Help/generator/Visual Studio 18 2026.rst new file mode 100644 index 0000000000..80127d0658 --- /dev/null +++ b/Help/generator/Visual Studio 18 2026.rst @@ -0,0 +1,47 @@ +Visual Studio 18 2026 +--------------------- + +.. versionadded:: 4.2 + +Generates Visual Studio 18 (VS 2026) project files. + +Project Types +^^^^^^^^^^^^^ + +Only Visual C++ and C# projects may be generated (and Fortran with +Intel compiler integration). Other types of projects (JavaScript, +Powershell, Python, etc.) are not supported. + +Instance Selection +^^^^^^^^^^^^^^^^^^ + +VS 2026 supports multiple installations on the same machine. The +:variable:`CMAKE_GENERATOR_INSTANCE` variable may be used to select one. + +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 :option:`cmake -A` option, to specify a target platform +name (architecture). For example: + +* ``cmake -G "Visual Studio 18 2026" -A Win32`` +* ``cmake -G "Visual Studio 18 2026" -A x64`` +* ``cmake -G "Visual Studio 18 2026" -A ARM`` +* ``cmake -G "Visual Studio 18 2026" -A ARM64`` + +Toolset Selection +^^^^^^^^^^^^^^^^^ + +The ``v145`` toolset that comes with VS 18 2026 is selected by default. +The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps +via the :option:`cmake -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:: include/VS_TOOLSET_HOST_ARCH.rst diff --git a/Help/manual/cmake-generators.7.rst b/Help/manual/cmake-generators.7.rst index 9647f0d11d..b8f352f78a 100644 --- a/Help/manual/cmake-generators.7.rst +++ b/Help/manual/cmake-generators.7.rst @@ -92,6 +92,7 @@ Visual Studio Generators /generator/Visual Studio 15 2017 /generator/Visual Studio 16 2019 /generator/Visual Studio 17 2022 + /generator/Visual Studio 18 2026 Other Generators ^^^^^^^^^^^^^^^^ diff --git a/Help/variable/MSVC_TOOLSET_VERSION.rst b/Help/variable/MSVC_TOOLSET_VERSION.rst index 84a6f33c68..cfd24abefc 100644 --- a/Help/variable/MSVC_TOOLSET_VERSION.rst +++ b/Help/variable/MSVC_TOOLSET_VERSION.rst @@ -24,6 +24,7 @@ Known toolset version numbers are: 141 VS 2017 (15.0) 142 VS 2019 (16.0) 143 VS 2022 (17.0) + 145 VS 2026 (18.0) ===== ============== Compiler versions newer than those known to CMake will be reported diff --git a/Help/variable/MSVC_VERSION.rst b/Help/variable/MSVC_VERSION.rst index 4d87a036ec..e3140a9180 100644 --- a/Help/variable/MSVC_VERSION.rst +++ b/Help/variable/MSVC_VERSION.rst @@ -26,6 +26,7 @@ Known version numbers are: 1910-1919 VS 15.0 (v141 toolset) 1920-1929 VS 16.0 (v142 toolset) 1930-1949 VS 17.0 (v143 toolset) + 1950-1959 VS 18.0 (v145 toolset) ========= ============== See also the :variable:`CMAKE__COMPILER_VERSION` and diff --git a/Modules/InstallRequiredSystemLibraries.cmake b/Modules/InstallRequiredSystemLibraries.cmake index 4d7aff387d..32e903e171 100644 --- a/Modules/InstallRequiredSystemLibraries.cmake +++ b/Modules/InstallRequiredSystemLibraries.cmake @@ -239,8 +239,12 @@ if(MSVC) set(_MSVC_IDE_VERSION "") if(MSVC_VERSION GREATER_EQUAL 2000) message(WARNING "MSVC ${MSVC_VERSION} not yet supported.") - elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 144) + elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 146) message(WARNING "MSVC toolset v${MSVC_TOOLSET_VERSION} not yet supported.") + elseif(MSVC_TOOLSET_VERSION EQUAL 145) + set(MSVC_REDIST_NAME VC145) + set(_MSVC_DLL_VERSION 140) + set(_MSVC_IDE_VERSION 18) elseif(MSVC_TOOLSET_VERSION EQUAL 143) set(MSVC_REDIST_NAME VC143) set(_MSVC_DLL_VERSION 140) @@ -285,7 +289,7 @@ if(MSVC) if(NOT vs VERSION_LESS 15) set(_vs_redist_paths "") # The toolset and its redistributables may come with any VS version 15 or newer. - set(_MSVC_IDE_VERSIONS 17 16 15) + set(_MSVC_IDE_VERSIONS 18 17 16 15) foreach(_vs_ver ${_MSVC_IDE_VERSIONS}) set(_vs_glob_redist_paths "") cmake_host_system_information(RESULT _vs_dir QUERY VS_${_vs_ver}_DIR) # undocumented query diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake index 37d5cf1ca6..962b57a014 100644 --- a/Modules/Platform/Windows-GNU.cmake +++ b/Modules/Platform/Windows-GNU.cmake @@ -181,7 +181,7 @@ macro(__windows_compiler_gnu_abi lang) # Query the VS Installer tool for locations of VS 2017 and above. set(_vs_installer_paths "") - foreach(vs RANGE 17 15 -1) # change the first number to the largest supported version + foreach(vs RANGE 18 15 -1) # change the first number to the largest supported version cmake_host_system_information(RESULT _vs_dir QUERY VS_${vs}_DIR) if(_vs_dir) list(APPEND _vs_installer_paths "${_vs_dir}/VC/Auxiliary/Build") diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index 48c7b49a2f..7812a9697a 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake @@ -61,7 +61,10 @@ if(NOT MSVC_VERSION) message(FATAL_ERROR "MSVC compiler version not detected properly: ${_compiler_version}") endif() - if(MSVC_VERSION GREATER_EQUAL 1930) + if(MSVC_VERSION GREATER_EQUAL 1950) + # VS 2026 or greater + set(MSVC_TOOLSET_VERSION 145) + elseif(MSVC_VERSION GREATER_EQUAL 1930) # VS 2022 or greater set(MSVC_TOOLSET_VERSION 143) elseif(MSVC_VERSION GREATER_EQUAL 1920) diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx index 00b59c62eb..447092b883 100644 --- a/Source/cmCMakeHostSystemInformationCommand.cxx +++ b/Source/cmCMakeHostSystemInformationCommand.cxx @@ -498,7 +498,7 @@ cm::optional GetWindowsValue(cmExecutionStatus& status, std::string const& key) { auto* const gg = status.GetMakefile().GetGlobalGenerator(); - for (auto vs : { 15, 16, 17 }) { + for (auto vs : { 15, 16, 17, 18 }) { if (key == cmStrCat("VS_"_s, vs, "_DIR"_s)) { std::string value; // If generating for the VS nn IDE, use the same instance. diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 1a21b06e6f..cb447aac83 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -1276,6 +1276,8 @@ char const* cmGlobalVisualStudio10Generator::GetToolsVersion() const return "16.0"; case cmGlobalVisualStudioGenerator::VSVersion::VS17: return "17.0"; + case cmGlobalVisualStudioGenerator::VSVersion::VS18: + return "18.0"; } return ""; } diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index f4c4219b06..b8ba1ad406 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -115,6 +115,8 @@ char const* cmGlobalVisualStudioGenerator::GetIDEVersion() const return "16.0"; case cmGlobalVisualStudioGenerator::VSVersion::VS17: return "17.0"; + case cmGlobalVisualStudioGenerator::VSVersion::VS18: + return "18.0"; } return ""; } @@ -150,6 +152,11 @@ void cmGlobalVisualStudioGenerator::WriteSLNHeader(std::ostream& fout) const fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n"; fout << "# Visual Studio Version 17\n"; break; + case cmGlobalVisualStudioGenerator::VSVersion::VS18: + // Visual Studio 18 writes .sln format 12.00 + fout << "Microsoft Visual Studio Solution File, Format Version 12.00\n"; + fout << "# Visual Studio Version 18\n"; + break; } } diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h index 364ab3c6f4..344295c29c 100644 --- a/Source/cmGlobalVisualStudioGenerator.h +++ b/Source/cmGlobalVisualStudioGenerator.h @@ -37,7 +37,8 @@ public: VS14 = 140, VS15 = 150, VS16 = 160, - VS17 = 170 + VS17 = 170, + VS18 = 180, }; ~cmGlobalVisualStudioGenerator() override; diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx index 4ba1c5a880..238475782a 100644 --- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx +++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx @@ -133,6 +133,8 @@ static unsigned int VSVersionToMajor( return 16; case cmGlobalVisualStudioGenerator::VSVersion::VS17: return 17; + case cmGlobalVisualStudioGenerator::VSVersion::VS18: + return 18; } return 0; } @@ -149,6 +151,8 @@ static char const* VSVersionToToolset( return "v142"; case cmGlobalVisualStudioGenerator::VSVersion::VS17: return "v143"; + case cmGlobalVisualStudioGenerator::VSVersion::VS18: + return "v145"; } return ""; } @@ -165,6 +169,8 @@ static std::string VSVersionToMajorString( return "16"; case cmGlobalVisualStudioGenerator::VSVersion::VS17: return "17"; + case cmGlobalVisualStudioGenerator::VSVersion::VS18: + return "18"; } return ""; } @@ -178,6 +184,7 @@ static char const* VSVersionToAndroidToolset( case cmGlobalVisualStudioGenerator::VSVersion::VS15: case cmGlobalVisualStudioGenerator::VSVersion::VS16: case cmGlobalVisualStudioGenerator::VSVersion::VS17: + case cmGlobalVisualStudioGenerator::VSVersion::VS18: return "Clang_5_0"; } return ""; @@ -258,6 +265,7 @@ cmGlobalVisualStudioVersionedGenerator::NewFactory15() static char const vs16generatorName[] = "Visual Studio 16 2019"; static char const vs17generatorName[] = "Visual Studio 17 2022"; +static char const vs18generatorName[] = "Visual Studio 18 2026"; // Map generator name without year to name with year. static char const* cmVS16GenName(std::string const& name, std::string& genName) @@ -288,6 +296,20 @@ static char const* cmVS17GenName(std::string const& name, std::string& genName) return p; } +static char const* cmVS18GenName(std::string const& name, std::string& genName) +{ + if (strncmp(name.c_str(), vs18generatorName, + sizeof(vs18generatorName) - 6) != 0) { + return nullptr; + } + char const* p = name.c_str() + sizeof(vs18generatorName) - 6; + if (cmHasLiteralPrefix(p, " 2026")) { + p += 5; + } + genName = cmStrCat(vs18generatorName, p); + return p; +} + class cmGlobalVisualStudioVersionedGenerator::Factory16 : public cmGlobalGeneratorFactory { @@ -408,6 +430,66 @@ cmGlobalVisualStudioVersionedGenerator::NewFactory17() return std::unique_ptr(new Factory17); } +class cmGlobalVisualStudioVersionedGenerator::Factory18 + : public cmGlobalGeneratorFactory +{ +public: + std::unique_ptr CreateGlobalGenerator( + std::string const& name, cmake* cm) const override + { + std::string genName; + char const* p = cmVS18GenName(name, genName); + if (!p) { + return std::unique_ptr(); + } + if (!*p) { + return std::unique_ptr( + new cmGlobalVisualStudioVersionedGenerator( + cmGlobalVisualStudioGenerator::VSVersion::VS18, cm, genName)); + } + return std::unique_ptr(); + } + + cmDocumentationEntry GetDocumentation() const override + { + return { std::string(vs18generatorName), + "Generates Visual Studio 2026 project files. " + "Use -A option to specify architecture." }; + } + + std::vector GetGeneratorNames() const override + { + std::vector names; + names.push_back(vs18generatorName); + return names; + } + + bool SupportsToolset() const override { return true; } + bool SupportsPlatform() const override { return true; } + + std::vector GetKnownPlatforms() const override + { + std::vector platforms; + platforms.emplace_back("x64"); + platforms.emplace_back("Win32"); + platforms.emplace_back("ARM"); + platforms.emplace_back("ARM64"); + platforms.emplace_back("ARM64EC"); + return platforms; + } + + std::string GetDefaultPlatformName() const override + { + return VSHostPlatformName(); + } +}; + +std::unique_ptr +cmGlobalVisualStudioVersionedGenerator::NewFactory18() +{ + return std::unique_ptr(new Factory18); +} + cmGlobalVisualStudioVersionedGenerator::cmGlobalVisualStudioVersionedGenerator( VSVersion version, cmake* cm, std::string const& name) : cmGlobalVisualStudio14Generator(cm, name) @@ -455,6 +537,11 @@ bool cmGlobalVisualStudioVersionedGenerator::MatchesGeneratorName( return genName == this->GetName(); } break; + case cmGlobalVisualStudioGenerator::VSVersion::VS18: + if (cmVS18GenName(name, genName)) { + return genName == this->GetName(); + } + break; } return false; } @@ -709,6 +796,7 @@ cmGlobalVisualStudioVersionedGenerator::GetAndroidApplicationTypeRevision() case cmGlobalVisualStudioGenerator::VSVersion::VS15: case cmGlobalVisualStudioGenerator::VSVersion::VS16: case cmGlobalVisualStudioGenerator::VSVersion::VS17: + case cmGlobalVisualStudioGenerator::VSVersion::VS18: return "3.0"; } return ""; diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.h b/Source/cmGlobalVisualStudioVersionedGenerator.h index b597965455..bb1def3096 100644 --- a/Source/cmGlobalVisualStudioVersionedGenerator.h +++ b/Source/cmGlobalVisualStudioVersionedGenerator.h @@ -26,6 +26,7 @@ public: static std::unique_ptr NewFactory15(); static std::unique_ptr NewFactory16(); static std::unique_ptr NewFactory17(); + static std::unique_ptr NewFactory18(); bool MatchesGeneratorName(std::string const& name) const override; @@ -89,6 +90,8 @@ private: friend class Factory16; class Factory17; friend class Factory17; + class Factory18; + friend class Factory18; mutable cmVSSetupAPIHelper vsSetupAPIHelper; bool ParseGeneratorInstance(std::string const& is, cmMakefile* mf); diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 0651405479..2882592aa5 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -2780,7 +2780,9 @@ std::unique_ptr cmake::EvaluateDefaultGlobalGenerator() "\\Setup\\VC;ProductDir", // ";InstallDir" // }; - if (cmVSSetupAPIHelper(17).IsVSInstalled()) { + if (cmVSSetupAPIHelper(18).IsVSInstalled()) { + found = "Visual Studio 18 2026"; + } else if (cmVSSetupAPIHelper(17).IsVSInstalled()) { found = "Visual Studio 17 2022"; } else if (cmVSSetupAPIHelper(16).IsVSInstalled()) { found = "Visual Studio 16 2019"; @@ -3212,6 +3214,8 @@ void cmake::AddDefaultGenerators() { #if defined(_WIN32) && !defined(__CYGWIN__) # if !defined(CMAKE_BOOT_MINGW) + this->Generators.push_back( + cmGlobalVisualStudioVersionedGenerator::NewFactory18()); this->Generators.push_back( cmGlobalVisualStudioVersionedGenerator::NewFactory17()); this->Generators.push_back( diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 15a1e2c0c3..5a455228f9 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -194,9 +194,12 @@ if(BUILD_TESTING) set(info_vs15 "VS_15_DIR") set(info_vs16 "VS_16_DIR") set(info_vs17 "VS_17_DIR") + set(info_vs18 "VS_18_DIR") set(vs_versions) if(WIN32) - if(NOT CMAKE_VERSION VERSION_LESS 3.21.20210624) + if(NOT CMAKE_VERSION VERSION_LESS 4.2) + set(vs_versions vs15 vs16 vs17 vs18) + elseif(NOT CMAKE_VERSION VERSION_LESS 3.21) set(vs_versions vs15 vs16 vs17) elseif(NOT CMAKE_VERSION VERSION_LESS 3.14) set(vs_versions vs15 vs16) @@ -2402,6 +2405,9 @@ if(BUILD_TESTING) if(vs17 AND CMake_TEST_ANDROID_VS17) add_test_VSAndroid(vs17 "Visual Studio 17 2022" "ARM") endif() + if(vs18 AND CMake_TEST_ANDROID_VS18) + add_test_VSAndroid(vs18 "Visual Studio 18 2026" "ARM") + endif() if(APPLE) if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index 9fda9eb5b1..60cb9f5561 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake @@ -413,7 +413,7 @@ function(run_EnvironmentGenerator) unset(ENV{CMAKE_GENERATOR_PLATFORM}) endif() # Instance is available since VS 2017. - if(RunCMake_GENERATOR MATCHES "Visual Studio 1[567].*") + if(RunCMake_GENERATOR MATCHES "Visual Studio 1[5678].*") set(ENV{CMAKE_GENERATOR_INSTANCE} "invalid") # Envvar shouldn't affect existing build tree run_cmake_command(Envgen-instance-existing ${CMAKE_COMMAND} -E chdir .. diff --git a/Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake index b1c758ada6..8322ef28a0 100644 --- a/Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake +++ b/Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake @@ -27,7 +27,7 @@ else() unset(RunCMake_TEST_OPTIONS) endif() -if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio (1[4567])( 20[0-9][0-9])?$") +if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio (1[45678])( 20[0-9][0-9])?$") unset(ENV{WindowsSDKVersion}) set(RunCMake_GENERATOR_PLATFORM "Test Platform,nocomma") diff --git a/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake index 80d1d5e860..83487111f7 100644 --- a/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake +++ b/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake @@ -64,7 +64,7 @@ if("${RunCMake_GENERATOR}" MATCHES "Visual Studio") run_cmake(BadToolsetHostArch) set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64,host=x86") run_cmake(BadToolsetHostArchTwice) - if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[567]") + if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[5678]") set(RunCMake_GENERATOR_TOOLSET "VCTargetsPath=Test Path") run_cmake(TestToolsetVCTargetsPathOnly) set(RunCMake_GENERATOR_TOOLSET "Test Toolset,version=Test Toolset Version") diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetHostArchNone.cmake b/Tests/RunCMake/GeneratorToolset/TestToolsetHostArchNone.cmake index 9d5d0b5b9f..c15b572a6d 100644 --- a/Tests/RunCMake/GeneratorToolset/TestToolsetHostArchNone.cmake +++ b/Tests/RunCMake/GeneratorToolset/TestToolsetHostArchNone.cmake @@ -2,7 +2,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}'") message(STATUS "CMAKE_HOST_SYSTEM_PROCESSOR='${CMAKE_HOST_SYSTEM_PROCESSOR}'") -if(CMAKE_GENERATOR MATCHES "Visual Studio 1[67]") +if(CMAKE_GENERATOR MATCHES "Visual Studio 1[678]") cmake_host_system_information(RESULT is_64_bit QUERY IS_64BIT) if(is_64_bit) if("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "ARM64")