生成任务之前是否有.NET Core CLI预先安装? [英] Is there a .NET Core CLI pre before build task?

查看:75
本文介绍了生成任务之前是否有.NET Core CLI预先安装?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我假设msbuild即将编译源代码文件时,它会根据项目的IncludeExclude规则生成要构建的文件列表.

I assume when msbuild is about to compile source code files, it produces a list of files to build, based on Include and Exclude rules of the project.

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

这是为了能够生成源代码文件并使其在构建中使用.

This is to be able to generate a source code file and get it to be taken in the build.

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

I'm making a .NET Core CLI tool that has to be run before the build of the project that is using it, because it (the CLI tool) generates a file that has to be included in the build.

该项目是使用新的.csproj系统创建的,而不是旧的project.json系统.

The project is created with the new .csproj system, not the old project.json one.

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

Along with my .NET Core CLI tool project, I created a library project for testing purpose.

如果我将其添加到测试库的.csproj中:

If I add this in the .csproj of the testing library:

<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工具生成的文件,则不会在编译中将其考虑在内.这意味着当文件存在时就可以了,但是这也意味着第一个构建(在克隆,清理或其他操作之后)将始终失败.

then the file generated by the CLI tool is not taken into account in the compilation if it didn't exist before. That means when the file exists, it is OK but it also means the very first build (after a clone, cleanup or what) will always fail.

我为BeforeTargets尝试了几种不同的目标,但是我找不到使它起作用的方法.我试图在Project节点的InitialTargets中设置目标,但是它也不起作用.我试图将Target节点的Outputs属性设置为CLI工具生成的文件名,但是同样,它失败了.

I tried several different targets for BeforeTargets but I couldn't find a way to make it work. I tried to set my target in the InitialTargets of the Project node, but it didn't work either. I tried to set the Outputs property of the Target node to the filename generated by the CLI tool, but same, it fails.

我发现可行的唯一解决方案是手动添加Compile指令,如下所示:

The only solution I found that worked is to manually add a Compile directive, as follow:

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

目前该解决方案还可以,但是文件名可能会根据CLI工具选项而更改,这将使文件名在两个位置都必须进行更改,如下所示:

This solution is fine for the moment, but the filename may change based on the CLI tool options, and this would make two places where a filename would have to be updated on change, like the following:

<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_FILENAME_HERE.CS出现两次)

(see CUSTOM_FILENAME_HERE.CS appears twice)

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

I know I could use a constant, as follow:

<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>

但是我对这种方法不满意,假设它仍然是简化版本,那么对于lambda用户来说,集成起来变得太复杂了,因为CLI工具可以采用其他几个选项,这意味着可以使用其他变量, bla bla bla.

but I'm not satisfied with this approach, it makes things way too complicated for a lambda user to integrate, assuming that this is still a simplified version, because the CLI tool can take several other options, meaning having other variables, bla bla bla.

我正在使用.NET Core SDK 1.0.1.

I'm using .NET Core SDK 1.0.1.

对于冗长的问题和我对msbuild的build惜感到抱歉.

Sorry for the lengthy question and my noobness with msbuild.

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

Thanks in advance for your time and help.





旁注:在构建前事件中调用dotnet my-cli-tool,例如:

Side note: calling dotnet my-cli-tool in pre-build event, as in:

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

根本不起作用,出现以下错误:

doesn't work at all, I get the following error:

代码:MSB3073 说明:命令"dotnet my-cli-tool"以代码1退出. 项目:测试库项目,而不是工具 文件:C:\ Program Files(x86)\ Microsoft Visual Studio \ 2017 \ Community \ MSBuild \ 15.0 \ Bin \ Microsoft.Common.CurrentVersion.targets 线:4935

Code: MSB3073 Description: The command "dotnet my-cli-tool" exited with code 1. Project: the testing library project, not the tool one File: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets Line: 4935

不过,以下方法可以正常工作:

Though, the following works fine:

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

所以这不是预构建事件的错误.

so this is not a bug with the pre build events.

无论如何,这是另一个我暂时不在乎的故事.

Anyway this is another story which I don't care much about for the moment.

推荐答案

.NET SDK称其为默认项"是对项目文件进行静态评估的一部分-在运行任何目标之前.因此,您需要一个在需要@(Compile)项之前运行的目标.

The "default items" as the .NET SDK calls it are part of the static evaluation of the project file - before any target is run. So you'll need a target that is run before the @(Compile) items are needed.

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

The trick is to include files added to the filesystem after the custom tool is run. This can be done by re-scanning all files and excluding those already part of the project inside a target that is run before the build:

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

这篇关于生成任务之前是否有.NET Core CLI预先安装?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