.Net Core遷移到MSBuild平臺(二)

1、前言

在上一篇文章.Net Core遷移到MSBuild的多平臺編譯問題中,簡單的講了下新的項目配置文件中的節點配置,這篇我將用一些例子來詳細講下從project.json遷移到msbuild過程的節點配置。作過完整遷移新項目配置文件的朋友,確定會以爲新的項目配置文件Msbuild的配置太扯了,雖然能直接編輯項目文件,但整個配置文件中沒有了像project.json中的智能提示,當你在打開文件後你就會發現之前很輕鬆能寫出來的json配置,如今已經什麼都寫不出來了,並且也沒有文檔能夠參考,通常的狀況下,每每開發人員就會關掉項目文件,打開NuGet管理器來進行包引用,可是這真的夠用嗎?不是全部的配置都能用可視化的方法來完成。
html

2、XML定義

新的.csproj是基於xml格式的,下面介紹下project.json與.csproj文件的差別定義的例子:git

項目名稱 (ProjectName)

{
  "name": "MyProjectName"
}

在csproj的配置中並無對應的定義,它只會有項目文件名相同如:MyProjectName.csprojgithub

程序集版本 (Version)

{
  "version": "1.0.0-alpha-*"
}
<PropertyGroup>
  <VersionPrefix>1.0.0</VersionPrefix>
  <VersionSuffix>alpha</VersionSuffix>
</PropertyGroup>

固然也能夠只使用Version來定義:web

<PropertyGroup>
  <Version>1.0.0-alpha</Version>
</PropertyGroup>

程序集描述

{
  "authors": [ "Anne", "Bob" ],
  "company": "Contoso",
  "language": "en-US",
  "title": "My library",
  "description": "This is my library.\r\nAnd it's really great!",
  "copyright": "Nugetizer 3000",
  "userSecretsId": "xyz123"
}
<PropertyGroup>
  <Authors>Anne;Bob<Authors>
  <Company>Contoso<Company>
  <NeutralLanguage>en-US</NeutralLanguage>
  <AssemblyTitle>My library</AssemblyTitle>
  <Description>This is my library.
And it's really great!</Description>
  <Copyright>Nugetizer 3000</Copyright>
  <UserSecretsId>xyz123</UserSecretsId>
</PropertyGroup>

frameworks (單目標框架)

"frameworks": {
    "netcoreapp1.0": {}
  }
<PropertyGroup>
  <TargetFramework>netcoreapp1.0</TargetFramework>
</PropertyGroup>

frameworks (多目標框架)

"frameworks": {
    "netcoreapp1.0": {},
    "net451": {}
  }
<PropertyGroup>
  <TargetFrameworks>netcoreapp1.0;net451</TargetFrameworks>
</PropertyGroup>

dependencies (框架依賴)

"dependencies": {
    "Microsoft.AspNetCore": "1.1.0"
  }
<ItemGroup>
  <PackageReference Include="Microsoft.AspNetCore" Version="1.1.0" />
</ItemGroup>

不一樣目標框架的依賴 (Per-framework dependencies)

{
  "framework": {
    "net451": {
      "dependencies": {
        "System.Collections.Immutable": "1.3.1"
      }
    },
    "netstandard1.5": {
      "dependencies": {
        "Newtonsoft.Json": "9.0.1"
      }
    }
  }
}
<ItemGroup Condition="'$(TargetFramework)'=='net451'">
  <PackageReference Include="System.Collections.Immutable" Version="1.3.1" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)'=='netstandard1.5'">
  <PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
</ItemGroup>

imports (兼容導入)

{
  "dependencies": {
    "xxx": "1.0-pre001"
  },
  "frameworks": {
    "netcoreapp1.0": {
      "imports": [
        "dnxcore50",
        "dotnet"
      ]
    }
  }
}
<PropertyGroup>
  <PackageTargetFallback>dnxcore50;dotnet</PackageTargetFallback>
</PropertyGroup>
<ItemGroup>
  <PackageReference Include="xxx" Version="1.0-pre001" />
</ItemGroup>

依賴類型 (dependency type)

type: build

{
  "dependencies": {
    "Microsoft.EntityFrameworkCore.Design": {
      "version": "1.1.0",
      "type": "build"
    }
  }
}
<ItemGroup>
  <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.0" PrivateAssets="All" />
