Пакетная обработка MSBuild по трем независимым переменным

Я писал систему сборки на основе MSBuild, и я подошел к концу проекта, где мне нужно по существу запустить один файл msbuild 88 раз путем группирования по трем переменным:

Конфигурация = Отладка; Бета; Выпускать; Оценка
Platform = x86; x64
Язык = CN; CS; DE; EN; ES; FR; ЭТО; JP; КО; PL; TW

Я хочу построить:
«Отладка x86 CN», «Отладка x86 CS», ... «Отладка x86 TW»
«Отладка x64 CN», ...

Я, конечно, могу определить 88 из них:

<ItemGroup>
  <ToBuild Include="Debug_x86_CN">
    <Configuration>Debug</Configuration>
    <Platform>x86</Platform>
    <Language>EN</Language>
  </ToBuild>
<ItemGroup>

А затем пакет на основе метаданных. Но что за тягость! Могу ли я создать 88 перестановок в коде, поэтому добавить язык так же просто, как добавить три символа в ItemGroup:

<ItemGroup>
  <AllConfigurations Include="Beta; Release; Evaluation;"/>
  <AllPlatforms Include="x86; x64" />
  <AllLanguages Include="CN; CS; DE; EN; ES; FR; IT; JP; KO; PL; TW" />
</ItemGroup>

person Brian Gillespie    schedule 08.10.2010    source источник


Ответы (2)


Спасибо Андерсу Люсбергу за публикацию ответа на этот вопрос много лет назад. Решение состоит в том, чтобы использовать задачу CreateItem для объединения отдельных ItemGroups в одну ItemGroup. Перекрестное произведение каждого элемента необходимо выполнять по одному в новую группу элементов (в данном случае _Config_X_Language и _Config_X_Language_X_Platform), чтобы предотвратить утечку пустых метаданных (если вы попытаетесь повторно использовать _Config_X_Language, вы получите элементы с пустой платформой, n дополнение к платформам в $ (Platform).

<ItemGroup>
  <Configuration Include="Beta; Release; Evaluation;"/>
  <Platform Include="x86; x64" />
  <Language Include="CN; CS; DE; EN; ES; FR; IT; JP; KO; PL; TW" />
</ItemGroup>

<!-- Create an ItemGroup that is the cross product of Configuration and Language: -->
<CreateItem Include="@(Configuration)" AdditionalMetadata="Language=%(Language.Identity);" >
  <Output ItemName="_Config_X_Language" TaskParameter="Include"/>
</CreateItem>
<!-- Create another ItemGroup that is the cross product of _Configuration_X_Language and Platform: -->
<CreateItem Include="@(_Config_X_Language)" AdditionalMetadata="Platform=%(Platform.Identity);" >
  <Output ItemName="_Config_X_Language_X_Platform" TaskParameter="Include"/>
</CreateItem>

<!-- Task batch over each unique set of metadata on AllBuilds -->
<MSBuild Projects="myproject.msbuild"
          Properties="Configuration=%(_Config_X_Language_X_Platform.Identity);
                      Platform=%(_Config_X_Language_X_Platform.Platform);
                      Language=%(_Config_X_Language_X_Platform.Language);"
          Targets="MyTarget"
          BuildInParallel="true" />
person Brian Gillespie    schedule 08.10.2010

Хорошая идея - объединить отдельные ItemGroup в одну ItemGroup. Однако при использовании этого метода MSBuild строит проекты, игнорируя атрибут BuildInParallel (все проекты строятся последовательно). Итак, вам нужно чем-то дополнить скрипт:

<ItemGroup>
  <Configuration Include="Beta; Release; Evaluation;"/>
  <Platform Include="x86; x64" />
  <Language Include="CN; CS; DE; EN; ES; FR; IT; JP; KO; PL; TW" />
</ItemGroup>

<!-- Create an ItemGroup that is the cross product of Configuration and Language: -->
<CreateItem Include="@(Configuration)" AdditionalMetadata="Language=%(Language.Identity);" >
  <Output ItemName="_Config_X_Language" TaskParameter="Include"/>
</CreateItem>
<!-- Create another ItemGroup that is the cross product of _Configuration_X_Language and Platform: -->
<CreateItem Include="@(_Config_X_Language)" AdditionalMetadata="Platform=%(Platform.Identity);" >
  <Output ItemName="_Config_X_Language_X_Platform" TaskParameter="Include"/>
</CreateItem>

<!--Creating groups for projects to build-->
<!--In the attribute AdditionalMetadata sign '=' is changed to '%3D', and the sign ';'' changed to '%3B'-->
<CreateItem Include="myproject.msbuild" AdditionalMetadata="Properties=
                                                            Configuration%3D%(_Config_X_Language_X_Platform.Identity)%3B
                                                            Platform%3D%(_Config_X_Language_X_Platform.Platform)%3B
                                                            Language%3D%(_Config_X_Language_X_Platform.Language)" >
  <Output ItemName="ProjectToBuild" TaskParameter="Include"/>
</CreateItem>

<!--Task batch build all projects parallel -->
<MSBuild Projects="@(ProjectToBuild)"
         Targets="MyTarget"
         BuildInParallel="true"
         StopOnFirstFailure="true" />
person stepnaz    schedule 25.09.2015