diff options
author | Brad King <brad.king@kitware.com> | 2021-12-22 13:56:04 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2021-12-22 13:56:22 (GMT) |
commit | 138aabfa9dfda15cabbc21a240aeacfa9bdcdec2 (patch) | |
tree | 9164c86e10d3d4570d1a333c898e0b808918b930 /Source/cmVisualStudio10TargetGenerator.cxx | |
parent | 7a07d089b9bbb8336eebf1c54fe6e2a8aaff4533 (diff) | |
parent | 0eea32a376fc54b198fa4690ca57b829a2d14baa (diff) | |
download | CMake-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
Diffstat (limited to 'Source/cmVisualStudio10TargetGenerator.cxx')
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.cxx | 244 |
1 files changed, 192 insertions, 52 deletions
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) |