我无法区分这两者。请帮忙!
答案 0 :(得分:66)
定义在目标可以执行之前必须执行的目标。
<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
表示目标应在指定目标之前或之后运行。
<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>
BeforeTargets
和AfterTargets
可用于扩展现有构建流程。
例如,使用此属性,您可以在 CoreCompile (在Microsoft.CSharp.targets 中定义)之前轻松执行目标。如果没有它,您将不得不覆盖属性CoreCompileDependsOn
。
如果没有定义任何扩展点(AfterTargets
在目标的末尾,并且你可以覆盖一个属性,那么没有CallTarget
你就无法轻易地在另一个目标之后执行一个目标。
在同一目标上使用DependsOnTargets
,BeforeTargets
和AfterTargets
时,执行顺序为:
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,那么您有两个选择:
将目标B修改为:DependsOnTargets =“A”。
将目标A修改为:BeforeTargets =“B”。
如果您无法修改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 中提到的是“BeforeTargets
和 AfterTargets
无论条件如何都运行,而 DependsOnTargets
(和目标本身)被跳过当条件评估为假时"
<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>
<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>