如何正确打包生成源代码的 Nuget 分布式自定义工具作为构建的一部分

How to properly package a Nuget distributed custom tool that generates source code as part of the build

感谢 this Nate McMaster 的精彩文章,我知道如何将 .NET 核心控制台应用程序打包为 Nuget 包,自动将自身安装为(预,在本例中)构建任务。

为了测试是否一切正常,我只是让我的自定义工具写了一个 public C# class。

Here is the complete and runnable sample on Github.

但是,我的自定义工具添加的文件实际上并不是构建的一部分(第一个实际生成文件的文件),因此引入的 class 不在第一次构建后的程序集中(参见第 38 行 here). However, because the .NET core projects now automatically include all .cs files alongside the project, it builds the new class into the output on subsequent builds (see Line 57 here)。

生成的文件不会完全消失,但通常不会像 MSBuild 任务输出的那样。但是,因为 exec 发生在目标文件中,所以我们应该可以访问所有机制来实现这一点。所以我的问题是:

如何正确执行需要检查项目及其文件并生成源代码的自定义构建工具(控制台应用程序)(最好在 obj/ 中,如 <foo>.g.cs 编译到生成的程序集中作为单个构建的一部分?理想情况下,这个生成的文件也不应该出现在解决方案资源管理器中。

求助!

在中间文件夹中生成中间文件(CustomTool.g.cs)时(需要自己解析,参见Refit库中的例子:https://github.com/reactiveui/refit/blob/5b4e14aaf8a1fcc27396b7c08171d100aba1b97d/Refit/targets/refit.targets#L11);您需要将其显式添加为编译项。

使用您的示例目标文件 (https://github.com/aniongithub/CustomTool/blob/master/CustomTool/RunCustomTool.targets#L13):

<Project>
  <PropertyGroup>
    <IntermediateOutputPath Condition="$(IntermediateOutputPath) == '' Or $(IntermediateOutputPath) == '*Undefined*'">$(MSBuildProjectDirectory)obj$(Configuration)\</IntermediateOutputPath>

    <!-- Command to invoke CustomTool -->
    <CustomTool>dotnet "$(MSBuildThisFileDirectory)/netcoreapp2.2/CustomTool.dll"</CustomTool>

    <!-- Other variables  -->
    <CustomVariable>"$(MSBuildProjectDir)"</CustomVariable>
  </PropertyGroup>

  <Target Name="CustomTool" BeforeTargets="CoreCompile" DependsOnTargets="PrepareForBuild">
    <Exec Command="$(CustomTool) $(ProjectPath) $(IntermediateOutputPath)CustomTool.g.cs" />

    <!-- add generated file as a compile item, otherwise it won't get picked up -->
    <ItemGroup Condition="Exists('$(IntermediateOutputPath)\CustomTool.g.cs')">
      <Compile Include="$(IntermediateOutputPath)\CustomTool.g.cs" />
    </ItemGroup>
  </Target>
</Project>