1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-22 16:07:49 +08:00

VS: Add support for .NET Standard and .NET Core

Fixes: #20105
This commit is contained in:
Joerg Bornemann
2020-01-13 17:33:55 +01:00
committed by Brad King
parent 93d4148612
commit ae1e1909a1
18 changed files with 216 additions and 23 deletions

View File

@@ -185,6 +185,7 @@ Properties on Targets
/prop_tgt/DEPLOYMENT_ADDITIONAL_FILES /prop_tgt/DEPLOYMENT_ADDITIONAL_FILES
/prop_tgt/DEPRECATION /prop_tgt/DEPRECATION
/prop_tgt/DISABLE_PRECOMPILE_HEADERS /prop_tgt/DISABLE_PRECOMPILE_HEADERS
/prop_tgt/DOTNET_TARGET_FRAMEWORK
/prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION /prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION
/prop_tgt/EchoString /prop_tgt/EchoString
/prop_tgt/ENABLE_EXPORTS /prop_tgt/ENABLE_EXPORTS

View File

@@ -48,6 +48,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_TARGET_FRAMEWORK
/variable/CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION /variable/CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION
/variable/CMAKE_EDIT_COMMAND /variable/CMAKE_EDIT_COMMAND
/variable/CMAKE_EXECUTABLE_SUFFIX /variable/CMAKE_EXECUTABLE_SUFFIX

View File

@@ -0,0 +1,13 @@
DOTNET_TARGET_FRAMEWORK
-----------------------
Specify the .NET target framework.
Used to specify the .NET target framework for C++/CLI and C#. For
example: ``netcoreapp2.1``.
This property is only evaluated for :ref:`Visual Studio Generators`
VS 2010 and above.
Can be initialized for all targets using the variable
:variable:`CMAKE_DOTNET_TARGET_FRAMEWORK`.

View File

@@ -3,11 +3,13 @@ DOTNET_TARGET_FRAMEWORK_VERSION
Specify the .NET target framework version. Specify the .NET target framework version.
Used to specify the .NET target framework version for C++/CLI. For Used to specify the .NET target framework version for C++/CLI and C#.
example: ``v4.5``. For example: ``v4.5``.
This property is only evaluated for :ref:`Visual Studio Generators` This property is only evaluated for :ref:`Visual Studio Generators`
VS 2010 and above. VS 2010 and above.
Can be initialized for all targets using the variable To initialize this variable for all targets set
:variable:`CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION`. :variable:`CMAKE_DOTNET_TARGET_FRAMEWORK` or
:variable:`CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION`. If both are set,
the latter is ignored.

View File

@@ -3,8 +3,9 @@ VS_DOTNET_TARGET_FRAMEWORK_VERSION
Specify the .NET target framework version. Specify the .NET target framework version.
Used to specify the .NET target framework version for C++/CLI. For Used to specify the .NET target framework version for C++/CLI. For
example, "v4.5". example, "v4.5".
This property is deprecated and should not be used anymore. Use This property is deprecated and should not be used anymore. Use
:prop_tgt:`DOTNET_TARGET_FRAMEWORK` or
:prop_tgt:`DOTNET_TARGET_FRAMEWORK_VERSION` instead. :prop_tgt:`DOTNET_TARGET_FRAMEWORK_VERSION` instead.

View File

@@ -0,0 +1,7 @@
vs-dotnet-standard-core
-----------------------
* :ref:`Visual Studio Generators` for VS 2010 and above learned to
support .NET Standard and .NET Core. See the
:prop_tgt:`DOTNET_TARGET_FRAMEWORK` target property and
associated :variable:`CMAKE_DOTNET_TARGET_FRAMEWORK` variable.

View File

@@ -0,0 +1,16 @@
CMAKE_DOTNET_TARGET_FRAMEWORK
-----------------------------
Default value for :prop_tgt:`DOTNET_TARGET_FRAMEWORK` property of
targets.
This variable is used to initialize the
:prop_tgt:`DOTNET_TARGET_FRAMEWORK` property on all targets. See that
target property for additional information.
Setting ``CMAKE_DOTNET_TARGET_FRAMEWORK`` may be necessary
when working with ``C#`` and newer .NET framework versions to
avoid referencing errors with the ``ALL_BUILD`` CMake target.
This variable is only evaluated for :ref:`Visual Studio Generators`
VS 2010 and above.

View File

