Я пытаюсь написать скрипт сборки для нашего дерева исходников.Это дерево состоит из (большого) числа решений с ссылками на сборки между ними.Я создал ItemGroup, содержащую все решения, и собираю эту ItemGroup для создания решений.
Мне также нужно скопировать некоторые выходные данные проекта в папку "exes output", каждый вих собственная папка.Я прикрепил некоторые метаданные к элементу решения, указывающие на проекты, из которых я хочу получить выходные данные.Поскольку у меня может быть потенциально более одного проекта для вывода из каждого решения, я делаю это, передавая метаданным значение, которое передается в группу объектов ItemGroup для создания группы элементов отдельно.Это работает успешно, и я могу выполнить групповую обработку этой динамически созданной ItemGroup.
Последний шаг, который я хочу сделать, который вызывает у меня головную боль, заключается в том, что для некоторых этих выходных проектовЯ хочу указать специальное имя папки.Теперь я могу сделать это, изменив метаданные внутри цели, которая выполняет работу, например:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
DefaultTargets="Build">
<!-- Define all the solutions to build, and any projects we want to handle the output of -->
<ItemGroup>
<SolutionsToBuild Include="$(MSBuildProjectDirectory)\Solution1\Solution1.sln">
<ProjectsToOutput>
$(MSBuildProjectDirectory)\Solution1\Project1A\Project1A.csproj;
$(MSBuildProjectDirectory)\Solution1\Project1B\Project1B.csproj;
</ProjectsToOutput>
</SolutionsToBuild>
<SolutionsToBuild Include="$(MSBuildProjectDirectory)\Solution2\Solution2.sln">
<ProjectsToOutput>
$(MSBuildProjectDirectory)\Solution2\Project2A\Project2A.csproj;
$(MSBuildProjectDirectory)\Solution2\Project2B\Project2B.csproj;
</ProjectsToOutput>
</SolutionsToBuild>
</ItemGroup>
<Target Name="Build">
<CallTarget Targets="DoBuild" />
</Target>
<Target Name="DoBuild" Outputs="%(SolutionsToBuild.Identity)">
<Message Text="Building project: %(SolutionsToBuild.FullPath)" />
<!-- e.g. <MSBuild Projects="%(SolutionsToBuild.FullPath)" /> -->
<PropertyGroup>
<ProjectsToOutputIncludeMask>%(SolutionsToBuild.ProjectsToOutput)</ProjectsToOutputIncludeMask>
</PropertyGroup>
<ItemGroup>
<OutputProjects Include="$(ProjectsToOutputIncludeMask)" />
<!-- Now create the OutputTo metadata -->
<!-- Default to the same name as the project file -->
<OutputProjects>
<OutputTo>%(OutputProjects.FileName)</OutputTo>
</OutputProjects>
<!-- Now override specific projects OutputTo metadata -->
<OutputProjects Condition="'%(OutputProjects.FileName)' == 'Project1A'">
<OutputTo>ArbitraryFolder1</OutputTo>
</OutputProjects>
<OutputProjects Condition="'%(OutputProjects.FileName)' == 'Project2B'">
<OutputTo>ArbitraryFolder2</OutputTo>
</OutputProjects>
</ItemGroup>
<Message Text=" Outputting project: %(OutputProjects.FullPath) -> %(OutputTo)" />
</Target>
</Project>
Однако этот сценарий сборки должен поддерживаться всеми разработчиками в команде, а не всемикого знакомы с MSBuild.Поэтому я хотел бы определить другую ItemGroup в верхней части скрипта, которая определяет любые специальные имена.Затем они могут игнорировать все цели и задачи и просто поддерживать группы элементов, например:
<ItemGroup>
<SolutionsToBuild Include="$(MSBuildProjectDirectory)\Solution1\Solution1.sln">
<ProjectsToOutput>
$(MSBuildProjectDirectory)\Solution1\Project1A\Project1A.csproj;
$(MSBuildProjectDirectory)\Solution1\Project1B\Project1B.csproj;
</ProjectsToOutput>
</SolutionsToBuild>
<SolutionsToBuild Include="$(MSBuildProjectDirectory)\Solution2\Solution2.sln">
<ProjectsToOutput>
$(MSBuildProjectDirectory)\Solution2\Project2A\Project2A.csproj;
$(MSBuildProjectDirectory)\Solution2\Project2B\Project2B.csproj;
</ProjectsToOutput>
</SolutionsToBuild>
<OutputNames Include="Project1A">
<OutputFolder>ArbitraryFolder1</OutputFolder>
</OutputNames>
<OutputNames Include="Project2B">
<OutputFolder>ArbitraryFolder2</OutputFolder>
</OutputNames>
</ItemGroup>
Однако любой способ, которым я пытался заставить цель DoBuild обновить метаданные, падает на его лицо.Я думал, что смогу сделать это:
<!-- Now override specific projects OutputTo metadata -->
<OutputProjects Condition="'%(OutputProjects.FileName)' == '%(OutputNames.Identity)'">
<OutputTo>%(OutputNames.OutputFolder)</OutputTo>
</OutputProjects>
Но этот код группируется по группе элементов OutputProjects и затем по группе элементов OutputNames, поэтому условие никогда не выполняется (один из аргументовк сравнению всегда пусто).
Я, к сожалению, на данном этапе не могу изменить ни структуру решения, ни требования к структуре выходной папки.Есть ли какой-нибудь трюк с MSBuild, который мне не хватает, который мог бы помочь мне здесь?Я не против включения в эту задачу пользовательской задачи, но предпочел бы по возможности простое решение MSBuild.
Если это имеет значение, я использую MSBuild v4.