我假设当 msbuild
即将编译源代码文件时,它会根据 Include
和 Exclude
生成要构建的文件列表项目规则.
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="PATHTOCUSTOM_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 PATHTOCUSTOM_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>PATHTOCUSTOM_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 工具可以采用其他几个选项,这意味着有其他变量,呜呜呜.
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 的菜鸟.
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 Studio2017CommunityMSBuild15.0BinMicrosoft.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 Studio2017CommunityMSBuild15.0BinMicrosoft.Common.CurrentVersion.targets Line: 4935
虽然,以下工作正常:
<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 pre?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!