Как вы управляете порядком сборки зависимых от брата целей с помощью msbuild?

В моем проекте у меня есть два оператора импорта:

<Import Project="<TransformConfigLocation>" />
<Import Project="<PackageLocation>" />

У каждой цели есть группа свойств, определенная так:

<PropertyGroup>
    <BuildDependsOn>
        $(BuildDependsOn);
        TransformConfig
    </BuildDependsOn>
</PropertyGroup>

<PropertyGroup>
    <BuildDependsOn>
        $(BuildDependsOn);
        Package
    </BuildDependsOn>
</PropertyGroup>

Я хотел бы гарантировать, что TransformConfig всегда запускается до Package. Я не контролирую ни одну из зависимых целей и предпочел бы не редактировать их явно, потому что эти изменения будут стираться каждый раз, когда я обновляю эти цели через NuGet. Цель Package последовательно запускается первой, что нежелательно.

Это возможно?

2 ответа

Решение

Простой ответ заключается в том, что порядок импорта имеет значение. Подробнее о том, почему, смотрите ответ @Seva Titov и наш последующий разговор.

Я настоятельно рекомендую http://amzn.com/0735645248 для тщательного анализа по этой теме.

В рамках проекта порядок сборки гарантированно соответствует правилам целевого порядка сборки MSBuild. Здесь нет условий гонки, все сериализовано. Цитата по ссылке выше:

<Target Name="Serve" DependsOnTargets="Chop;Cook" />

сообщает MSBuild, что цель Serve зависит от цели Chop и цели Cook. MSBuild запускает цель Chop, а затем запускает цель Cook перед запуском цели Serve.

Обратите внимание, что если какая-либо другая цель, которая выполняется до "Служить", имеет какие-либо цели Chop/Cook в качестве своих зависимостей или перечислила их в BeforeTargets/AfterTargets, это может повлиять на порядок. Например, если у вас есть этот набор целей:

 <Target Name="One" DependsOnTargets="Two;Three" />
 <Target Name="Two" DependsOnTargets="TargetB" />
 <Target Name="Three" DependsOnTargets="TargetA;TargetB;" />

и вы строите "One", тогда порядок сборки будет следующим:

TargetB
Two
TargetA
// skip TargetB because it was already run
Three
One

Итак, в вашем случае, если предположить, что TargetB не указан в качестве зависимости от каких-либо предыдущих целей, список $(BuildDependsOn) будет выполнен в том порядке, в котором перечислены цели, что будет ...;TargetA;TargetB,

Другие вопросы по тегам