简体   繁体   English

使 MSBuild 目标依赖于来自不同项目的目标

[英]Make MSBuild target depend on target from a different project

I have a setup where I have an API (ASP.NET) project and a test project to test the API.我有一个设置,我有一个 API (ASP.NET) 项目和一个测试项目来测试 API。 I use NSwag to auto-generate an API client in the test project through the following steps:我使用 NSwag 通过以下步骤在测试项目中自动生成 API 客户端:

  1. After the API project is built, use NSwag to generate an OpenAPI definition from the produced DLL构建 API 项目后,使用 NSwag 从生成的 DLL 生成 OpenAPI 定义
  2. Before building the API test project, use the OpenAPI definition produced in (1) to generate/update a C# API client在构建 API 测试项目之前,使用 (1) 中生成的 OpenAPI 定义来生成/更新 C# API 客户端

These steps are done through MSBuild targets:这些步骤是通过 MSBuild 目标完成的:

<!-- API Project -->
<Project Sdk="Microsoft.NET.Sdk.Web">
  <Target Name="GenerateApiDefinition" BeforeTargets="AfterBuild">
    <!-- Use NSwag to generate an openapi.json output file based on the built DLL -->
  </Target>
</Project>

<!-- API test project -->
<Project Sdk="Microsoft.NET.Sdk">
  <ProjectReference Include="..\ApiProject\ApiProject.csproj" />

  <Target Name="GenerateApiClient" BeforeTargets="BeforeBuild">
    <!-- Consumes the openapi.json file generated by project A to generate/update a C# API client class -->
  </Target>
</Project>

This works when building with Visual Studio or MSBuild, because the projects are built sequentially in order.这在使用 Visual Studio 或 MSBuild 构建时有效,因为项目是按顺序构建的。 It will fully build the API project first, then it will build the test project.它将首先完全构建 API 项目,然后构建测试项目。

But it doesn't work when I try to build the clean solution using dotnet build .但是当我尝试使用dotnet build干净的解决方案时它不起作用 I will receive an error for the test project explaining that the openapi.json file does not exist.我将收到测试项目的错误,说明openapi.json文件不存在。 This error will only happen the first time I build -- if I use dotnet build again, the build will work because the file was generated in the previous build.这个错误只会在我第一次构建时发生——如果我再次使用dotnet build ,构建将起作用,因为该文件是在之前的构建中生成的。

It seems that dotnet build somehow builds the projects in parallel, at least to some degree.似乎dotnet build以某种方式并行构建项目,至少在某种程度上是这样。 I am thinking the test project cannot compile before the API project is compiled since it has a project reference, but maybe the pre-build steps are performed in parallel?我认为测试项目在编译 API 项目之前无法编译,因为它有项目引用,但也许预构建步骤是并行执行的?

I have tried to change the BeforeTargets attribute to Compile and other values, but I am stuck with either getting the error for the missing API definition file, or an error explaining the auto-generated ApiClient class was not generated, indicating that I am hooking the target in either too early (before the GenerateApiDefinition target has completed) or too late (after the build process needs to have the class defined).我试图将BeforeTargets属性更改为Compile和其他值,但我遇到了丢失 API 定义文件的错误,或者解释未生成自动生成的ApiClient类的错误,这表明我正在挂钩目标太早(在GenerateApiDefinition目标完成之前)或太晚(在构​​建过程需要定义类之后)。

What I would really like to do is to make the GenerateApiClient target depend on the GenerateApiDefinition target in the other project.我真正想做的是使GenerateApiClient目标依赖于另一个项目中的GenerateApiDefinition目标。 I don't know if it is possible to make target dependencies between projects?不知道是否可以在项目之间建立目标依赖关系? Is there another way I can go about this?我还有其他方法可以解决这个问题吗?

There isn't a way to have the GenerateApiClient target in the 'API test' project depend on the GenerateApiDefinition target in the 'API' Project.没有办法让“API 测试”项目中的GenerateApiClient目标依赖于“API”项目中的GenerateApiDefinition目标。

MSBuild will try to build projects in parallel. MSBuild 将尝试并行构建项目。 If the test project is supplied to the dotnet build command, the project reference in the test project will be used to find and build the API project.如果将测试项目提供给dotnet build命令,则测试项目中的项目引用将用于查找和构建 API 项目。 Clearly the compile step in the test project needs the API project to be up to date.显然,测试项目中的编译步骤需要 API 项目是最新的。

I tested the following change to the 'API Test' project and it seems to solve the issue:我测试了对“API 测试”项目的以下更改,它似乎解决了这个问题:

  <Target Name="GenerateApiClient" BeforeTargets="CoreCompile">

It would seem that MSBuild considers that targets before the build (ie BeforeTargets="BeforeBuild" ) can be run in parallel.似乎 MSBuild 认为构建之前的目标(即BeforeTargets="BeforeBuild" )可以并行运行。 Changing the GenerateApiClient target to depend on CoreCompile instead seems to cause MSBuild to treat it as a target that must wait for the API build to complete (which the CoreCompile target itself must do).GenerateApiClient目标更改为依赖CoreCompile似乎会导致 MSBuild 将其视为必须等待 API 构建完成的目标( CoreCompile目标本身必须这样做)。

I created a mockup of the project setup that you described and I replicated your issue.我创建了您描述的项目设置的模型,并复制了您的问题。 Then I changed the dependency to CoreCompile .然后我将依赖项更改为CoreCompile After the change the GenerateApiClient target never ran too early.更改后GenerateApiClient目标永远不会过早运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM