Jul*_*rau 71

DependsOnTargets

定义在执行目标之前必须执行的目标.

<Target Name="DependsOn" DependsOnTargets="DependencyTarget1;DependencyTarget2">
  <Message Text="Target : DependsOn"/>
</Target>

<Target Name="DependencyTarget2">
  <Message Text="Target : DependencyTarget2"/>
</Target> 

<Target Name="DependencyTarget1">
  <Message Text="Target : DependencyTarget1"/>
</Target> 

Output
> Target : DependencyTarget1
> Target : DependencyTarget2
> Target : DependsOn
Run Code Online (Sandbox Code Playgroud)

BeforeTargets和AfterTargets(仅在MSBuild 4中可用)

表示目标应在指定目标之前或之后运行.

<Target Name="BeforeAndAfter">
  <Message Text="Target : BeforeAndAfter"/>
</Target>

<!-- BeforeTarget1 will run BEFORE target "BeforeAndAfter" -->
<Target Name="BeforeTarget" BeforeTargets="BeforeAndAfter">
  <Message Text="BeforeTarget run before : BeforeAndAfter"/>
</Target> 

<!-- BeforeTarget1 will run AFTER target "BeforeAndAfter" -->
<Target Name="AfterTarget" AfterTargets="BeforeAndAfter">
  <Message Text="AfterTarget run after : BeforeAndAfter"/>
</Target> 

Output
> BeforeTarget run before : BeforeAndAfter
> Target : BeforeAndAfter
> AfterTarget run after : BeforeAndAfter
Run Code Online (Sandbox Code Playgroud)
  • 如果您具有应在同一指定目标之前或之后运行的倍数目标,则它们将按声明顺序执行:

    <Target Name="BeforeAndAfter">
      <Message Text="Target : BeforeAndAfter"/>
    </Target>
    
    <!-- 
       BOTH BeforeTarget1 and BeforeTarget2 should run before target "BeforeAndAfter"
    -->
    <Target Name="BeforeTarget1" BeforeTargets="BeforeAndAfter">
      <Message Text="BeforeTarget1 run before : BeforeAndAfter"/>
    </Target> 
    
    <Target Name="BeforeTarget2" BeforeTargets="BeforeAndAfter">
      <Message Text="BeforeTarget2 run before : BeforeAndAfter"/>
    </Target> 
    
    Run Code Online (Sandbox Code Playgroud)

BeforeTargets并可AfterTargets用于扩展现有的构建过程.

例如,使用此属性,您可以在CoreCompile(在Microsoft.CSharp.targets中定义)之前轻松执行目标.没有它你将不得不覆盖该属性CoreCompileDependsOn.

如果没有AfterTargets,你有没有办法一个又一个容易执行的目标,如果没有扩展点定义(CallTarget在目标与您可以覆盖属性的结束)

DependsOnTargets,BeforeTargets和AfterTargets执行顺序?

DependsOnTargets,BeforeTargetsAfterTargets在相同的靶使用的,执行的顺序是:

  • DependsOnTargets
  • BeforeTargets
  • 目标
  • AfterTargets

    <Target Name="MainTarget" DependsOnTargets="DefaultDependsOn">
      <Message Text="Target : MainTarget"/>
    </Target>
    
    <Target Name="DefaultDependsOn">
      <Message Text="Target : DefaultDependsOn"/>
    </Target>
    
    <Target Name="DefaultBeforeTarget" BeforeTargets="MainTarget">
      <Message Text="Target : DefaultBeforeTarget"/>
    </Target>
    
    <Target Name="DefaultAfterTarget" AfterTargets="MainTarget">
      <Message Text="Target : DefaultAfterTarget"/>
    </Target> 
    
    Output
    > Target : DefaultDependsOn
    > Target : DefaultBeforeTarget
    > Target : MainTarget
    > Target : DefaultAfterTarget
    
    Run Code Online (Sandbox Code Playgroud)

  • 我认为你的执行顺序错了; 它应该是`AfterTargets - >目标 - > BeforeTargets`. (3认同)
  • 我不明白为什么这个答案是最受好评的。它没有解释AfterTargets和DependsOnTargets之间的行为差​​异。[aprelev的评论](/sf/ask/199899941/#comment83741182_34099077)实际上回答了它。 (2认同)

aoe*_*lks 13

更简洁地来自 Microsoft Docs 上的这个 GitHub 问题

<Target Name="x" DependsOnTargets="y" /> 方法:

如果有东西要运行xy必须先运行。

<Target Name="a" AfterTargets="b" /> 方法:

如果有什么东西在跑b,那就追着a它跑。


Mar*_*lug 10

虽然之前提供的其他答案是正确的,但我认为他们没有提到我认为AfterTargetsover的主要好处DependsOnTargets

DependsOnTargets从 MSBuild 开始就已经存在。, 的问题DependsOnTargets在于它需要目标作者明确允许可扩展性。这是通过定义一个用作DependsOnTargets值的属性来完成的,如下所示:

<PropertyGroup>
   <SomeTargetDependsOnTargets>
     Dependency1;Dependency2
   </SomeTargetDependsOnTargets>
</PropertyGroup>

<Target Name="SomeTarget" DependsOnTargets="$(SomeTargetDependsOnTargets)">
 ...
</Target>
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过SomeTargetDependsOnTargets如下修改属性来添加依赖项:

<SomeTargetDependsOnTargets>
    $(SomeTargetDependsOnTargets);Dependency3
</SomeTargetDependsOnTargets>
Run Code Online (Sandbox Code Playgroud)

这种设计的问题在于,如果作者只是简单地内联Dependency1;Dependency2而不是将其提取到属性中,则无法从外部修改它以允许自定义。

AfterTargets,另一方面,不要求原始目标作者已将DependsOnTargets值显式提取到属性中以允许可扩展性。


Ste*_*ins 5

我认为答案要简单得多.DependsOnTargets和AfterTargets的效果基本相同.BeforeTargets和AfterTargets的原因(来自Microsoft文档):

这使项目作者可以扩展现有的一组目标,而无需直接修改它们.

因此,如果您有一个现有目标B并且想要添加必须首先执行的新目标A,那么您有两个选择:

  1. 将目标B修改为:DependsOnTargets ="A".

  2. 将目标A修改为:BeforeTargets ="B".

如果您无法修改B(例如,它是现有的Microsoft目标),那就是您需要BeforeTargets的时候.

  • @史蒂夫·罗宾斯(Steve Robbins)评论您的第二句话,*不,它们不相同*。有一个奇怪的转折,其他所有人都没有提到:考虑在`msbuild / t:A`中构建目标A。当使用`DependsOnTargets`属性指定依赖关系时,以这种方式调用msbuild不会构建目标B *。但是,当使用`AfterTargets`属性指定依赖项时,以这种方式调用msbuild会构建目标B *。 (4认同)