• .Net Core迁移到MSBuild的多平台编译问题


    一、前言

      本篇主要讨论.NET Core应用程序项目结构的主题,重点探索.NET Core应用程序的多平台编译问题,这里指的多平台是指.NET Framework、.NET Core App、.NET Standard、Mono、UWP等多平台的条件编译、项目(包)引用、编译符号等问题。

      .NET Core已经将新的项目管理配置过渡回MSBuild编译系统中。虽然现在可以从无到有的使用VS2017来创建一个新的MSBuild项目,但是还是有好多遗留程序使用着以JSON格式存储的项目配置文件为基础的项目。Scott Hanselman也在博客中发文教大家怎么使用新的.NET SDK RC4工具将project.json转换到MSBuild的.csproj项目系统。当然这篇文章也解释了MS为什么要这么做。

      MSBuild 是一种基于 XML 的项目文件格式的项目配置文件。这种格式容易理解、易于扩展并且完全受 Microsoft 支持。MSBuild 项目文件的格式使开发人员能够充分描述哪些项需要生成,以及如何利用不同的平台和配置生成这些项。另外,项目文件的格式还使开发人员能够创作可重用的生成规则,这些规则可以分解到不同的文件中,以便可以在产品内的不同项目之间一致地执行生成。

      当时ASP.NET Core的第一个版本为了使开源平台对开发者更具吸引力,ASP.NET Core采用了一种基于JSON的项目系统project.json文件定义,这是一种与Node.js类似的定义,这对于吸引Web开发者来说是个明智的选择。但是随着.NET Core的整体开源,非Web开发者如UWP和Xamarin,对这种JSON项目结构并不熟悉。这些开发者和社区都希望继续使用MSBuild的XML项目系统。因些微软宣布他们将为.NET Core重新启用和规范MSBuild构建系统。在最新的.NET Core SDK 1.0 RC4 版本中,dotnet cli(命令行接口,dotnet cli 1.0.0-preview3-004056及以后版本)已经包含了”dotnet migrate”命令,这个命令为了将JSON为基础的配置项目转换为.csproj项目配置文件。

    本文不再谈论如何使用新dotnet cli命令行,而卓重讨论多平台编译问题。

    二、定义多平台

    project.json

    在project.json项目配置中定义多平台,使用的是”frameworks”节点来配置的,并且在每个平台节点下也配置了对应的项目引用或依赖。
    下面的实例使用project.json定义的多平台和依赖如下:

    "frameworks": {
        "net451": {
          "frameworkAssemblies": {
            "System.Xml": "4.0.0.0",
          }
        },
        "netstandard1.6": {
          "dependencies": {
            "System.Runtime":"4.1.0",
            "System.Xml.XmlSerializer": "4.0.11"
          },
        }
    }

    MSBuild

    在.csproj项目配置中定义多平台,要使用”TargetFrameworks”的XML节点来配置:

    <TargetFrameworks>netstandard1.6;net45;</TargetFrameworks>

    如果要定义某个平台下的依赖引用的话需要如下定义:

    <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
        <Reference Include="System.Xml" />
    </ItemGroup>
    <ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.6' ">
        <PackageReference Include="System.Xml.XmlSerializer" Version="4.0.11"/>
    </ItemGroup>

    当然有时候我们还需要对某个平台定义,定义编译符号常量:

    <PropertyGroup Condition="'$(TargetFramework)' == 'netstandard1.6'">
        <DefineConstants>$(DefineConstants);NETSTANDARD</DefineConstants>
    </PropertyGroup>

    这些代码中就可以针对平台特性来编写代码了:

    #if NETSTANDARD
        //netstandard1.*平台代码
    #endif

    如果我们想在某个平台下,只编译某些文件,也是可以实现的:

    <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
        <Reference Include="System" />
        <Reference Include="Microsoft.CSharp" />
        <Compile Include="Platforms
    et45*.cs" />
    </ItemGroup>

    三、结语

    说实话MSBuild的项目配置系统还是比较灵活的,以后整个dotnet体系的构建过程也都得到了统一。在dotnet cli中也集成了msbuild,即dotnet build。

    GitHub:https://github.com/maxzhang1985/YOYOFx 如果觉还可以请Star下, 欢迎一起交流。

    .NET Core 开源学习群:214741894

  • 相关阅读:
    第十一周学习总结
    个人冲刺——(六)
    第二阶段冲刺—第二天
    软件工程第十四周总结
    第二阶段冲刺—第一天
    大道至简阅读笔记02
    输入法用户体验评价
    软件工程第十三周总结
    人机交互-水王
    大道至简阅读笔记01
  • 原文地址:https://www.cnblogs.com/maxzhang1985/p/6481549.html
Copyright © 2020-2023  润新知