Когда мы должны называть цель, используя "DependsOnTargets" и <CallTarget>?

Насколько я знаю, на данный момент мы можем вызывать другие цели из цели с помощью атрибута DependsOnTargets или с помощью задачи <CallTarget ...>

Мой вопрос в том, когда мы должны использовать каждый случай?

Ответ 1

MSBuild предоставляет различные способы вызова цели:

Использование CallTarget - явный подход, вы начинаете со своей первой цели и явно вызываете каждую цель в CallTarget вам порядке.

В то время как DependsOnTargets является неявным подходом, MSBuild определяет порядок вызова, проверяя зависимость целей.

Между CallTarget и DependsOnTargets нет разницы в количестве времени, в течение которого цель может выполняться: цель никогда не будет запускаться дважды в течение одной сборки (кроме случаев, когда вы используете задачу MSBuild с другим свойством)

Ограничение CallTarget

Одно ограничение CallTarget связано с динамическими элементами и свойством: вы не можете получить доступ к элементу или свойству, которые вы создали в цели в другой цели, которая называется CallTarget:

<Target Name="Caller">
  <CreateProperty Value="MyValue">
    <OutputTaskParameter="Value" PropertyName="NewProperty"/>
  </CreateProperty>
  <CallTarget Targets="Called"/>
</Target>

<Target Name="Called">
  <Message Text="$(NewProperty)"/>
</Target>

Динамические свойства не публикуются до тех пор, пока цель, создавшая их, не будет выполнена. У вас нет этой проблемы с использованием DependsOnTarget

Что я должен использовать?

Вы должны использовать DependsOnTargets для целей, которые должны быть выполнены перед вашей целью. И CallTarget для цели, чтобы выполнить после вашей цели. Вот так Microsoft делает это.

<Target Name="CoreCompile"
        DependsOnTargets="$(CoreCompileDependsOn)">
  <!-- Target execution -->
  <Csc ... />
  ...

  <!-- Targets to execute after -->
  <CallTarget Targets="$(TargetsTriggeredByCompilation)"/>      
</Target>

Ответ 2

Критическая разница заключается в том, что цель, указанная в DependsOnTarget , не будет выполняться, если она уже выполнена ранее. Таким образом, несколько целей могут иметь одинаковую зависимость, но только первая цель будет запускать ее выполнение (см. Документацию MSDN).

Вы можете подумать об этом, сказав: "Убедитесь, что эта цель уже выполнена, и выполните ее, если она не имеет значения."

CallTarget будет просто выполнять заданный объект, независимо от того, выполнялся ли он ранее или нет.