'DependsOnTargets'和'AfterTargets'有什么区别?

时间:2010-05-18 08:49:22

标签: msbuild

我无法区分这两者。请帮忙!

7 个答案:

答案 0 :(得分:66)

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

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
  • 如果你有多个目标应该在同一个指定目标之前或之后运行,它们将按声明顺序执行

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

BeforeTargetsAfterTargets可用于扩展现有构建流程

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

如果没有定义任何扩展点(AfterTargets在目标的末尾,并且你可以覆盖一个属性,那么没有CallTarget你就无法轻易地在另一个目标之后执行一个目标。

DependsOnTargets,BeforeTargets和AfterTargets执行顺序?

在同一目标上使用DependsOnTargetsBeforeTargetsAfterTargets时,执行顺序为:

  • 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
    

答案 1 :(得分:6)

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

  

这使项目作者可以扩展现有的一组目标   直接修改它们。

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

  1. 将目标B修改为:DependsOnTargets =“A”。

  2. 将目标A修改为:BeforeTargets =“B”。

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

答案 2 :(得分:4)

更简洁的from this GitHub issue on Microsoft Docs

<Target Name="x" DependsOnTargets="y" />的意思是:

如果要运行x,则必须首先运行y

<Target Name="a" AfterTargets="b" />的意思是:

如果某项运行b,则在其后运行a

答案 3 :(得分:2)

虽然之前提供的其他答案都是正确的,但我认为他们没有提及我认为AfterTargets超过DependsOnTargets的主要好处。

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

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

<Target Name="SomeTarget" DependsOnTargets="$(SomeTargetDependsOnTargets)">
 ...
</Target>

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

<SomeTargetDependsOnTargets>
    $(SomeTargetDependsOnTargets);Dependency3
</SomeTargetDependsOnTargets>

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

另一方面,

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

答案 4 :(得分:1)

DependsOnTarget - 我们假设您有两个任务:1 - 构建项目,2 - 复制所有内容。您可以通过执行任务2开始构建,然后在任务声明中定义它的依赖项。因此,如果您定义任务2取决于任务1,则构建过程将启动并执行任务1,然后执行2。

AfterTargets - 更简单意味着只有在其他目标之后执行的任务。因此,从上面的示例 - 在任务1 - 构建项目之后执行任务2。

我希望这会有所帮助

答案 5 :(得分:0)

主要有两个区别:

  • 第一:在dependsOnTargets属性中指定的目标是 在AfterTargets中执行。

  • 第二个:如果执行了AfterTargets属性中指定的目标之一 这个目标也会在之后执行(我的意思是目标 您在其中指定AfterTargets属性),对于 那些在DependsOnTargets中。

答案 6 :(得分:0)

另一个不同之处,在另一个 answer 中提到的是“BeforeTargetsAfterTargets 无论条件如何都运行,而 DependsOnTargets(和目标本身)被跳过当条件评估为假时"

  1. 在下面的代码中,即使没有执行第一个目标,也会执行第二个目标:
    <Target Name="FirstTarget" AfterTargets="PostBuildEvent" Condition="'False'">
        <Message Text="This target is never executed" />
    </Target>

    <Target Name="SecondTarget" AfterTargets="FirstTarget">
        <Message Text="SecondTarget is executed" />
    </Target>
  1. 在下面的代码中,第二个目标没有被执行:
    <Target Name="FirstTarget" AfterTargets="PostBuildEvent" Condition="'False'">
        <Message Text="This target is never executed" />
    </Target>

    <Target Name="SecondTarget" DependsOnTargets="FirstTarget">
        <Message Text="SecondTarget is executed" />
    </Target>