Когда мы должны вызывать цель, используя 'DependsOnTargets' и <CallTarget>?
Насколько я знаю, на данный момент мы можем вызывать другие цели изнутри цели, используя атрибут DependsOnTargets
или с помощью задачи <CallTarget ...>
У меня вопрос, когда мы должны использовать каждый случай?
2 ответа
MSBuild предоставляет различные способы вызова цели:
- Задача MSBuild
- Задача CallTarget
- Целевой атрибут DependsOnTarget
- Атрибуты цели BeforeTargets и AfterTargets в MSBuild 4
С помощью 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>
Критическим отличием является то, что цель, указанная в DependsOnTarget , не будет выполняться, если она уже была выполнена ранее. Таким образом, несколько целей могут иметь одинаковую зависимость, но только первая цель будет запускать ее выполнение ( см. Документацию MSDN).
Вы можете думать об этом как о том, что "убедитесь, что эта цель уже выполнена, и выполните ее, если она не выполнила".
CallTarget просто выполнит указанную цель независимо от того, выполнялась она ранее или нет.