</ItemGroup>

type: platform

{
  "dependencies": {
    "Microsoft.NETCore.App": {
      "version": "1.1.0",
      "type": "platform"
    }
  }
}

在*.csproj項目配置文件中沒有對應的配置節點,只有目標框架定義:shell

<TargetFramework>netcoreapp1.1</TargetFramework>

以前想要編譯出獨立發佈的可執行文件,就須要把 "type": "platform"節點刪除掉。apache

獨立發佈定義 (runtimes)

{
  "runtimes": {
    "win7-x64": {},
    "osx.10.11-x64": {},
    "ubuntu.16.04-x64": {}
  }
}
<PropertyGroup>
  <RuntimeIdentifiers>win7-x64;osx.10-11-x64;ubuntu.16.04-x64</RuntimeIdentifiers>
</PropertyGroup>

如今想生成獨立發佈版本,只須要在項目配置中定義RuntimeIdentifiers節點,並運行以下命令:json

dotnet publish --framework netcoreapp1.0 --runtime osx.10.11-x64

DOTNET CLI工具 (tools)

{
  "tools": {
    "Microsoft.EntityFrameworkCore.Tools.DotNet": "1.0.0-*"
  }
}
<ItemGroup>
  <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />
</ItemGroup>

提示:tools下的引用,再也不支持「imports」節點定義(不能兼容非dotnet core版本的tools)。ubuntu

編譯可執行 (emitEntryPoint)

{
  "buildOptions": {
    "emitEntryPoint": true
  }
}
<PropertyGroup>
  <OutputType>Exe</OutputType>
</PropertyGroup>
{
  "buildOptions": {
    "emitEntryPoint": false
  }
}
<PropertyGroup>
  <OutputType>Library</OutputType>
</PropertyGroup>

程序集強命名簽名 (keyFile)

{
  "buildOptions": {
    "keyFile": "MyKey.snk"
  }
}
<PropertyGroup>
  <AssemblyOriginatorKeyFile>MyKey.snk</AssemblyOriginatorKeyFile>
  <SignAssembly>true</SignAssembly>
  <PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
</PropertyGroup>

其它編譯設置

{
  "buildOptions": {
    "warningsAsErrors": true,
    "nowarn": ["CS0168", "CS0219"],
    "xmlDoc": true,
    "preserveCompilationContext": true,
    "outputName": "Different.AssemblyName",
    "debugType": "portable",
    "allowUnsafe": true,
    "define": ["TEST", "OTHERCONDITION"]
  }
}
<PropertyGroup>
  <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
  <NoWarn>$(NoWarn);CS0168;CS0219</NoWarn>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
  <PreserveCompliationContext>true</PreserveCompliationContext>
  <AssemblyName>Different.AssemblyName</AssemblyName>
  <DebugType>portable</DebugType>
  <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
  <DefineConstants>$(DefineConstants);TEST;OTHERCONDITION</DefineConstants>
</PropertyGroup>

打包設置 (packOptions)

{
  "packOptions": {
    "summary": "A bundle of cats",
    "tags": ["hyperscale", "cats"],
    "owners": [ "Nate", "Jenna" ],
    "releaseNotes": "Version 1.0",
    "iconUrl": "https://icons.com/awesomeness.png",
    "projectUrl": "https://github.com/natemcmaster",
    "licenseUrl": "https://www.apache.org/licenses/LICENSE-2.0",
    "requireLicenseAcceptance": false,
    "repository": {
      "type": "git",
      "url": "https://github.com/natemcmaster/natemcmaster.github.io"
    }
  }
}
<PropertyGroup>
  <Description>A bundle of cats</Description>
  <PackageTags>hyperscale;cats</PackageTags>
  <PackageReleaseNotes>Version 1.0</PackageReleaseNotes>
  <PackageIconUrl>https://icons.com/awesomeness.png</PackageIconUrl>
  <PackageProjectUrl>https://github.com/natemcmaster</PackageProjectUrl>
  <PackageLicenseUrl>https://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
  <PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
  <RepositoryType>git</RepositoryType>
  <RepositoryUrl>https://github.com/natemcmaster/natemcmaster.github.io</RepositoryUrl>
  <!-- regrettably, 'owners' does not translate to MSBuild. -->
