如何使用CMake生成.NET Standard目标框架的Visual Studio项目

3
我正在尝试使用CMake生成Visual Studio C#项目。目前我已经完成了以下步骤:
cmake_minimum_required(VERSION 3.10)

project(myProject VERSION 0.1.0 LANGUAGES CSharp)

add_library(myLib SHARED
    src/file1.cs
    src/file2.cs
    src/file3.cs)

set_property(TARGET myLib PROPERTY VS_DOTNET_TARGET_FRAMEWORK_VERSION "netstandard1.4")

我从使用Visual Studio生成的.csproj文件中得知了这个框架的名称,它的内容如下:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard1.4</TargetFramework>
  </PropertyGroup>
</Project>

以下是我需要为了构建.NET Standard 1.4库所需的内容。然而,CMake生成了这个(其中还有其他的东西):
<TargetFrameworkVersion>netstandard1.4</TargetFrameworkVersion>

这似乎不是有效的,因为Visual Studio抱怨无法打开该项目。我在CMake文档中没有找到设置<TargetFramework>而非<TargetFrameworkVersion>的任何内容。这是否可能?
1个回答

5
这是我成功生成项目的方式。请注意,这是一个很丑的hack。在尝试这个方法之前,请检查CMake是否已经更新以支持它。首先: VS_DOTNET_TARGET_FRAMEWORK_VERSION不是必需的。可以使用以下命令添加正确的<TargetFramework>:
set_property(TARGET myLib PROPERTY VS_GLOBAL_TargetFramework "netstandard1.4")

您还需要添加这个,因为出于我不明白的原因,CMake认为默认生成一个使用C# 3作为语言级别的项目是一个好主意:

set_property(TARGET myLib PROPERTY VS_GLOBAL_LangVersion "6")

生成的项目在Visual Studio中无法正确打开。这是因为.NET Core带来了一些对csproj格式的更改,而CMake目前无法生成。有关此更改的参考,请查看此文章。 CMake无法正确生成它们,因此我将首先告诉您需要进行哪些修改,然后提供一些hacky PowerShell脚本来为您完成这些操作。
主要的.csproj文件
现在,在根<Project>上有一个Sdk属性,我们需要按照以下方式设置:
<Project Sdk="Microsoft.NET.Sdk" ...

自动生成的ZERO_CHECK项目无法工作,所以我们只需将其删除(我们真的不需要它)。从<ProjectReference ... </ProjectReference>中删除它,如果它是唯一的项目,则删除整个XML标记。
然后,由于项目现在会自动引用SDK中的内容,因此我们需要摆脱对Microsoft.CSharp.targetsMicrosoft.Common.props的引用。否则,Visual Studio将向您显示警告和错误,指出已加载多个内容。只需删除包含这些字符串的行。
主要的.sln文件
CMake始终生成的标准项目ALL_BUILDZERO_CHECK无法工作,而且我无法费心适当地修复它们,因为它们并不是真正必要的。我只是从.sln文件中删除了它们。
完成
就是这样!现在,您可以在Visual Studio中打开该项目,并且它将正常工作。
PowerShell脚本
这是我编写的一个脚本,用作正确生成项目和解决方案的解决方法。它在一个名为cmake-vs的文件夹中生成解决方案。您需要.NET Core SDK中的dotnet实用程序。
请注意,路径可能不可移植。将myLib替换为您的库名称。
mkdir -Force cmake-vs | Out-Null
Set-Location cmake-vs
& "$Env:Programfiles\CMake\bin\cmake.exe" -G "Visual Studio 15 2017 Win64" ".."
& "$Env:Programfiles\CMake\bin\cmake.exe" --build .
((Get-Content "myLib.csproj") `
  <# add Sdk attribute to project which is needed by netstandard1.4 #> `
  -replace ('<Project ','<Project Sdk="Microsoft.NET.Sdk" ') `
  <# remove reference to ZERO_CHECK project which causes problems #> `
  -replace ('(?ms)<ProjectReference.*</ProjectReference>','') |
  <# remove imports that are unneccessary for netstandard1.4 and cause
     problems #> `
  Select-String -Pattern "Microsoft.CSharp.targets" -NotMatch |
  Select-String -Pattern "Microsoft.Common.props" -NotMatch |
  <# for some reason, Select-String prepends an empty line which is not
     allowed before <?xml ..., so we trim it away. #>
  Out-String).Trim() | Out-File "myLib.csproj"
<# use dotnet util (part of the .NET Core SDK) to remove projects with problems
   from the solution because I am really tired of regexes #>
& "$Env:Programfiles\dotnet\dotnet.exe" sln myLib.sln remove ALL_BUILD.vcxproj
& "$Env:Programfiles\dotnet\dotnet.exe" sln myLib.sln remove ZERO_CHECK.vcxproj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接