Merge topic 'vs-csharp-dotnet-sdk'
0eea32a376
VS: Add DOTNET_SDK property to generate SDK-style C# projectsa450cc9533
VS: Set ResolveNugetPackages to false for ALL_BUILD and ZERO_CHECKfa76e5d194
cmVisualStudio10TargetGenerator: Factor out helper for classic MSBuild project Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !6634
This commit is contained in:
commit
138aabfa9d
@ -152,6 +152,7 @@ syn keyword cmakeProperty contained
|
|||||||
\ DISABLED
|
\ DISABLED
|
||||||
\ DISABLED_FEATURES
|
\ DISABLED_FEATURES
|
||||||
\ DISABLE_PRECOMPILE_HEADERS
|
\ DISABLE_PRECOMPILE_HEADERS
|
||||||
|
\ DOTNET_SDK
|
||||||
\ DOTNET_TARGET_FRAMEWORK
|
\ DOTNET_TARGET_FRAMEWORK
|
||||||
\ DOTNET_TARGET_FRAMEWORK_VERSION
|
\ DOTNET_TARGET_FRAMEWORK_VERSION
|
||||||
\ ECLIPSE_EXTRA_CPROJECT_CONTENTS
|
\ ECLIPSE_EXTRA_CPROJECT_CONTENTS
|
||||||
@ -1001,6 +1002,7 @@ syn keyword cmakeVariable contained
|
|||||||
\ CMAKE_DIRECTORY_LABELS
|
\ CMAKE_DIRECTORY_LABELS
|
||||||
\ CMAKE_DISABLE_PRECOMPILE_HEADERS
|
\ CMAKE_DISABLE_PRECOMPILE_HEADERS
|
||||||
\ CMAKE_DL_LIBS
|
\ CMAKE_DL_LIBS
|
||||||
|
\ CMAKE_DOTNET_SDK
|
||||||
\ CMAKE_DOTNET_TARGET_FRAMEWORK
|
\ CMAKE_DOTNET_TARGET_FRAMEWORK
|
||||||
\ CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION
|
\ CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION
|
||||||
\ CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES
|
\ CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES
|
||||||
|
@ -191,6 +191,7 @@ Properties on Targets
|
|||||||
/prop_tgt/DEPLOYMENT_REMOTE_DIRECTORY
|
/prop_tgt/DEPLOYMENT_REMOTE_DIRECTORY
|
||||||
/prop_tgt/DEPRECATION
|
/prop_tgt/DEPRECATION
|
||||||
/prop_tgt/DISABLE_PRECOMPILE_HEADERS
|
/prop_tgt/DISABLE_PRECOMPILE_HEADERS
|
||||||
|
/prop_tgt/DOTNET_SDK
|
||||||
/prop_tgt/DOTNET_TARGET_FRAMEWORK
|
/prop_tgt/DOTNET_TARGET_FRAMEWORK
|
||||||
/prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION
|
/prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION
|
||||||
/prop_tgt/EchoString
|
/prop_tgt/EchoString
|
||||||
|
@ -49,6 +49,7 @@ Variables that Provide Information
|
|||||||
/variable/CMAKE_DEBUG_TARGET_PROPERTIES
|
/variable/CMAKE_DEBUG_TARGET_PROPERTIES
|
||||||
/variable/CMAKE_DIRECTORY_LABELS
|
/variable/CMAKE_DIRECTORY_LABELS
|
||||||
/variable/CMAKE_DL_LIBS
|
/variable/CMAKE_DL_LIBS
|
||||||
|
/variable/CMAKE_DOTNET_SDK
|
||||||
/variable/CMAKE_DOTNET_TARGET_FRAMEWORK
|
/variable/CMAKE_DOTNET_TARGET_FRAMEWORK
|
||||||
/variable/CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION
|
/variable/CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION
|
||||||
/variable/CMAKE_EDIT_COMMAND
|
/variable/CMAKE_EDIT_COMMAND
|
||||||
|
25
Help/prop_tgt/DOTNET_SDK.rst
Normal file
25
Help/prop_tgt/DOTNET_SDK.rst
Normal file
@ -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.
|
9
Help/release/dev/vs-csharp-dotnet-sdk.rst
Normal file
9
Help/release/dev/vs-csharp-dotnet-sdk.rst
Normal file
@ -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.
|
9
Help/variable/CMAKE_DOTNET_SDK.rst
Normal file
9
Help/variable/CMAKE_DOTNET_SDK.rst
Normal file
@ -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.
|
@ -7842,6 +7842,11 @@ bool cmGeneratorTarget::IsCSharpOnly() const
|
|||||||
return languages.size() == 1 && languages.count("CSharp") > 0;
|
return languages.size() == 1 && languages.count("CSharp") > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cmGeneratorTarget::IsDotNetSdkTarget() const
|
||||||
|
{
|
||||||
|
return !this->GetProperty("DOTNET_SDK").IsEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
void cmGeneratorTarget::ComputeLinkImplementationLanguages(
|
void cmGeneratorTarget::ComputeLinkImplementationLanguages(
|
||||||
const std::string& config, cmOptionalLinkImplementation& impl) const
|
const std::string& config, cmOptionalLinkImplementation& impl) const
|
||||||
{
|
{
|
||||||
|
@ -436,6 +436,8 @@ public:
|
|||||||
|
|
||||||
bool IsCSharpOnly() const;
|
bool IsCSharpOnly() const;
|
||||||
|
|
||||||
|
bool IsDotNetSdkTarget() const;
|
||||||
|
|
||||||
void GetObjectLibrariesCMP0026(
|
void GetObjectLibrariesCMP0026(
|
||||||
std::vector<cmGeneratorTarget*>& objlibs) const;
|
std::vector<cmGeneratorTarget*>& objlibs) const;
|
||||||
|
|
||||||
|
@ -373,8 +373,16 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
|
|||||||
this->IsPartOfDefaultBuild(configs, projectTargets, target);
|
this->IsPartOfDefaultBuild(configs, projectTargets, target);
|
||||||
cmValue vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
|
cmValue vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
|
||||||
if (vcprojName) {
|
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,
|
this->WriteProjectConfigurations(fout, *vcprojName, *target, configs,
|
||||||
configsPartOfDefaultBuild);
|
configsPartOfDefaultBuild, mapping);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -529,6 +529,10 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
|
|||||||
this->impl->PolicyMap.Set(cmPolicies::CMP0022, cmPolicies::NEW);
|
this->impl->PolicyMap.Set(cmPolicies::CMP0022, cmPolicies::NEW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this->IsImported()) {
|
||||||
|
initProp("DOTNET_SDK");
|
||||||
|
}
|
||||||
|
|
||||||
if (this->impl->TargetType <= cmStateEnums::GLOBAL_TARGET) {
|
if (this->impl->TargetType <= cmStateEnums::GLOBAL_TARGET) {
|
||||||
initProp("DOTNET_TARGET_FRAMEWORK");
|
initProp("DOTNET_TARGET_FRAMEWORK");
|
||||||
initProp("DOTNET_TARGET_FRAMEWORK_VERSION");
|
initProp("DOTNET_TARGET_FRAMEWORK_VERSION");
|
||||||
|
@ -405,6 +405,27 @@ void cmVisualStudio10TargetGenerator::Generate()
|
|||||||
// Write the encoding header into the file
|
// Write the encoding header into the file
|
||||||
char magic[] = { char(0xEF), char(0xBB), char(0xBF) };
|
char magic[] = { char(0xEF), char(0xBB), char(0xBF) };
|
||||||
BuildFileStream.write(magic, 3);
|
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=\""
|
BuildFileStream << "<?xml version=\"1.0\" encoding=\""
|
||||||
<< this->GlobalGenerator->Encoding() << "\"?>";
|
<< this->GlobalGenerator->Encoding() << "\"?>";
|
||||||
{
|
{
|
||||||
@ -447,14 +468,27 @@ void cmVisualStudio10TargetGenerator::Generate()
|
|||||||
e1.Element("PreferredToolArchitecture", hostArch);
|
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) {
|
if (this->ProjectType != VsProjectType::csproj) {
|
||||||
this->WriteProjectConfigurations(e0);
|
this->WriteProjectConfigurations(e0);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
Elem e1(e0, "PropertyGroup");
|
Elem e1(e0, "PropertyGroup");
|
||||||
e1.Attribute("Label", "Globals");
|
this->WriteCommonPropertyGroupGlobals(e1);
|
||||||
e1.Element("ProjectGuid", "{" + this->GUID + "}");
|
|
||||||
|
|
||||||
if ((this->MSTools || this->Android) &&
|
if ((this->MSTools || this->Android) &&
|
||||||
this->GeneratorTarget->IsInBuildSystem()) {
|
this->GeneratorTarget->IsInBuildSystem()) {
|
||||||
@ -462,16 +496,6 @@ void cmVisualStudio10TargetGenerator::Generate()
|
|||||||
this->VerifyNecessaryFiles();
|
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 =
|
cmValue vsProjectName =
|
||||||
this->GeneratorTarget->GetProperty("VS_SCC_PROJECTNAME");
|
this->GeneratorTarget->GetProperty("VS_SCC_PROJECTNAME");
|
||||||
cmValue vsLocalPath =
|
cmValue vsLocalPath =
|
||||||
@ -495,24 +519,6 @@ void cmVisualStudio10TargetGenerator::Generate()
|
|||||||
e1.Element("WinMDAssembly", "true");
|
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);
|
e1.Element("Platform", this->Platform);
|
||||||
cmValue projLabel = this->GeneratorTarget->GetProperty("PROJECT_LABEL");
|
cmValue projLabel = this->GeneratorTarget->GetProperty("PROJECT_LABEL");
|
||||||
e1.Element("ProjectName", projLabel ? projLabel : this->Name);
|
e1.Element("ProjectName", projLabel ? projLabel : this->Name);
|
||||||
@ -602,24 +608,6 @@ void cmVisualStudio10TargetGenerator::Generate()
|
|||||||
e1.Element("VCTargetsPath", vcTargetsPath);
|
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->Managed) {
|
||||||
if (this->LocalGenerator->GetVersion() >=
|
if (this->LocalGenerator->GetVersion() >=
|
||||||
cmGlobalVisualStudioGenerator::VS17) {
|
cmGlobalVisualStudioGenerator::VS17) {
|
||||||
@ -839,13 +827,165 @@ void cmVisualStudio10TargetGenerator::Generate()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (BuildFileStream.Close()) {
|
void cmVisualStudio10TargetGenerator::WriteSdkStyleProjectFile(
|
||||||
this->GlobalGenerator->FileReplacedDuringGenerate(PathToProjectFile);
|
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
|
if (this->HasCustomCommands()) {
|
||||||
this->WriteGroups();
|
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)
|
void cmVisualStudio10TargetGenerator::WritePackageReferences(Elem& e0)
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
class cmComputeLinkInformation;
|
class cmComputeLinkInformation;
|
||||||
class cmCustomCommand;
|
class cmCustomCommand;
|
||||||
class cmCustomCommandGenerator;
|
class cmCustomCommandGenerator;
|
||||||
|
class cmGeneratedFileStream;
|
||||||
class cmGlobalVisualStudio10Generator;
|
class cmGlobalVisualStudio10Generator;
|
||||||
class cmLocalVisualStudio10Generator;
|
class cmLocalVisualStudio10Generator;
|
||||||
class cmMakefile;
|
class cmMakefile;
|
||||||
@ -260,6 +261,15 @@ private:
|
|||||||
void ClassifyAllConfigSources();
|
void ClassifyAllConfigSources();
|
||||||
void ClassifyAllConfigSource(cmGeneratorTarget::AllConfigSource const& acs);
|
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;
|
std::unordered_map<std::string, ConfigToSettings> ParsedToolTargetSettings;
|
||||||
bool PropertyIsSameInAllConfigs(const ConfigToSettings& toolSettings,
|
bool PropertyIsSameInAllConfigs(const ConfigToSettings& toolSettings,
|
||||||
const std::string& propName);
|
const std::string& propName);
|
||||||
|
@ -616,6 +616,10 @@ if("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([^9]|9[0-9])")
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(CMAKE_GENERATOR MATCHES "^Visual Studio (1[6-9]|[2-9][0-9])")
|
||||||
|
add_RunCMake_test(VsDotnetSdk)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(XCODE_VERSION)
|
if(XCODE_VERSION)
|
||||||
add_RunCMake_test(XcodeProject -DXCODE_VERSION=${XCODE_VERSION})
|
add_RunCMake_test(XcodeProject -DXCODE_VERSION=${XCODE_VERSION})
|
||||||
add_RunCMake_test(XcodeProject-Embed -DXCODE_VERSION=${XCODE_VERSION})
|
add_RunCMake_test(XcodeProject-Embed -DXCODE_VERSION=${XCODE_VERSION})
|
||||||
|
3
Tests/RunCMake/VsDotnetSdk/CMakeLists.txt
Normal file
3
Tests/RunCMake/VsDotnetSdk/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.22.0)
|
||||||
|
project(${RunCMake_TEST} NONE)
|
||||||
|
include(${RunCMake_TEST}.cmake)
|
52
Tests/RunCMake/VsDotnetSdk/DotnetSdkVariables-check.cmake
Normal file
52
Tests/RunCMake/VsDotnetSdk/DotnetSdkVariables-check.cmake
Normal file
@ -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()
|
14
Tests/RunCMake/VsDotnetSdk/DotnetSdkVariables.cmake
Normal file
14
Tests/RunCMake/VsDotnetSdk/DotnetSdkVariables.cmake
Normal file
@ -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)
|
17
Tests/RunCMake/VsDotnetSdk/RunCMakeTest.cmake
Normal file
17
Tests/RunCMake/VsDotnetSdk/RunCMakeTest.cmake
Normal file
@ -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()
|
18
Tests/RunCMake/VsDotnetSdk/VsDotnetSdk.cmake
Normal file
18
Tests/RunCMake/VsDotnetSdk/VsDotnetSdk.cmake
Normal file
@ -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)
|
@ -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.
|
@ -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)
|
@ -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.
|
@ -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)
|
11
Tests/RunCMake/VsDotnetSdk/csharponly.cs
Normal file
11
Tests/RunCMake/VsDotnetSdk/csharponly.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace CSharpOnly
|
||||||
|
{
|
||||||
|
class CSharpOnly
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
int val = Lib1.getResult();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
Tests/RunCMake/VsDotnetSdk/lib1.cs
Normal file
10
Tests/RunCMake/VsDotnetSdk/lib1.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
namespace CSharpOnly
|
||||||
|
{
|
||||||
|
public class Lib1
|
||||||
|
{
|
||||||
|
public static int getResult()
|
||||||
|
{
|
||||||
|
return 23;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user