4

我一直在编写一个基于 MSBuild 的构建系统,并且到了项目的最后,我需要通过批处理三个变量来运行一个 msbuild 文件 88 次:

配置=调试;测试版;释放; 评估
平台 = x86;x64
语言 = CN;CS; 德; CN; ES; 法兰西; 它; J.P; KO; PL; 台湾

我要构建:
“调试 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>
4

2 回答 2

7

感谢Anders Ljusberg在几年前发布了这个问题的答案。解决方案是使用 CreateItem 任务将各个 ItemGroup 组合成一个 ItemGroup。每个项目的叉积需要一次完成一个到新的 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" />
于 2010-10-08T20:00:03.537 回答
0

将各个 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" />
于 2015-09-25T13:02:47.740 回答