代码之家  ›  专栏  ›  技术社区  ›  Sebastien ROBERT

在生成任务之前是否有.NET Core CLI预处理?

  •  19
  • Sebastien ROBERT  · 技术社区  · 8 年前

    这个问题

    我想什么时候 msbuild Include Exclude 项目规则。

    在评估要编译的文件列表之前,是否有方法执行任务?

    我正在制作一个.NET Core CLI工具,它必须在使用它的项目构建之前运行,因为它(CLI工具)生成一个必须包含在构建中的文件。

    项目是使用新的 .csproj project.json

    在我的.NET Core CLI工具项目中,我创建了一个用于测试的库项目。

    <ItemGroup>
        <DotNetCliToolReference Include="MyCliTool" Version="x.x.x" />
        <!-- here x.x.x is just a placeholder -->
    </ItemGroup>
    
    <Target Name="MyCliToolTarget" AfterTargets="Restore" BeforeTargets="BeforeBuild">
        <Exec Command="dotnet my-cli-tool" />
    </Target>
    

    然后,如果CLI工具生成的文件以前不存在,则在编译中不考虑该文件。这意味着当文件存在时,它是可以的,但也意味着第一次构建(在克隆、清理或其他之后)总是会失败。

    我尝试了几个不同的目标 BeforeTargets InitialTargets Project 节点,但它也不起作用。我试着设置 Outputs Target 节点设置为CLI工具生成的文件名,但同样失败。

    我发现唯一有效的解决方案是手动添加 Compile

    <ItemGroup>
        <Compile Include="MyGeneratedFile.cs" />
    </ItemGroup>
    

    此解决方案目前还可以,但文件名可能会根据CLI工具选项而更改,这将导致文件名在两个地方必须在更改时更新,如下所示:

    <ItemGroup>
        <Compile Include="PATH\TO\CUSTOM_FILENAME_HERE.CS" />
        <DotNetCliToolReference Include="MyCliTool" Version="x.x.x" />
    </ItemGroup>
    
    <Target Name="MyCliToolTarget" AfterTargets="Restore" BeforeTargets="BeforeBuild">
        <Exec Command="dotnet my-cli-tool --output PATH\TO\CUSTOM_FILENAME_HERE.CS" />
    </Target>
    

    (请参阅CUSTOM\u FILENAME\u HERE.CS出现两次)

    我知道我可以使用一个常数,如下所示:

    <PropertyGroup>
        <MyFilename>PATH\TO\CUSTOM_FILENAME_HERE.CS</MyFilename>
    </PropertyGroup>
    
    <ItemGroup>
        <Compile Condition="!Exists('$(MyFilename)')" Include="$(MyFilename)" />
        <DotNetCliToolReference Include="MyCliTool" Version="x.x.x" />
    </ItemGroup>
    
    <Target Name="MyCliToolTarget" AfterTargets="Restore" BeforeTargets="BeforeBuild">
        <Exec Command="dotnet my-cli-tool --output $(MyFilename)" />
    </Target>
    

    我使用的是.NET核心SDK 1.0.1。

    提前感谢您的时间和帮助。




    旁注: dotnet my-cli-tool 在预构建事件中,如:

    <PropertyGroup>
        <PreBuildEvent>dotnet my-cli-tool</PreBuildEvent>
    </PropertyGroup>
    

    描述:“dotnet my cli tool”命令退出,代码为1。 项目: 文件:C:\Program Files(x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets 线路:4935

    不过,以下方法很好:

    <PropertyGroup>
        <PreBuildEvent>echo meh</PreBuildEvent>
    </PropertyGroup>
    

    无论如何,这是另一个故事,我现在不太关心。

    2 回复  |  直到 5 年前
        1
  •  42
  •   Martin Ullrich    8 年前

    NET SDK调用的“默认项”是项目文件静态评估的一部分-在运行任何目标之前。因此,您需要在 @(Compile) 需要物品。

    诀窍是在运行自定义工具后包括添加到文件系统的文件。这可以通过重新扫描所有文件并排除在生成之前运行的目标中已经是项目一部分的文件来实现:

      <Target Name="GenerateSomeFiles" BeforeTargets="BeforeBuild">
        <Exec Command="dotnet my-tool" />
        <ItemGroup>
          <Compile Include="**/*$(DefaultLanguageSourceExtension)"
                   Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder);$(BaseIntermediateOutputPath)**;$(BaseOutputPath)**;@(Compile)" />
        </ItemGroup>
      </Target>
    
        2
  •  1
  •   shuelsmeier    3 年前

    如果自定义工具仅创建一个文件,则可以直接在中间输出路径中创建它,并将其包含在编译中:

      <Target Name="GenerateSomeFiles" BeforeTargets="CoreCompile" DependsOnTargets="PrepareForBuild">
        <Exec Command="dotnet my-tool $(MSBuildProjectDirectory)\$(IntermediateOutputPath)\my-output.cs" />
      </Target>
    
      <ItemGroup>
        <Compile Include="$(MSBuildProjectDirectory)\$(IntermediateOutputPath)\my-output.cs" />
      </ItemGroup>