MSBuild - 在构建中集成跨平台编译器

MSBuild - integrating a cross-platform compiler in the build

有一个编译器,我需要将它集成到 MSBuild 的项目构建中。 为此,我有一个任务和一个调用任务的目标文件。

目前,该任务是一个 ToolTask,它将调用编译器,并支持带有 GenerateCommandLineCommands 的命令行参数。

编译器是一个 .NET Core 应用程序,我希望能够通过 dotnet 工具 (.NET Core MSBuild) 和 Visual Studio (.NET Framework MSBuild) 使用它。

  1. 应该如何从任务中调用编译器?
  2. 如果我是对的,我将需要一个任务 属性 来了解它是 Core 还是 Full MSBuild,但是 Core MSBuild 将如何执行编译器? dotnet compiler.dll ?
  3. 任务和目标应该作为工具 nuget 包随编译器一起提供?

首先,建议在编译器项目中同时针对 .NET Framework 和 .NET Core。

对于Core MSBuild,需要通过dotnet调用编译器,这可以使用脚本来完成。 Roslyn 和 F# 编译器就是这样做的。有两个脚本,一个用于 Windows(类似于 RunCompiler.cmd),如下所示:

@echo off
dotnet %~dp0\compiler.dll %*

还有另一个 Unix 脚本(类似于 RunCompiler),像这样:

#!/bin/sh

THISDIR=$(dirname [=11=])

dotnet $THISDIR/compiler.dll "$@"

编译器任务,类似于扩展 ToolTaskCompiler,被编译成一个单独的程序集,它随编译器包一起提供(脚本也随附在其中)。为了允许通过安装该包使用不同版本的编译器,工具路径应该像这样包含(假设 .NET Core 二进制文件位于 netcoreapp 文件夹中,.NET Framework 二进制文件位于 win 文件夹,与目标文件在同一目录中):

<Choose>
    <When Condition="'$(MSBuildRuntimeType)' == 'Core'">
        <PropertyGroup>
            <CompilerToolPath>$(MSBuildThisFileDirectory)netcoreapp\</CompilerToolPath>
            <CompilerToolExeCondition="'$(OS)' == 'Windows_NT'">RunCompiler.cmd</CompilerToolExe>
            <CompilerToolExeCondition="'$(OS)' != 'Windows_NT'">RunCompiler</CompilerToolExe>
        </PropertyGroup>
    </When>
    <Otherwise>
        <PropertyGroup>
            <CompilerToolPath>$(MSBuildThisFileDirectory)win\</CompilerToolPath>
            <CompilerToolExe>compiler.exe</CompilerToolExe>
        </PropertyGroup>
    </Otherwise>
</Choose>

<Target Name="MakeCompilerScriptsExecutable"
        BeforeTargets="CoreCompile"
        Condition="'$(MSBuildRuntimeType)' == 'Core' AND '$(OS)' != 'Windows_NT'">

    <Exec Command="chmod +x '$(CompilerToolPath)/$(CompilerToolExe)'" />

</Target>

<UsingTask TaskName="Compiler.Tasks.Compiler" AssemblyFile="Compiler.Tasks.dll" />

然后在 CoreCompile 中调用任务,如下所示:

<Compiler Parameter1="$(Parameter1)"
          ToolPath="$(CompilerToolPath)"
          ToolExe="$(CompilerToolExe)" />