2010-10-08 39 views
4

我一直在写基于MSBuild的构建系统,并且是在项目结束时,我需要基本运行一个MSBuild的文件通过分批88次以上三个变量:的MSBuild配料上三个独立变量

配置=调试;测试版;发布;评估
平台= x86; x64
Language = CN; CS; DE; EN; ES; FR;它; J.P; KO; PL; TW

我想建立:
“调试的x86 CN”, “调试的x86 CS” ...... “调试86 TW”
“调试64 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> 

回答

7

感谢Anders Ljusberg为前张贴的答案,这几年。解决方案是使用CreateItem任务将各个ItemGroups组合成一个ItemGroup。每个项目的交叉产品需要一次一个到一个新的ItemGroup(在这种情况下是_Config_X_Language和_Config_X_Language_X_Platform),以防止空元数据泄漏(如果您尝试重用_Config_X_Language,您将获得具有空平台的项目,施氮的平台,$(平台)。

<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" /> 
+0

哦,非常欢迎/ Anders ;-) – CodingInsomnia 2011-04-11 20:40:50

0

这是个别ItemGroups合而为一的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" />