@@ -6,7 +6,11 @@ property of targets.
This variable is used to initialize the This variable is used to initialize the
:prop_tgt:`DOTNET_TARGET_FRAMEWORK_VERSION` property on all :prop_tgt:`DOTNET_TARGET_FRAMEWORK_VERSION` property on all
targets. See that target property for additional information. targets. See that target property for additional information. When set,
:variable:`CMAKE_DOTNET_TARGET_FRAMEWORK` takes precednece over this
variable. See that variable or the associated target property
:prop_tgt:`DOTNET_TARGET_FRAMEWORK` for additional information.
Setting ``CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION`` may be necessary Setting ``CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION`` may be necessary
when working with ``C#`` and newer .NET framework versions to when working with ``C#`` and newer .NET framework versions to

View File

@@ -517,6 +517,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
} }
if (impl->TargetType <= cmStateEnums::UTILITY) { if (impl->TargetType <= cmStateEnums::UTILITY) {
initProp("DOTNET_TARGET_FRAMEWORK");
initProp("DOTNET_TARGET_FRAMEWORK_VERSION"); initProp("DOTNET_TARGET_FRAMEWORK_VERSION");
} }

View File

@@ -483,23 +483,33 @@ void cmVisualStudio10TargetGenerator::Generate()
} }
e1.Element("ProjectName", projLabel); e1.Element("ProjectName", projLabel);
{ {
// TODO: add deprecation warning for VS_* property? const char* targetFramework =
const char* targetFrameworkVersion = this->GeneratorTarget->GetProperty("DOTNET_TARGET_FRAMEWORK");
this->GeneratorTarget->GetProperty( if (targetFramework) {
"VS_DOTNET_TARGET_FRAMEWORK_VERSION"); if (std::strchr(targetFramework, ';') != nullptr) {
if (!targetFrameworkVersion) { e1.Element("TargetFrameworks", targetFramework);
targetFrameworkVersion = this->GeneratorTarget->GetProperty( } else {
"DOTNET_TARGET_FRAMEWORK_VERSION"); e1.Element("TargetFramework", targetFramework);
} }
if (!targetFrameworkVersion && this->ProjectType == csproj && } else {
this->GlobalGenerator->TargetsWindowsCE() && // TODO: add deprecation warning for VS_* property?
this->GlobalGenerator->GetVersion() == const char* targetFrameworkVersion =
cmGlobalVisualStudioGenerator::VS12) { this->GeneratorTarget->GetProperty(
// VS12 .NETCF default to .NET framework 3.9 "VS_DOTNET_TARGET_FRAMEWORK_VERSION");
targetFrameworkVersion = "v3.9"; if (!targetFrameworkVersion) {
} targetFrameworkVersion = this->GeneratorTarget->GetProperty(
if (targetFrameworkVersion) { "DOTNET_TARGET_FRAMEWORK_VERSION");
e1.Element("TargetFrameworkVersion", targetFrameworkVersion); }
if (!targetFrameworkVersion && this->ProjectType == csproj &&
this->GlobalGenerator->TargetsWindowsCE() &&
this->GlobalGenerator->GetVersion() ==
cmGlobalVisualStudioGenerator::VS12) {
// VS12 .NETCF default to .NET framework 3.9
targetFrameworkVersion = "v3.9";
}
if (targetFrameworkVersion) {
e1.Element("TargetFrameworkVersion", targetFrameworkVersion);
}
} }
if (this->ProjectType == vcxproj && if (this->ProjectType == vcxproj &&
this->GlobalGenerator->TargetsWindowsCE()) { this->GlobalGenerator->TargetsWindowsCE()) {
@@ -4110,6 +4120,9 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0)
e2.Element("Project", "{" + this->GlobalGenerator->GetGUID(name) + "}"); e2.Element("Project", "{" + this->GlobalGenerator->GetGUID(name) + "}");
e2.Element("Name", name); e2.Element("Name", name);
this->WriteDotNetReferenceCustomTags(e2, name); this->WriteDotNetReferenceCustomTags(e2, name);
if (dt->IsCSharpOnly() || cmHasLiteralSuffix(path, "csproj")) {
e2.Element("SkipGetTargetFrameworkProperties", "true");
}
// Don't reference targets that don't produce any output. // Don't reference targets that don't produce any output.
if (dt->GetManagedType("") == cmGeneratorTarget::ManagedType::Undefined) { if (dt->GetManagedType("") == cmGeneratorTarget::ManagedType::Undefined) {

View File

@@ -53,3 +53,6 @@ if (RunCMake_GENERATOR MATCHES "Visual Studio 1[0-4] 201[0-5]" OR
else() else()
run_cmake(UnityBuildNative) run_cmake(UnityBuildNative)
endif() endif()
run_cmake(VsDotnetTargetFramework)
run_cmake(VsDotnetTargetFrameworkVersion)

View File

@@ -0,0 +1,10 @@
enable_language(CSharp)
if(NOT CMAKE_CSharp_COMPILER)
return()
endif()
set(CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION "v4.6.1")
add_library(foo SHARED foo.cs)
set(CMAKE_DOTNET_TARGET_FRAMEWORK "netcoreapp3.1")
add_library(bar SHARED foo.cs)

View File

@@ -0,0 +1,40 @@
set(files foo.csproj bar.csproj)
set(inLib1 FALSE)
set(targetFrameworkInLib1 FALSE)
set(inLib2 FALSE)
set(targetFrameworksInLib2 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 " *<TargetFramework>netcoreapp3.1</TargetFramework> *$")
set(targetFrameworkInLib1 TRUE)
set(inLib1 TRUE)
endif()
elseif(NOT inLib2)
if(line MATCHES " *<TargetFrameworks>netcoreapp3.1;net461</TargetFrameworks> *$")
set(targetFrameworksInLib2 TRUE)
set(inLib2 TRUE)
endif()
endif()
endforeach()
endforeach()
if(NOT targetFrameworkInLib1)
set(RunCMake_TEST_FAILED "TargetFramework not set correctly.")
endif()
if(NOT targetFrameworksInLib2)
set(RunCMake_TEST_FAILED "TargetFrameworks not set correctly.")
endif()

View File

@@ -0,0 +1,11 @@
enable_language(CSharp)
if(NOT CMAKE_CSharp_COMPILER)
return()
endif()
set(CMAKE_DOTNET_TARGET_FRAMEWORK "netcoreapp3.1")
set(CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION "net461")
add_library(foo SHARED foo.cs)
set(CMAKE_DOTNET_TARGET_FRAMEWORK "netcoreapp3.1;net461")
add_library(bar SHARED foo.cs)

View File

@@ -0,0 +1,40 @@
set(files foo.csproj bar.csproj)
set(inLib1 FALSE)
set(targetFrameworkInLib1 FALSE)
set(inLib2 FALSE)
set(targetFrameworksInLib2 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 " *<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> *$")
set(targetFrameworkInLib1 TRUE)
set(inLib1 TRUE)
endif()
elseif(NOT inLib2)
if(line MATCHES " *<TargetFramework>netcoreapp3.1</TargetFramework> *$")
set(targetFrameworksInLib2 TRUE)
set(inLib2 TRUE)
endif()
endif()
endforeach()
endforeach()
if(NOT targetFrameworkInLib1)
set(RunCMake_TEST_FAILED "TargetFrameworkVersion not set correctly.")
endif()
if(NOT targetFrameworksInLib2)
set(RunCMake_TEST_FAILED "TargetFramework not set correctly.")
endif()

View File

@@ -5,3 +5,7 @@ run_cmake(CustomGuid)
run_cmake(CustomTypePlatform) run_cmake(CustomTypePlatform)
run_cmake(CustomGuidTypePlatform) run_cmake(CustomGuidTypePlatform)
run_cmake(CustomConfig) run_cmake(CustomConfig)
if(RunCMake_GENERATOR MATCHES "Visual Studio ([^9]|9[0-9])")
run_cmake(SkipGetTargetFrameworkProperties)
endif()

View File

@@ -0,0 +1,21 @@
file(READ "${RunCMake_TEST_BINARY_DIR}/ALL_BUILD.vcxproj" all_build)
macro(project_reference EXTERNAL_PROJECT)
string(REGEX MATCH
"<ProjectReference.Include=.${${EXTERNAL_PROJECT}}.>.*</SkipGetTargetFrameworkProperties>"
EndOfProjectReference
${all_build}
)
endmacro()
set(external_project "external.project")
project_reference(external_project)
if(NOT ${EndOfProjectReference} MATCHES ".*</ProjectReference>")
set(RunCMake_TEST_FAILED "${test} is being set unexpectedly.")
endif()
set(external_project "external.csproj")
project_reference(external_project)
if(${EndOfProjectReference} MATCHES ".*</ProjectReference>")
set(RunCMake_TEST_FAILED "${test} is not set.")
endif()

View File

@@ -0,0 +1,5 @@
include_external_msproject(external1 external.project
GUID aaa-bbb-ccc-000)
include_external_msproject(external2 external.csproj
GUID aaa-bbb-ccc-001)