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
This commit is contained in:
Brad King 2021-12-22 13:56:04 +00:00 committed by Kitware Robot
commit 138aabfa9d
26 changed files with 439 additions and 53 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View 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.

View 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.

View 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.

View File

@ -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
{ {

View File

@ -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;

View File

@ -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);
} }
} }
} }

View File

@ -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");

View File

@ -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)

View File

@ -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);

View File

@ -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})

View File

@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.22.0)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)

View 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()

View 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)

View 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()

View 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)

View File

@ -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.

View File

@ -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)

View File

@ -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.

View File

@ -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)

View File

@ -0,0 +1,11 @@
namespace CSharpOnly
{
class CSharpOnly
{
public static void Main(string[] args)
{
int val = Lib1.getResult();
return;
}
}
}

View File

@ -0,0 +1,10 @@
namespace CSharpOnly
{
public class Lib1
{
public static int getResult()
{
return 23;
}
}
}