From 78782cc7dc9f4efa2e3a19c174dca0129d99af2e Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 3 Nov 2021 11:58:27 -0400 Subject: cmGlobalVisualStudio8Generator: Refactor SetGeneratorPlatform Re-organize the method to make room for additional `CMAKE_GENERATOR_PLATFORM` processing. --- Source/cmGlobalVisualStudio8Generator.cxx | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 092e5b9..439d13e 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -67,12 +67,19 @@ void cmGlobalVisualStudio8Generator::AddPlatformDefinitions(cmMakefile* mf) bool cmGlobalVisualStudio8Generator::SetGeneratorPlatform(std::string const& p, cmMakefile* mf) { - if (!this->PlatformInGeneratorName) { - this->GeneratorPlatform = p; - return this->cmGlobalVisualStudio7Generator::SetGeneratorPlatform("", mf); - } else { + if (this->PlatformInGeneratorName) { + // This is an old-style generator name that contains the platform name. + // No explicit platform specification is supported, so pass it through + // to our base class implementation, which errors on non-empty platforms. return this->cmGlobalVisualStudio7Generator::SetGeneratorPlatform(p, mf); } + + this->GeneratorPlatform = p; + + // The generator name does not contain the platform name, and so supports + // explicit platform specification. We handled that above, so pass an + // empty platform name to our base class implementation so it does not error. + return this->cmGlobalVisualStudio7Generator::SetGeneratorPlatform("", mf); } std::string cmGlobalVisualStudio8Generator::GetGenerateStampList() -- cgit v0.12 From e40cedddc0bcdd7d0317592a83fde42fd018f72f Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 5 Nov 2021 08:54:14 -0400 Subject: cmVisualStudio10TargetGenerator: Refactor target framework selection Split the selection from the generation of the resulting element(s). --- Source/cmVisualStudio10TargetGenerator.cxx | 88 ++++++++++++++++++------------ 1 file changed, 53 insertions(+), 35 deletions(-) diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 1ea0461..f765612 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -492,50 +493,67 @@ void cmVisualStudio10TargetGenerator::Generate() cmValue projLabel = this->GeneratorTarget->GetProperty("PROJECT_LABEL"); e1.Element("ProjectName", projLabel ? projLabel : this->Name); { - cmValue targetFramework = - this->GeneratorTarget->GetProperty("DOTNET_TARGET_FRAMEWORK"); + cm::optional targetFramework; + cm::optional targetFrameworkVersion; + cm::optional targetFrameworkIdentifier; + cm::optional targetFrameworkTargetsVersion; + if (cmValue tf = + this->GeneratorTarget->GetProperty("DOTNET_TARGET_FRAMEWORK")) { + targetFramework = *tf; + } else if (cmValue vstfVer = this->GeneratorTarget->GetProperty( + "VS_DOTNET_TARGET_FRAMEWORK_VERSION")) { + // FIXME: Someday, add a deprecation warning for VS_* property. + targetFrameworkVersion = *vstfVer; + } else if (cmValue tfVer = this->GeneratorTarget->GetProperty( + "DOTNET_TARGET_FRAMEWORK_VERSION")) { + targetFrameworkVersion = *tfVer; + } else if (this->ProjectType == csproj && + this->GlobalGenerator->TargetsWindowsCE() && + this->GlobalGenerator->GetVersion() == + cmGlobalVisualStudioGenerator::VS12) { + // VS12 .NETCF default to .NET framework 3.9 + targetFrameworkVersion = "v3.9"; + } + if (this->ProjectType == vcxproj && + this->GlobalGenerator->TargetsWindowsCE()) { + e1.Element("EnableRedirectPlatform", "true"); + e1.Element("RedirectPlatformValue", this->Platform); + } + if (this->ProjectType == csproj) { + if (this->GlobalGenerator->TargetsWindowsCE()) { + // FIXME: These target VS_TARGET_FRAMEWORK* target properties + // are undocumented settings only ever supported for WinCE. + // We need a better way to control these in general. + if (cmValue tfId = this->GeneratorTarget->GetProperty( + "VS_TARGET_FRAMEWORK_IDENTIFIER")) { + targetFrameworkIdentifier = *tfId; + } else { + targetFrameworkIdentifier = "WindowsEmbeddedCompact"; + } + if (cmValue tfTargetsVer = this->GeneratorTarget->GetProperty( + "VS_TARGET_FRAMEWORKS_TARGET_VERSION")) { + targetFrameworkTargetsVersion = *tfTargetsVer; + } else { + targetFrameworkTargetsVersion = "v8.0"; + } + } + } if (targetFramework) { if (targetFramework->find(';') != std::string::npos) { e1.Element("TargetFrameworks", *targetFramework); } else { e1.Element("TargetFramework", *targetFramework); } - } else { - // TODO: add deprecation warning for VS_* property? - cmValue p = this->GeneratorTarget->GetProperty( - "VS_DOTNET_TARGET_FRAMEWORK_VERSION"); - if (!p) { - p = this->GeneratorTarget->GetProperty( - "DOTNET_TARGET_FRAMEWORK_VERSION"); - } - std::string targetFrameworkVersion = p; - if (targetFrameworkVersion.empty() && this->ProjectType == csproj && - this->GlobalGenerator->TargetsWindowsCE() && - this->GlobalGenerator->GetVersion() == - cmGlobalVisualStudioGenerator::VS12) { - // VS12 .NETCF default to .NET framework 3.9 - targetFrameworkVersion = "v3.9"; - } - if (!targetFrameworkVersion.empty()) { - e1.Element("TargetFrameworkVersion", targetFrameworkVersion); - } } - if (this->ProjectType == vcxproj && - this->GlobalGenerator->TargetsWindowsCE()) { - e1.Element("EnableRedirectPlatform", "true"); - e1.Element("RedirectPlatformValue", this->Platform); + if (targetFrameworkVersion) { + e1.Element("TargetFrameworkVersion", *targetFrameworkVersion); } - if (this->ProjectType == csproj && - this->GlobalGenerator->TargetsWindowsCE()) { - cmValue targetFrameworkId = this->GeneratorTarget->GetProperty( - "VS_TARGET_FRAMEWORK_IDENTIFIER"); - e1.Element("TargetFrameworkIdentifier", - targetFrameworkId ? *targetFrameworkId - : "WindowsEmbeddedCompact"); - cmValue targetFrameworkVer = this->GeneratorTarget->GetProperty( - "VS_TARGET_FRAMEWORKS_TARGET_VERSION"); + if (targetFrameworkIdentifier) { + e1.Element("TargetFrameworkIdentifier", *targetFrameworkIdentifier); + } + if (targetFrameworkTargetsVersion) { e1.Element("TargetFrameworkTargetsVersion", - targetFrameworkVer ? *targetFrameworkVer : "v8.0"); + *targetFrameworkTargetsVersion); } if (!this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString() .empty()) { -- cgit v0.12 From f97f8537f371daa073edce34f54743d1f261c022 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 3 Nov 2021 14:31:04 -0400 Subject: VS: Model a default target framework Add fields to the VS generator to select a target framework. Migrate the existing default for VS 12 .NET CF for Windows CE. Report the values in `CMAKE_VS_*` variables and use them for the CSharp compiler id project too. Issue: #22849 --- Help/manual/cmake-variables.7.rst | 3 ++ .../CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER.rst | 13 ++++++++ .../CMAKE_VS_TARGET_FRAMEWORK_TARGETS_VERSION.rst | 13 ++++++++ .../variable/CMAKE_VS_TARGET_FRAMEWORK_VERSION.rst | 17 ++++++++++ Modules/CMakeDetermineCompilerId.cmake | 9 ++++++ Modules/CompilerId/VS-10.csproj.in | 3 ++ Source/cmGlobalVisualStudio10Generator.cxx | 7 +++++ Source/cmGlobalVisualStudio8Generator.cxx | 36 ++++++++++++++++++++++ Source/cmGlobalVisualStudio8Generator.h | 10 ++++++ Source/cmVisualStudio10TargetGenerator.cxx | 21 +++++++------ 10 files changed, 122 insertions(+), 10 deletions(-) create mode 100644 Help/variable/CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER.rst create mode 100644 Help/variable/CMAKE_VS_TARGET_FRAMEWORK_TARGETS_VERSION.rst create mode 100644 Help/variable/CMAKE_VS_TARGET_FRAMEWORK_VERSION.rst diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index a2103f7..4ed0b2e 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -125,6 +125,9 @@ Variables that Provide Information /variable/CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR /variable/CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE /variable/CMAKE_VS_PLATFORM_TOOLSET_VERSION + /variable/CMAKE_VS_TARGET_FRAMEWORK_VERSION + /variable/CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER + /variable/CMAKE_VS_TARGET_FRAMEWORK_TARGETS_VERSION /variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION /variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM /variable/CMAKE_XCODE_BUILD_SYSTEM diff --git a/Help/variable/CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER.rst b/Help/variable/CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER.rst new file mode 100644 index 0000000..5ad5897 --- /dev/null +++ b/Help/variable/CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER.rst @@ -0,0 +1,13 @@ +CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER +------------------------------------ + +.. versionadded:: 3.22 + +Visual Studio target framework identifier. + +In some cases, the :ref:`Visual Studio Generators` may use an explicit value +for the MSBuild ``TargetFrameworkIdentifier`` setting in ``.csproj`` files. +CMake provides the chosen value in this variable. + +See also :variable:`CMAKE_VS_TARGET_FRAMEWORK_VERSION` and +:variable:`CMAKE_VS_TARGET_FRAMEWORK_TARGETS_VERSION`. diff --git a/Help/variable/CMAKE_VS_TARGET_FRAMEWORK_TARGETS_VERSION.rst b/Help/variable/CMAKE_VS_TARGET_FRAMEWORK_TARGETS_VERSION.rst new file mode 100644 index 0000000..8dcb3a7 --- /dev/null +++ b/Help/variable/CMAKE_VS_TARGET_FRAMEWORK_TARGETS_VERSION.rst @@ -0,0 +1,13 @@ +CMAKE_VS_TARGET_FRAMEWORK_TARGETS_VERSION +----------------------------------------- + +.. versionadded:: 3.22 + +Visual Studio target framework targets version. + +In some cases, the :ref:`Visual Studio Generators` may use an explicit value +for the MSBuild ``TargetFrameworkTargetsVersion`` setting in ``.csproj`` files. +CMake provides the chosen value in this variable. + +See also :variable:`CMAKE_VS_TARGET_FRAMEWORK_VERSION` and +:variable:`CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER`. diff --git a/Help/variable/CMAKE_VS_TARGET_FRAMEWORK_VERSION.rst b/Help/variable/CMAKE_VS_TARGET_FRAMEWORK_VERSION.rst new file mode 100644 index 0000000..5489f79 --- /dev/null +++ b/Help/variable/CMAKE_VS_TARGET_FRAMEWORK_VERSION.rst @@ -0,0 +1,17 @@ +CMAKE_VS_TARGET_FRAMEWORK_VERSION +--------------------------------- + +.. versionadded:: 3.22 + +Visual Studio target framework version. + +In some cases, the :ref:`Visual Studio Generators` may use an explicit value +for the MSBuild ``TargetFrameworkVersion`` setting in ``.csproj`` files. +CMake provides the chosen value in this variable. + +See the :variable:`CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION` variable +and :prop_tgt:`DOTNET_TARGET_FRAMEWORK_VERSION` target property to +specify custom ``TargetFrameworkVersion`` values for project targets. + +See also :variable:`CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER` and +:variable:`CMAKE_VS_TARGET_FRAMEWORK_TARGETS_VERSION`. diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index fa283fe..c62cb7d 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -421,6 +421,15 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS} if(CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR) set(id_ToolsetVCTargetsDir "${CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR}") endif() + if(CMAKE_VS_TARGET_FRAMEWORK_VERSION) + set(id_TargetFrameworkVersion "${CMAKE_VS_TARGET_FRAMEWORK_VERSION}") + endif() + if(CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER) + set(id_TargetFrameworkIdentifier "${CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER}") + endif() + if(CMAKE_VS_TARGET_FRAMEWORK_TARGETS_VERSION) + set(id_TargetFrameworkTargetsVersion "${CMAKE_VS_TARGET_FRAMEWORK_TARGETS_VERSION}") + endif() set(id_CustomGlobals "") foreach(pair IN LISTS CMAKE_VS_GLOBALS) if("${pair}" MATCHES "([^=]+)=(.*)$") diff --git a/Modules/CompilerId/VS-10.csproj.in b/Modules/CompilerId/VS-10.csproj.in index ed5e847..fba74ff 100644 --- a/Modules/CompilerId/VS-10.csproj.in +++ b/Modules/CompilerId/VS-10.csproj.in @@ -6,6 +6,9 @@ Win32Proj @id_system@ @id_system_version@ + @id_TargetFrameworkVersion@ + @id_TargetFrameworkIdentifier@ + @id_TargetFrameworkTargetsVersion@ @id_WindowsTargetPlatformVersion@ @id_WindowsSDKDesktopARMSupport@ diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index c11516d..6cab492 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -580,6 +580,13 @@ bool cmGlobalVisualStudio10Generator::InitializeWindowsCE(cmMakefile* mf) this->DefaultPlatformToolset = this->SelectWindowsCEToolset(); + if (this->GetVersion() == cmGlobalVisualStudioGenerator::VS12) { + // VS 12 .NET CF defaults to .NET framework 3.9 for Windows CE. + this->DefaultTargetFrameworkVersion = "v3.9"; + this->DefaultTargetFrameworkIdentifier = "WindowsEmbeddedCompact"; + this->DefaultTargetFrameworkTargetsVersion = "v8.0"; + } + return true; } diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 439d13e..1e45813 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -76,12 +76,48 @@ bool cmGlobalVisualStudio8Generator::SetGeneratorPlatform(std::string const& p, this->GeneratorPlatform = p; + // FIXME: Add CMAKE_GENERATOR_PLATFORM field to set the framework. + // For now, just report the generator's default, if any. + if (cm::optional const& targetFrameworkVersion = + this->GetTargetFrameworkVersion()) { + mf->AddDefinition("CMAKE_VS_TARGET_FRAMEWORK_VERSION", + *targetFrameworkVersion); + } + if (cm::optional const& targetFrameworkIdentifier = + this->GetTargetFrameworkIdentifier()) { + mf->AddDefinition("CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER", + *targetFrameworkIdentifier); + } + if (cm::optional const& targetFrameworkTargetsVersion = + this->GetTargetFrameworkTargetsVersion()) { + mf->AddDefinition("CMAKE_VS_TARGET_FRAMEWORK_TARGETS_VERSION", + *targetFrameworkTargetsVersion); + } + // The generator name does not contain the platform name, and so supports // explicit platform specification. We handled that above, so pass an // empty platform name to our base class implementation so it does not error. return this->cmGlobalVisualStudio7Generator::SetGeneratorPlatform("", mf); } +cm::optional const& +cmGlobalVisualStudio8Generator::GetTargetFrameworkVersion() const +{ + return this->DefaultTargetFrameworkVersion; +} + +cm::optional const& +cmGlobalVisualStudio8Generator::GetTargetFrameworkIdentifier() const +{ + return this->DefaultTargetFrameworkIdentifier; +} + +cm::optional const& +cmGlobalVisualStudio8Generator::GetTargetFrameworkTargetsVersion() const +{ + return this->DefaultTargetFrameworkTargetsVersion; +} + std::string cmGlobalVisualStudio8Generator::GetGenerateStampList() { return "generate.stamp.list"; diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h index 96e3553..b6ecdf0 100644 --- a/Source/cmGlobalVisualStudio8Generator.h +++ b/Source/cmGlobalVisualStudio8Generator.h @@ -2,6 +2,8 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #pragma once +#include + #include "cmGlobalVisualStudio71Generator.h" /** \class cmGlobalVisualStudio8Generator @@ -24,6 +26,10 @@ public: bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf) override; + cm::optional const& GetTargetFrameworkVersion() const; + cm::optional const& GetTargetFrameworkIdentifier() const; + cm::optional const& GetTargetFrameworkTargetsVersion() const; + /** * Override Configure and Generate to add the build-system check * target. @@ -76,4 +82,8 @@ protected: std::string Name; std::string WindowsCEVersion; + + cm::optional DefaultTargetFrameworkVersion; + cm::optional DefaultTargetFrameworkIdentifier; + cm::optional DefaultTargetFrameworkTargetsVersion; }; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index f765612..d2c49ae 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -507,12 +507,9 @@ void cmVisualStudio10TargetGenerator::Generate() } else if (cmValue tfVer = this->GeneratorTarget->GetProperty( "DOTNET_TARGET_FRAMEWORK_VERSION")) { targetFrameworkVersion = *tfVer; - } else if (this->ProjectType == csproj && - this->GlobalGenerator->TargetsWindowsCE() && - this->GlobalGenerator->GetVersion() == - cmGlobalVisualStudioGenerator::VS12) { - // VS12 .NETCF default to .NET framework 3.9 - targetFrameworkVersion = "v3.9"; + } else if (this->ProjectType == csproj) { + targetFrameworkVersion = + this->GlobalGenerator->GetTargetFrameworkVersion(); } if (this->ProjectType == vcxproj && this->GlobalGenerator->TargetsWindowsCE()) { @@ -527,16 +524,20 @@ void cmVisualStudio10TargetGenerator::Generate() if (cmValue tfId = this->GeneratorTarget->GetProperty( "VS_TARGET_FRAMEWORK_IDENTIFIER")) { targetFrameworkIdentifier = *tfId; - } else { - targetFrameworkIdentifier = "WindowsEmbeddedCompact"; } if (cmValue tfTargetsVer = this->GeneratorTarget->GetProperty( "VS_TARGET_FRAMEWORKS_TARGET_VERSION")) { targetFrameworkTargetsVersion = *tfTargetsVer; - } else { - targetFrameworkTargetsVersion = "v8.0"; } } + if (!targetFrameworkIdentifier) { + targetFrameworkIdentifier = + this->GlobalGenerator->GetTargetFrameworkIdentifier(); + } + if (!targetFrameworkTargetsVersion) { + targetFrameworkTargetsVersion = + this->GlobalGenerator->GetTargetFrameworkTargetsVersion(); + } } if (targetFramework) { if (targetFramework->find(';') != std::string::npos) { -- cgit v0.12 From d51246c6621aa5025e06fcea720930ae00e6f448 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 3 Nov 2021 14:34:58 -0400 Subject: VS: Default TargetFrameworkVersion to v4.7.2 for VS 2022 MSBuild defaults to v4.0 but VS 2022 does not install it anymore. Explicitly specify a newer framework version by default. Use a version that VS 2022 installs without selecting a separate component. Fixes: #22835 --- Source/cmGlobalVisualStudioVersionedGenerator.cxx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx index f27b2c4..b5a6b9f 100644 --- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx +++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx @@ -401,6 +401,12 @@ cmGlobalVisualStudioVersionedGenerator::cmGlobalVisualStudioVersionedGenerator( this->DefaultPlatformName = VSHostPlatformName(); this->DefaultPlatformToolsetHostArchitecture = VSHostArchitecture(); } + if (this->Version >= cmGlobalVisualStudioGenerator::VS17) { + // FIXME: Search for an existing framework? Under '%ProgramFiles(x86)%', + // see 'Reference Assemblies\Microsoft\Framework\.NETFramework'. + // Use a version installed by VS 2022 without a separate component. + this->DefaultTargetFrameworkVersion = "v4.7.2"; + } } bool cmGlobalVisualStudioVersionedGenerator::MatchesGeneratorName( -- cgit v0.12