У меня есть решение Visual Studio 2012 с двенадцатью конфигурациями решений. Каждая конфигурация решения независима (т.е. Выходы каждой конфигурации полностью не связаны).
Вопрос: Как я могу построить все двенадцать конфигураций за один шаг, то есть, выполнив одну команду MSBuild в командной строке и как я могу построить параллельные конфигурации?
В качестве примера, если бы было только две конфигурации: Release/AnyCPU и Debug/AnyCPU, я бы хотел, чтобы оба они были созданы в одно и то же время параллельно.
Для полноты, вот что я пробовал; У меня пока нет решения этой проблемы.
Чтобы собрать все проекты сразу, я создал новый файл проекта с целью сборки, который запускает задачу MSBuild в файле Solution для каждой конфигурации:
<Target Name="Build">
<MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Release;Platform=Win32" Targets="$(BuildCommand)" />
<MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Release;Platform=x64" Targets="$(BuildCommand)" />
<MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Release;Platform=ARM" Targets="$(BuildCommand)" />
<MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Release(ZW);Platform=Win32" Targets="$(BuildCommand)" />
<MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Release(ZW);Platform=x64" Targets="$(BuildCommand)" />
<MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Release(ZW);Platform=ARM" Targets="$(BuildCommand)" />
<MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Debug;Platform=Win32" Targets="$(BuildCommand)" />
<MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Debug;Platform=x64" Targets="$(BuildCommand)" />
<MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Debug;Platform=ARM" Targets="$(BuildCommand)" />
<MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Debug(ZW);Platform=Win32" Targets="$(BuildCommand)" />
<MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Debug(ZW);Platform=x64" Targets="$(BuildCommand)" />
<MSBuild Projects="cxxreflect.sln" Properties="SolutionDir=$(MSBuildProjectDirectory)\;Configuration=Debug(ZW);Platform=ARM" Targets="$(BuildCommand)" />
</Target>
Это отлично работает, за исключением того, что каждая задача MSBuild вызывается последовательно, поэтому нет parallelism (да, есть parallelism внутри каждой сборки конфигурации, но я действительно хотел бы получить parallelism в конфигурационных сборках).
В попытке построить конфигурации для параллельной сборки я попытался использовать свойство BuildInParallel задачи MSBuild. Я написал задачу предварительной сборки, которая сгенерировала файлы проекта для каждой конфигурации, а затем попыталась собрать все эти сгенерированные проекты параллельно:
<Target Name="PreBuild" Outputs="%(ProjectConfiguration.Identity)" Returns="%(BuildProject.Identity)">
<Message Text="Cloning Solution for Configuration: %(ProjectConfiguration.Identity)" />
<PropertyGroup>
<BuildProjectPath>$(IntPath)\%(ProjectConfiguration.Platform)\%(ProjectConfiguration.Configuration)\build.proj</BuildProjectPath>
</PropertyGroup>
<ItemGroup>
<BuildProject Include="$(BuildProjectPath)" />
</ItemGroup>
<MakeDir Directories="$(IntPath)\%(ProjectConfiguration.Platform)\%(ProjectConfiguration.Configuration)" />
<WriteLinesToFile
File="$(BuildProjectPath)"
Lines="<?xml version='1.0' encoding='utf-8'?>
<Project DefaultTargets='Build' ToolsVersion='4.0' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
<Target Name='Build'>
<MSBuild
Projects='$(SlnPath)'
Properties='
SolutionDir=$(MSBuildProjectDirectory)\%3b
Configuration=%(ProjectConfiguration.Configuration)%3b
Platform=%(ProjectConfiguration.Platform)
'
Targets='$(BuildCommand)'
/>
</Target>
</Project>"
Overwrite="true" />
</Target>
<Target Name="Build" DependsOnTargets="PreBuild">
<Message Text="%(BuildProject.Identity)" />
<MSBuild Projects="%(BuildProject.Identity)" Properties="BuildCommand=$(BuildCommand)" BuildInParallel="true" />
</Target>
К сожалению, хотя это и создает все двенадцать конфигураций, он строит их последовательно. Я предполагаю, что когда MSBuild выполняет анализ зависимостей над множеством проектов, которые будут созданы, он определяет, что все они зависят от одного и того же файла решения, поэтому он решает, что они не могут быть построены параллельно. (Это всего лишь догадка, я мог быть совершенно не прав. Я очень мало знаю о MSBuild.)
Я также использую переключатель /m при создании.