Msbuild 我们应该在什么时候使用';依赖于目标';及<;CallTarget>;?
据我所知,目前我们可以使用属性Msbuild 我们应该在什么时候使用';依赖于目标';及<;CallTarget>;?,msbuild,Msbuild,据我所知,目前我们可以使用属性DependsOnTargets或使用任务从目标内部调用其他目标 我的问题是我们应该在什么时候使用每种情况?关键的区别在于,DependsOnTarget中指定的目标如果之前已经执行过,则不会执行。这样,多个目标可以具有相同的依赖关系,但只有第一个目标将触发其执行() 您可以将其视为“确保此目标已执行,如果尚未执行,则执行它。” 将只执行指定的目标,而不管它以前是否执行过。MSBuild提供了调用目标的不同方法: 目标属性 MSBuild 4中的目标属性 使
DependsOnTargets
或使用任务
从目标内部调用其他目标
我的问题是我们应该在什么时候使用每种情况?关键的区别在于,DependsOnTarget中指定的目标如果之前已经执行过,则不会执行。这样,多个目标可以具有相同的依赖关系,但只有第一个目标将触发其执行() 您可以将其视为“确保此目标已执行,如果尚未执行,则执行它。”
将只执行指定的目标,而不管它以前是否执行过。MSBuild提供了调用目标的不同方法:
- 目标属性
- MSBuild 4中的目标属性
CallTarget
是一种显式方法,从第一个目标开始,按照您想要的顺序显式调用每个目标
鉴于DependsOnTargets
是一种隐式方法,MSBuild通过检查目标的依赖关系来推断调用顺序
CallTarget
和DependsOnTargets
在目标可以运行的时间上没有区别:目标在单个构建过程中不会运行两次(除非您)
调用目标的限制
CallTarget
的一个限制是动态项和属性:您不能访问在另一个调用CallTarget的目标中的目标中创建的项或属性:
<Target Name="Caller">
<CreateProperty Value="MyValue">
<OutputTaskParameter="Value" PropertyName="NewProperty"/>
</CreateProperty>
<CallTarget Targets="Called"/>
</Target>
<Target Name="Called">
<Message Text="$(NewProperty)"/>
</Target>
这不是真的,一个目标在一个构建过程中永远不会运行两次,即使使用CallTarget.+1进行详细解释。我个人尽量避免使用CallTarget,而是使用DependsOnTargets。
CallTarget
违背了MSBuild的原则,即构建目标的依赖关系树并运行它。这有点像C++中使用<代码> Goto 。请原谅我的无知…如果当前项目依赖于另一个项目中的工件,那么对于DependsOnTargets
,我们应该使用什么表达式?例如,从Bar.vcxproj
中,我无法得到像DependsOnTargets=“Project=Foo.vcxproj;Configuration=Debug;Platform=Win32;
这样的东西来工作。MS文档绝对糟糕。他们告诉我去讨论,然后就不讨论了。@jonathan有什么缺点吗(除了答案中的缺点之外)通过这样做,我发现CallTarget
更具可读性。
<Target Name="CoreCompile"
DependsOnTargets="$(CoreCompileDependsOn)">
<!-- Target execution -->
<Csc ... />
...
<!-- Targets to execute after -->
<CallTarget Targets="$(TargetsTriggeredByCompilation)"/>
</Target>