帮助我理解为什么目标A(和D)运行,而目标B不时调用MSBuild如下:
msbuild /target:C
在这个简单的项目上(省略了XML标题):
<Target Name="A" BeforeTargets="C">
<Message Text="Inside target A" />
</Target>
<Target Name="B">
<Message Text="Inside target B" />
</Target>
<Target Name="C" DependsOnTargets="B" Condition="'False'">
<Message Text="Inside target C" />
</Target>
<Target Name="D" AfterTargets="C">
<Message Text="Inside target D" />
</Target>
- 评估目标的
Condition
属性。如果Condition
属性存在且评估为false
,则目标不会被执行,并且对构建没有进一步影响。- 在执行目标之前,会运行其
DependsOnTargets
目标。- 在执行目标之前,将运行在
BeforeTargets
属性中列出目标的任何目标。- ...
- 执行或跳过目标后,将运行在
AfterTargets
属性中列出目标的任何目标。
这就是为什么只能合理地断定,因为谓词在执行目标之前对于DependsOnTargets
和BeforeTargets
属性都是相同的,要么都是应该运行A
和B
,或者不运行。
据我的理解,由于要求MSBuild运行目标A
,因此无法运行B
和C
,这是有条件的,Condition
计算为{ {1}}。
P.S。 MSBuild 15.5.180.51428
答案 0 :(得分:0)
这似乎是MSBuild 4.0 false
,BeforeTargets
属性与旧版AfterTargets
属性之间存在特殊差异的情况。
DependsOnTargets
是什么,{p> BeforeTargets
和AfterTargets
都会运行,而当Condition
评估为DependsOnTargets
时会跳过Condition
(和目标本身)
对false
source code的调查表明
使用TargetBuilder::ProcessTargetStack()
和AfterTargets
属性指定的目标unconditionally pushed到要通过BeforeTargets
和afterTargets
列表构建的目标堆栈上{ {1}}和beforeTargets
方法。
通过GetTargetsWhichRunAfter()
方法返回的GetTargetsWhichRunBefore()
列表,DependsOnTargets
属性指定的目标为pushed when non-null到目标堆栈。
dependencies
属性实际上仅在TargetEntry::GetDependencies()
方法中进行评估,该方法返回empty list when condition is present and resolves to false
,否则返回依赖项列表。
target build order中的描述似乎与调度背后的逻辑相矛盾;正确的顺序似乎是:
- 在执行目标之前,将运行在
Condition
属性中列出目标的任何目标。- 评估目标的
TargetEntry::GetDependencies()
属性。如果BeforeTargets
属性存在且评估为Condition
,则不会执行目标及其Condition
目标。- ...
- 执行或跳过目标后,将运行在
false
属性中列出目标的任何目标。
(母语人士可能会更好地记录这一点。)
P.S。如果我错了,请纠正我,但我来自C背景,check
DependsOnTargets
对我来说似乎是多余的,因为AfterTargets
变量初始化为
if (null != dependencies)
和dependencies
返回dependencies = currentTargetEntry.GetDependencies(...)
的{{1}} regardless的初始化实例:
GetDependencies