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>