summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2021-12-22 13:56:04 (GMT)
committerKitware Robot <kwrobot@kitware.com>2021-12-22 13:56:22 (GMT)
commit138aabfa9dfda15cabbc21a240aeacfa9bdcdec2 (patch)
tree9164c86e10d3d4570d1a333c898e0b808918b930
parent7a07d089b9bbb8336eebf1c54fe6e2a8aaff4533 (diff)
parent0eea32a376fc54b198fa4690ca57b829a2d14baa (diff)
downloadCMake-138aabfa9dfda15cabbc21a240aeacfa9bdcdec2.zip
CMake-138aabfa9dfda15cabbc21a240aeacfa9bdcdec2.tar.gz
CMake-138aabfa9dfda15cabbc21a240aeacfa9bdcdec2.tar.bz2
Merge topic 'vs-csharp-dotnet-sdk'
0eea32a376 VS: Add DOTNET_SDK property to generate SDK-style C# projects a450cc9533 VS: Set ResolveNugetPackages to false for ALL_BUILD and ZERO_CHECK fa76e5d194 cmVisualStudio10TargetGenerator: Factor out helper for classic MSBuild project Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !6634
-rw-r--r--Auxiliary/vim/syntax/cmake.vim2
-rw-r--r--Help/manual/cmake-properties.7.rst1
-rw-r--r--Help/manual/cmake-variables.7.rst1
-rw-r--r--Help/prop_tgt/DOTNET_SDK.rst25
-rw-r--r--Help/release/dev/vs-csharp-dotnet-sdk.rst9
-rw-r--r--Help/variable/CMAKE_DOTNET_SDK.rst9
-rw-r--r--Source/cmGeneratorTarget.cxx5
-rw-r--r--Source/cmGeneratorTarget.h2
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx10
-rw-r--r--Source/cmTarget.cxx4
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx244
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h10
-rw-r--r--Tests/RunCMake/CMakeLists.txt4
-rw-r--r--Tests/RunCMake/VsDotnetSdk/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/VsDotnetSdk/DotnetSdkVariables-check.cmake52
-rw-r--r--Tests/RunCMake/VsDotnetSdk/DotnetSdkVariables.cmake14
-rw-r--r--Tests/RunCMake/VsDotnetSdk/RunCMakeTest.cmake17
-rw-r--r--Tests/RunCMake/VsDotnetSdk/VsDotnetSdk.cmake18
-rw-r--r--Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsSource-result.txt0
-rw-r--r--Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsSource-stderr.txt7
-rw-r--r--Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsSource.cmake15
-rw-r--r--Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsTarget-result.txt0
-rw-r--r--Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsTarget-stderr.txt7
-rw-r--r--Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsTarget.cmake12
-rw-r--r--Tests/RunCMake/VsDotnetSdk/csharponly.cs11
-rw-r--r--Tests/RunCMake/VsDotnetSdk/lib1.cs10
26 files changed, 439 insertions, 53 deletions
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index 52330f7..c6c5d23 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -152,6 +152,7 @@ syn keyword cmakeProperty contained
\ DISABLED
\ DISABLED_FEATURES
\ DISABLE_PRECOMPILE_HEADERS
+ \ DOTNET_SDK
\ DOTNET_TARGET_FRAMEWORK
\ DOTNET_TARGET_FRAMEWORK_VERSION
\ ECLIPSE_EXTRA_CPROJECT_CONTENTS
@@ -1001,6 +1002,7 @@ syn keyword cmakeVariable contained
\ CMAKE_DIRECTORY_LABELS
\ CMAKE_DISABLE_PRECOMPILE_HEADERS
\ CMAKE_DL_LIBS
+ \ CMAKE_DOTNET_SDK
\ CMAKE_DOTNET_TARGET_FRAMEWORK
\ CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION
\ CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 8db7161..ddb917a 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -191,6 +191,7 @@ Properties on Targets
/prop_tgt/DEPLOYMENT_REMOTE_DIRECTORY
/prop_tgt/DEPRECATION
/prop_tgt/DISABLE_PRECOMPILE_HEADERS
+ /prop_tgt/DOTNET_SDK
/prop_tgt/DOTNET_TARGET_FRAMEWORK
/prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION
/prop_tgt/EchoString
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 253ebc4..51b092f 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -49,6 +49,7 @@ Variables that Provide Information
/variable/CMAKE_DEBUG_TARGET_PROPERTIES
/variable/CMAKE_DIRECTORY_LABELS
/variable/CMAKE_DL_LIBS
+ /variable/CMAKE_DOTNET_SDK
/variable/CMAKE_DOTNET_TARGET_FRAMEWORK
/variable/CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION
/variable/CMAKE_EDIT_COMMAND
diff --git a/Help/prop_tgt/DOTNET_SDK.rst b/Help/prop_tgt/DOTNET_SDK.rst
new file mode 100644
index 0000000..ca1dcac
--- /dev/null
+++ b/Help/prop_tgt/DOTNET_SDK.rst
@@ -0,0 +1,25 @@
+DOTNET_SDK
+----------
+
+.. versionadded:: 3.23
+
+Specify the .NET SDK for C# projects. For example: ``Microsoft.NET.Sdk``.
+
+This property tells :ref:`Visual Studio Generators` for VS 2019 and
+above to generate a .NET SDK-style project using the specified SDK.
+The property is meaningful only to these generators, and only in C#
+targets. It is ignored for C++ projects, even if they are managed
+(e.g. using :prop_tgt:`COMMON_LANGUAGE_RUNTIME`).
+
+This property must be a non-empty string to generate .NET SDK-style projects.
+CMake does not perform any validations for the value of the property.
+
+This property may be initialized for all targets using the
+:variable:`CMAKE_DOTNET_SDK` variable.
+
+.. note::
+
+ The :ref:`Visual Studio Generators` in this version of CMake have not
+ yet learned to support :command:`add_custom_command` in .NET SDK-style
+ projects. It is currently an error to attach a custom command to a
+ target with the ``DOTNET_SDK`` property set.
diff --git a/Help/release/dev/vs-csharp-dotnet-sdk.rst b/Help/release/dev/vs-csharp-dotnet-sdk.rst
new file mode 100644
index 0000000..cc0ebe4
--- /dev/null
+++ b/Help/release/dev/vs-csharp-dotnet-sdk.rst
@@ -0,0 +1,9 @@
+vs-csharp-dotnet-sdk
+--------------------
+
+* The :ref:`Visual Studio Generators` for VS 2019 and above learned to
+ support .NET SDK-style project files (``.csproj``) for C# projects.
+ See the :prop_tgt:`DOTNET_SDK` target property and corresponding
+ :variable:`CMAKE_DOTNET_SDK` variable.
+ However, this version of CMake does not yet support using
+ :command:`add_custom_command` in .NET SDK-style projects.
diff --git a/Help/variable/CMAKE_DOTNET_SDK.rst b/Help/variable/CMAKE_DOTNET_SDK.rst
new file mode 100644
index 0000000..dc8806a
--- /dev/null
+++ b/Help/variable/CMAKE_DOTNET_SDK.rst
@@ -0,0 +1,9 @@
+CMAKE_DOTNET_SDK
+----------------
+
+.. versionadded:: 3.23
+
+Default value for :prop_tgt:`DOTNET_SDK` property of targets.
+
+This variable is used to initialize the :prop_tgt:`DOTNET_SDK`
+property on all targets. See that target property for additional information.
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index b651104..421e136 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -7842,6 +7842,11 @@ bool cmGeneratorTarget::IsCSharpOnly() const
return languages.size() == 1 && languages.count("CSharp") > 0;
}
+bool cmGeneratorTarget::IsDotNetSdkTarget() const
+{
+ return !this->GetProperty("DOTNET_SDK").IsEmpty();
+}
+
void cmGeneratorTarget::ComputeLinkImplementationLanguages(
const std::string& config, cmOptionalLinkImplementation& impl) const
{
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 5f317c4..71212c4 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -436,6 +436,8 @@ public:
bool IsCSharpOnly() const;
+ bool IsDotNetSdkTarget() const;
+
void GetObjectLibrariesCMP0026(
std::vector<cmGeneratorTarget*>& objlibs) const;
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index b3f8d90..c72b109 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -373,8 +373,16 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
this->IsPartOfDefaultBuild(configs, projectTargets, target);
cmValue vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
if (vcprojName) {
+ std::string mapping;
+
+ // On VS 19 and above, always map .NET SDK projects to "Any CPU".
+ if (target->IsDotNetSdkTarget() &&
+ this->GetVersion() >= VSVersion::VS16 &&
+ !this->IsReservedTarget(target->GetName())) {
+ mapping = "Any CPU";
+ }
this->WriteProjectConfigurations(fout, *vcprojName, *target, configs,
- configsPartOfDefaultBuild);
+ configsPartOfDefaultBuild, mapping);
}
}
}
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index c03a252..c5703a1 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -529,6 +529,10 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
this->impl->PolicyMap.Set(cmPolicies::CMP0022, cmPolicies::NEW);
}
+ if (!this->IsImported()) {
+ initProp("DOTNET_SDK");
+ }
+
if (this->impl->TargetType <= cmStateEnums::GLOBAL_TARGET) {
initProp("DOTNET_TARGET_FRAMEWORK");
initProp("DOTNET_TARGET_FRAMEWORK_VERSION");
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 9523038..84044e4 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -405,6 +405,27 @@ void cmVisualStudio10TargetGenerator::Generate()
// Write the encoding header into the file
char magic[] = { char(0xEF), char(0xBB), char(0xBF) };
BuildFileStream.write(magic, 3);
+
+ if (this->Managed && this->ProjectType == VsProjectType::csproj &&
+ this->GeneratorTarget->IsDotNetSdkTarget() &&
+ this->GlobalGenerator->GetVersion() >=
+ cmGlobalVisualStudioGenerator::VS16) {
+ this->WriteSdkStyleProjectFile(BuildFileStream);
+ } else {
+ this->WriteClassicMsBuildProjectFile(BuildFileStream);
+ }
+
+ if (BuildFileStream.Close()) {
+ this->GlobalGenerator->FileReplacedDuringGenerate(PathToProjectFile);
+ }
+
+ // The groups are stored in a separate file for VS 10
+ this->WriteGroups();
+}
+
+void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
+ cmGeneratedFileStream& BuildFileStream)
+{
BuildFileStream << "<?xml version=\"1.0\" encoding=\""
<< this->GlobalGenerator->Encoding() << "\"?>";
{
@@ -447,14 +468,27 @@ void cmVisualStudio10TargetGenerator::Generate()
e1.Element("PreferredToolArchitecture", hostArch);
}
+ // ALL_BUILD and ZERO_CHECK projects transitively include
+ // Microsoft.Common.CurrentVersion.targets which triggers Target
+ // ResolveNugetPackageAssets when SDK-style targets are in the project.
+ // However, these projects have no nuget packages to reference and the
+ // build fails.
+ // Setting ResolveNugetPackages to false skips this target and the build
+ // succeeds.
+ cm::string_view targetName{ this->GeneratorTarget->GetName() };
+ if (targetName == "ALL_BUILD" ||
+ targetName == CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
+ Elem e1(e0, "PropertyGroup");
+ e1.Element("ResolveNugetPackages", "false");
+ }
+
if (this->ProjectType != VsProjectType::csproj) {
this->WriteProjectConfigurations(e0);
}
{
Elem e1(e0, "PropertyGroup");
- e1.Attribute("Label", "Globals");
- e1.Element("ProjectGuid", "{" + this->GUID + "}");
+ this->WriteCommonPropertyGroupGlobals(e1);
if ((this->MSTools || this->Android) &&
this->GeneratorTarget->IsInBuildSystem()) {
@@ -462,16 +496,6 @@ void cmVisualStudio10TargetGenerator::Generate()
this->VerifyNecessaryFiles();
}
- cmValue vsProjectTypes =
- this->GeneratorTarget->GetProperty("VS_GLOBAL_PROJECT_TYPES");
- if (vsProjectTypes) {
- const char* tagName = "ProjectTypes";
- if (this->ProjectType == VsProjectType::csproj) {
- tagName = "ProjectTypeGuids";
- }
- e1.Element(tagName, *vsProjectTypes);
- }
-
cmValue vsProjectName =
this->GeneratorTarget->GetProperty("VS_SCC_PROJECTNAME");
cmValue vsLocalPath =
@@ -495,24 +519,6 @@ void cmVisualStudio10TargetGenerator::Generate()
e1.Element("WinMDAssembly", "true");
}
- cmValue vsGlobalKeyword =
- this->GeneratorTarget->GetProperty("VS_GLOBAL_KEYWORD");
- if (!vsGlobalKeyword) {
- if (this->GlobalGenerator->TargetsAndroid()) {
- e1.Element("Keyword", "Android");
- } else {
- e1.Element("Keyword", "Win32Proj");
- }
- } else {
- e1.Element("Keyword", *vsGlobalKeyword);
- }
-
- cmValue vsGlobalRootNamespace =
- this->GeneratorTarget->GetProperty("VS_GLOBAL_ROOTNAMESPACE");
- if (vsGlobalRootNamespace) {
- e1.Element("RootNamespace", *vsGlobalRootNamespace);
- }
-
e1.Element("Platform", this->Platform);
cmValue projLabel = this->GeneratorTarget->GetProperty("PROJECT_LABEL");
e1.Element("ProjectName", projLabel ? projLabel : this->Name);
@@ -602,24 +608,6 @@ void cmVisualStudio10TargetGenerator::Generate()
e1.Element("VCTargetsPath", vcTargetsPath);
}
- std::vector<std::string> keys = this->GeneratorTarget->GetPropertyKeys();
- for (std::string const& keyIt : keys) {
- static const cm::string_view prefix = "VS_GLOBAL_";
- if (!cmHasPrefix(keyIt, prefix))
- continue;
- cm::string_view globalKey =
- cm::string_view(keyIt).substr(prefix.length());
- // Skip invalid or separately-handled properties.
- if (globalKey.empty() || globalKey == "PROJECT_TYPES" ||
- globalKey == "ROOTNAMESPACE" || globalKey == "KEYWORD") {
- continue;
- }
- cmValue value = this->GeneratorTarget->GetProperty(keyIt);
- if (!value)
- continue;
- e1.Element(globalKey, *value);
- }
-
if (this->Managed) {
if (this->LocalGenerator->GetVersion() >=
cmGlobalVisualStudioGenerator::VS17) {
@@ -839,13 +827,165 @@ void cmVisualStudio10TargetGenerator::Generate()
}
}
}
+}
- if (BuildFileStream.Close()) {
- this->GlobalGenerator->FileReplacedDuringGenerate(PathToProjectFile);
+void cmVisualStudio10TargetGenerator::WriteSdkStyleProjectFile(
+ cmGeneratedFileStream& BuildFileStream)
+{
+ if (!this->Managed || this->ProjectType != VsProjectType::csproj ||
+ !this->GeneratorTarget->IsDotNetSdkTarget()) {
+ std::string message = "The target \"" + this->GeneratorTarget->GetName() +
+ "\" is not eligible for .Net SDK style project.";
+ this->Makefile->IssueMessage(MessageType::INTERNAL_ERROR, message);
+ return;
}
- // The groups are stored in a separate file for VS 10
- this->WriteGroups();
+ if (this->HasCustomCommands()) {
+ std::string message = "The target \"" + this->GeneratorTarget->GetName() +
+ "\" does not currently support add_custom_command as the Visual Studio "
+ "generators have not yet learned how to generate custom commands in "
+ ".Net SDK-style projects.";
+ this->Makefile->IssueMessage(MessageType::FATAL_ERROR, message);
+ return;
+ }
+
+ Elem e0(BuildFileStream, "Project");
+ e0.Attribute("Sdk", *this->GeneratorTarget->GetProperty("DOTNET_SDK"));
+
+ {
+ Elem e1(e0, "PropertyGroup");
+ this->WriteCommonPropertyGroupGlobals(e1);
+
+ e1.Element("EnableDefaultItems", "false");
+ // Disable the project upgrade prompt that is displayed the first time a
+ // project using an older toolset version is opened in a newer version
+ // of the IDE.
+ e1.Element("VCProjectUpgraderObjectName", "NoUpgrade");
+ e1.Element("ManagedAssembly", "true");
+
+ cmValue targetFramework =
+ this->GeneratorTarget->GetProperty("DOTNET_TARGET_FRAMEWORK");
+ if (targetFramework) {
+ if (targetFramework->find(';') != std::string::npos) {
+ e1.Element("TargetFrameworks", *targetFramework);
+ } else {
+ e1.Element("TargetFramework", *targetFramework);
+ }
+ } else {
+ e1.Element("TargetFramework", "net5.0");
+ }
+
+ std::string outputType;
+ switch (this->GeneratorTarget->GetType()) {
+ case cmStateEnums::OBJECT_LIBRARY:
+ case cmStateEnums::STATIC_LIBRARY:
+ case cmStateEnums::MODULE_LIBRARY:
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Target \"", this->GeneratorTarget->GetName(),
+ "\" is of a type not supported for managed binaries."));
+ return;
+ case cmStateEnums::SHARED_LIBRARY:
+ outputType = "Library";
+ break;
+ case cmStateEnums::EXECUTABLE: {
+ auto const win32 =
+ this->GeneratorTarget->GetSafeProperty("WIN32_EXECUTABLE");
+ if (win32.find("$<") != std::string::npos) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Target \"", this->GeneratorTarget->GetName(),
+ "\" has a generator expression in its WIN32_EXECUTABLE "
+ "property. This is not supported on managed "
+ "executables."));
+ return;
+ }
+ outputType = "Exe";
+ } break;
+ case cmStateEnums::UTILITY:
+ case cmStateEnums::INTERFACE_LIBRARY:
+ case cmStateEnums::GLOBAL_TARGET:
+ outputType = "Utility";
+ break;
+ case cmStateEnums::UNKNOWN_LIBRARY:
+ break;
+ }
+ e1.Element("OutputType", outputType);
+ }
+
+ this->WriteDotNetDocumentationFile(e0);
+ this->WriteAllSources(e0);
+ this->WritePackageReferences(e0);
+ this->WriteProjectReferences(e0);
+}
+
+void cmVisualStudio10TargetGenerator::WriteCommonPropertyGroupGlobals(Elem& e1)
+{
+ e1.Attribute("Label", "Globals");
+ e1.Element("ProjectGuid", "{" + this->GUID + "}");
+
+ cmValue vsProjectTypes =
+ this->GeneratorTarget->GetProperty("VS_GLOBAL_PROJECT_TYPES");
+ if (vsProjectTypes) {
+ const char* tagName = "ProjectTypes";
+ if (this->ProjectType == VsProjectType::csproj) {
+ tagName = "ProjectTypeGuids";
+ }
+ e1.Element(tagName, *vsProjectTypes);
+ }
+
+ cmValue vsGlobalKeyword =
+ this->GeneratorTarget->GetProperty("VS_GLOBAL_KEYWORD");
+ if (!vsGlobalKeyword) {
+ if (this->GlobalGenerator->TargetsAndroid()) {
+ e1.Element("Keyword", "Android");
+ } else {
+ e1.Element("Keyword", "Win32Proj");
+ }
+ } else {
+ e1.Element("Keyword", *vsGlobalKeyword);
+ }
+
+ cmValue vsGlobalRootNamespace =
+ this->GeneratorTarget->GetProperty("VS_GLOBAL_ROOTNAMESPACE");
+ if (vsGlobalRootNamespace) {
+ e1.Element("RootNamespace", *vsGlobalRootNamespace);
+ }
+
+ std::vector<std::string> keys = this->GeneratorTarget->GetPropertyKeys();
+ for (std::string const& keyIt : keys) {
+ static const cm::string_view prefix = "VS_GLOBAL_";
+ if (!cmHasPrefix(keyIt, prefix))
+ continue;
+ cm::string_view globalKey = cm::string_view(keyIt).substr(prefix.length());
+ // Skip invalid or separately-handled properties.
+ if (globalKey.empty() || globalKey == "PROJECT_TYPES" ||
+ globalKey == "ROOTNAMESPACE" || globalKey == "KEYWORD") {
+ continue;
+ }
+ cmValue value = this->GeneratorTarget->GetProperty(keyIt);
+ if (!value)
+ continue;
+ e1.Element(globalKey, *value);
+ }
+}
+
+bool cmVisualStudio10TargetGenerator::HasCustomCommands() const
+{
+ if (!this->GeneratorTarget->GetPreBuildCommands().empty() ||
+ !this->GeneratorTarget->GetPreLinkCommands().empty() ||
+ !this->GeneratorTarget->GetPostBuildCommands().empty()) {
+ return true;
+ }
+
+ for (cmGeneratorTarget::AllConfigSource const& si :
+ this->GeneratorTarget->GetAllConfigSources()) {
+ if (si.Source->GetCustomCommand()) {
+ return true;
+ }
+ }
+
+ return false;
}
void cmVisualStudio10TargetGenerator::WritePackageReferences(Elem& e0)
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index ec6362f..37b8dfd 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -18,6 +18,7 @@
class cmComputeLinkInformation;
class cmCustomCommand;
class cmCustomCommandGenerator;
+class cmGeneratedFileStream;
class cmGlobalVisualStudio10Generator;
class cmLocalVisualStudio10Generator;
class cmMakefile;
@@ -260,6 +261,15 @@ private:
void ClassifyAllConfigSources();
void ClassifyAllConfigSource(cmGeneratorTarget::AllConfigSource const& acs);
+ // .Net SDK-stype project variable and helper functions
+ void WriteClassicMsBuildProjectFile(cmGeneratedFileStream& BuildFileStream);
+ void WriteSdkStyleProjectFile(cmGeneratedFileStream& BuildFileStream);
+
+ void WriteCommonPropertyGroupGlobals(
+ cmVisualStudio10TargetGenerator::Elem& e1);
+
+ bool HasCustomCommands() const;
+
std::unordered_map<std::string, ConfigToSettings> ParsedToolTargetSettings;
bool PropertyIsSameInAllConfigs(const ConfigToSettings& toolSettings,
const std::string& propName);
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 2363d7d..f0457a8 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -616,6 +616,10 @@ if("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([^9]|9[0-9])")
endif()
endif()
+if(CMAKE_GENERATOR MATCHES "^Visual Studio (1[6-9]|[2-9][0-9])")
+ add_RunCMake_test(VsDotnetSdk)
+endif()
+
if(XCODE_VERSION)
add_RunCMake_test(XcodeProject -DXCODE_VERSION=${XCODE_VERSION})
add_RunCMake_test(XcodeProject-Embed -DXCODE_VERSION=${XCODE_VERSION})
diff --git a/Tests/RunCMake/VsDotnetSdk/CMakeLists.txt b/Tests/RunCMake/VsDotnetSdk/CMakeLists.txt
new file mode 100644
index 0000000..e597708
--- /dev/null
+++ b/Tests/RunCMake/VsDotnetSdk/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.22.0)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/VsDotnetSdk/DotnetSdkVariables-check.cmake b/Tests/RunCMake/VsDotnetSdk/DotnetSdkVariables-check.cmake
new file mode 100644
index 0000000..7a5cd1d
--- /dev/null
+++ b/Tests/RunCMake/VsDotnetSdk/DotnetSdkVariables-check.cmake
@@ -0,0 +1,52 @@
+set(files foo.csproj bar.csproj baz.csproj)
+
+set(inLib1 FALSE)
+set(dotnetSdkInLib1 FALSE)
+
+set(inLib2 FALSE)
+set(dotnetSdkWebInLib2 FALSE)
+
+set(inLib3 FALSE)
+set(classicProjInLib3 FALSE)
+
+foreach(file ${files})
+ set(csProjectFile ${RunCMake_TEST_BINARY_DIR}/${file})
+
+ if(NOT EXISTS "${csProjectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${csProjectFile} does not exist.")
+ return()
+ endif()
+
+ file(STRINGS "${csProjectFile}" lines)
+
+ foreach(line IN LISTS lines)
+ if(NOT inLib1)
+ if(line MATCHES "<Project Sdk=\"Microsoft\.NET\.Sdk\">")
+ set(dotnetSdkInLib1 TRUE)
+ set(inLib1 TRUE)
+ endif()
+ elseif(NOT inLib2)
+ if(line MATCHES "<Project Sdk=\"Microsoft\.NET\.Sdk\.Web\">")
+ set(dotnetSdkWebInLib2 TRUE)
+ set(inLib2 TRUE)
+ endif()
+ elseif(NOT inLib3)
+ if(line MATCHES "<Project DefaultTargets=\"Build\" ToolsVersion=\"")
+ set(classicProjInLib3 TRUE)
+ set(inLib3 TRUE)
+ endif()
+ endif()
+ endforeach()
+endforeach()
+
+if(NOT dotnetSdkInLib1)
+ set(RunCMake_TEST_FAILED ".Net SDK not set correctly.")
+endif()
+
+if(NOT dotnetSdkWebInLib2)
+ set(RunCMake_TEST_FAILED ".Net Web SDK not set correctly.")
+endif()
+
+if(NOT classicProjInLib3)
+ set(RunCMake_TEST_FAILED "Empty DOTNET_SDK doesn't build Classic project.")
+endif()
diff --git a/Tests/RunCMake/VsDotnetSdk/DotnetSdkVariables.cmake b/Tests/RunCMake/VsDotnetSdk/DotnetSdkVariables.cmake
new file mode 100644
index 0000000..f080edd
--- /dev/null
+++ b/Tests/RunCMake/VsDotnetSdk/DotnetSdkVariables.cmake
@@ -0,0 +1,14 @@
+enable_language(CSharp)
+
+if(NOT CMAKE_CSharp_COMPILER)
+ return()
+endif()
+
+set(CMAKE_DOTNET_SDK "Microsoft.NET.Sdk")
+add_library(foo SHARED lib1.cs)
+
+set(CMAKE_DOTNET_SDK "Microsoft.NET.Sdk.Web")
+add_library(bar SHARED lib1.cs)
+
+set(CMAKE_DOTNET_SDK "")
+add_library(baz SHARED lib1.cs)
diff --git a/Tests/RunCMake/VsDotnetSdk/RunCMakeTest.cmake b/Tests/RunCMake/VsDotnetSdk/RunCMakeTest.cmake
new file mode 100644
index 0000000..b174c25
--- /dev/null
+++ b/Tests/RunCMake/VsDotnetSdk/RunCMakeTest.cmake
@@ -0,0 +1,17 @@
+cmake_policy(SET CMP0053 NEW)
+include(RunCMake)
+
+run_cmake(VsDotnetSdkCustomCommandsTarget)
+run_cmake(VsDotnetSdkCustomCommandsSource)
+run_cmake(DotnetSdkVariables)
+
+function(run_VsDotnetSdk)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/VsDotnetSdk-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ run_cmake(VsDotnetSdk)
+ set(build_flags /restore)
+ run_cmake_command(VsDotnetSdk-build ${CMAKE_COMMAND} --build . -- ${build_flags})
+endfunction()
+run_VsDotnetSdk()
diff --git a/Tests/RunCMake/VsDotnetSdk/VsDotnetSdk.cmake b/Tests/RunCMake/VsDotnetSdk/VsDotnetSdk.cmake
new file mode 100644
index 0000000..60066ab
--- /dev/null
+++ b/Tests/RunCMake/VsDotnetSdk/VsDotnetSdk.cmake
@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 3.22)
+
+# a simple CSharp only test case
+project (DotNetSdk CSharp)
+
+set(CMAKE_DOTNET_TARGET_FRAMEWORK net472)
+set(CMAKE_DOTNET_SDK "Microsoft.NET.Sdk")
+
+add_library(dotNetSdkLib1 SHARED lib1.cs)
+set_target_properties(dotNetSdkLib1
+ PROPERTIES
+ VS_GLOBAL_RuntimeIdentifier win10-x64)
+
+add_executable(DotNetSdk csharponly.cs)
+target_link_libraries(DotNetSdk dotNetSdkLib1)
+set_target_properties(DotNetSdk
+ PROPERTIES
+ VS_GLOBAL_RuntimeIdentifier win10-x64)
diff --git a/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsSource-result.txt b/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsSource-result.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsSource-result.txt
diff --git a/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsSource-stderr.txt b/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsSource-stderr.txt
new file mode 100644
index 0000000..90af627
--- /dev/null
+++ b/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsSource-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error in CMakeLists.txt:
+ The target "foo" does not currently support add_custom_command as the
+ Visual Studio generators have not yet learned how to generate custom
+ commands in .Net SDK-style projects.
+
+
+CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsSource.cmake b/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsSource.cmake
new file mode 100644
index 0000000..af18946
--- /dev/null
+++ b/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsSource.cmake
@@ -0,0 +1,15 @@
+enable_language(CSharp)
+
+if(NOT CMAKE_CSharp_COMPILER)
+ return()
+endif()
+
+set(CMAKE_DOTNET_SDK "Microsoft.NET.Sdk")
+add_custom_command(
+ OUTPUT bar.cs
+ COMMAND copy /A ${CMAKE_CURRENT_SOURCE_DIR}/lib1.cs
+ bar.cs
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/lib1.cs
+ VERBATIM)
+
+add_library(foo SHARED bar.cs)
diff --git a/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsTarget-result.txt b/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsTarget-result.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsTarget-result.txt
diff --git a/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsTarget-stderr.txt b/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsTarget-stderr.txt
new file mode 100644
index 0000000..90af627
--- /dev/null
+++ b/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsTarget-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error in CMakeLists.txt:
+ The target "foo" does not currently support add_custom_command as the
+ Visual Studio generators have not yet learned how to generate custom
+ commands in .Net SDK-style projects.
+
+
+CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsTarget.cmake b/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsTarget.cmake
new file mode 100644
index 0000000..f5cd317
--- /dev/null
+++ b/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkCustomCommandsTarget.cmake
@@ -0,0 +1,12 @@
+enable_language(CSharp)
+
+if(NOT CMAKE_CSharp_COMPILER)
+ return()
+endif()
+
+set(CMAKE_DOTNET_SDK "Microsoft.NET.Sdk")
+add_library(foo SHARED lib1.cs)
+add_custom_command(TARGET foo
+ PRE_BUILD
+ COMMAND echo "This shouldn't happen!"
+ VERBATIM)
diff --git a/Tests/RunCMake/VsDotnetSdk/csharponly.cs b/Tests/RunCMake/VsDotnetSdk/csharponly.cs
new file mode 100644
index 0000000..f02e8a3
--- /dev/null
+++ b/Tests/RunCMake/VsDotnetSdk/csharponly.cs
@@ -0,0 +1,11 @@
+namespace CSharpOnly
+{
+ class CSharpOnly
+ {
+ public static void Main(string[] args)
+ {
+ int val = Lib1.getResult();
+ return;
+ }
+ }
+}
diff --git a/Tests/RunCMake/VsDotnetSdk/lib1.cs b/Tests/RunCMake/VsDotnetSdk/lib1.cs
new file mode 100644
index 0000000..7a7ae10
--- /dev/null
+++ b/Tests/RunCMake/VsDotnetSdk/lib1.cs
@@ -0,0 +1,10 @@
+namespace CSharpOnly
+{
+ public class Lib1
+ {
+ public static int getResult()
+ {
+ return 23;
+ }
+ }
+}