</PropertyGroup>

MsBuild腳本

{
  "scripts": {
    "precompile": "generateCode.cmd",
    "postpublish": [ "obfuscate.cmd", "removeTempFiles.cmd" ]
  }
}
<Target Name="MyPreCompileTarget" BeforeTargets="Build">
  <Exec Command="generateCode.cmd" />
</Target>
<Target Name="MyPostCompileTarget" AfterTargets="Publish">
  <Exec Command="obfuscate.cmd" />
  <Exec Command="removeTempFiles.cmd" />
</Target>

運行時設置 (runtimeOptions)

{
  "runtimeOptions": {
    "configProperties": {
      "System.GC.Server": true,
      "System.GC.Concurrent": true,
      "System.GC.RetainVM": true,
      "System.Threading.ThreadPool.MinThreads": 10,
      "System.Threading.ThreadPool.MaxThreads": 100
    }
  }
}
<PropertyGroup>
  <ServerGarbageCollection>true</ServerGarbageCollection>
  <ConcurrentGarbageCollection>true</ConcurrentGarbageCollection>
  <RetainVMGarbageCollection>true</RetainVMGarbageCollection>
  <!-- I'm not suggesting these settings...just showing usage ;) -->
  <ThreadPoolMinThreads>10</ThreadPoolMinThreads>
  <ThreadPoolMaxThreads>100</ThreadPoolMaxThreads>
</ProeprtyGroup>

固然若是你建立的是一個web項目的話,及Microsoft.NET.Sdk.Web。那麼 ServerGarbageCollection設置將默認爲true。app

項目文件管理

{
  "buildOptions": {
    "compile": {
      "copyToOutput": "notes.txt",
      "include": "../Shared/*.cs",
      "exclude": "../Shared/Not/*.cs"
    },
    "embed": {
      "include": "../Shared/*.resx"
    }
  },
  "packOptions": {
    "include": "Views/",
    "mappings": {
      "some/path/in/project.txt": "in/package.txt"
    }
  },
  "publishOptions": {
    "include": [
      "files/",
      "publishnotes.txt"
    ]
  }
}
<ItemGroup>
  <Compile Include="..\Shared\*.cs" Exclude="..\Shared\Not\*.cs" />
  <EmbeddedResource Include="..\Shared\*.resx" />
  <Content Include="Views\**\*" PackagePath="%(Identity)" />
  <None Include="some/path/in/project.txt" Pack="true" PackagePath="in/package.txt" />
  
  <None Include="notes.txt" CopyToOutputDirectory="Always" />
  <!-- CopyToOutputDirectory = { Always, PreserveNewest, Never } -->

  <Content Include="files\**\*" CopyToPublishDirectory="PreserveNewest" />
  <None Include="publishnotes.txt" CopyToPublishDirectory="Always" />
  <!-- CopyToPublishDirectory = { Always, PreserveNewest, Never } -->

  <!-- you can set both copy output and publish directories-->
  <None Include="testasset.txt" CopyToOutputDirectory="Always" CopyToPublishDirectory="Always" />

  <!-- alternatively, use nested XML attributes. They're functionally the same-->
  <None Include="testasset2.txt">
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    <CopyToPublishDirectory>Always</CopyToPublishDirectory>
  </None>

</ItemGroup>

單元測試

xunit

{
  "testRunner": "xunit",
  "dependencies": {
    "dotnet-test-xunit": "<any>"
  }
}
<ItemGroup>
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
  <PackageReference Include="xunit" Version="2.2.0" />
  <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
</ItemGroup>

mstest

{
  "testRunner": "mstest",
  "dependencies": {
    "dotnet-test-mstest": "<any>"
  }
}
<ItemGroup>
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
  <PackageReference Include="MSTest.TestAdapter" Version="1.1.12" />
  <PackageReference Include="MSTest.TestFramework" Version="1.1.11" />
</ItemGroup>

3、結語

說實話MSBuild的項目配置系統仍是比較靈活的,之後整個dotnet體系的構建過程也都獲得了統一。在dotnet cli中也集成了msbuild,即dotnet build。框架

.NET Core 開源學習羣:214741894

GitHub:https://github.com/maxzhang1985/YOYOFx 若是覺還能夠請Star下, 歡迎一塊兒交流。

相關文章
相關標籤/搜索