то, что вы описываете "параллельное инкрементное здание", уже встроено в (вроде) , но вам действительно нужно параллельное частичное построение.
Позвольте мне сначала объяснить концепции, а затем я вернусь к тому, как это работает в вашем сценарии. Есть две вещи, о которых вам нужно знать; добавочное строительство и частичное строительство. Я только что написал сообщение в блоге, обсуждающее это в http://sedodream.com/2010/09/23/MSBuildYouveHeardOfIncrementalBuildingButHaveYouHeardOfPartialBuilding.aspx, но я вставлю соответствующие части сюда.
Постепенное строительство - это концепция, согласно которой вы должны строить только то, что устарело. Для поддержки этого MSBuild имеет атрибуты, входы и выходы в элементе Target. С помощью этих атрибутов вы можете указать файлы, которые попадают в цель (через атрибут input), и файлы, которые вы ожидаете получить от цели (через атрибут output). Как только вы сделаете это, MSBuild будет сравнивать временную метку входов с выходами, и если все выходы будут обновлены (то есть входы более старые), тогда цель будет пропущена. Посмотрите на очень простой файл проекта ниже.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Files Include="src\01.txt;src\02.txt;src\03.txt;src\04.txt;src\05.txt;"/>
</ItemGroup>
<PropertyGroup>
<Dest>dest\</Dest>
</PropertyGroup>
<Target Name="CopyFiles"
Inputs="@(Files)"
Outputs="@(Files->'$(Dest)%(Filename)%(Extension)')">
<Message Text="CopyFiles" />
<Copy SourceFiles="@(Files)"
DestinationFiles="@(Files->'$(Dest)%(Filename)%(Extension)')"/>
</Target>
<Target Name="DeleteTwoFiles">
<Message Text="DeleteTwoFiles" />
<Delete Files="$(dest)01.txt;$(dest)02.txt"/>
</Target>
</Project>
В этом файле проекта у нас есть две цели; CopyFiles и DeleteTwoFiles. Игнорируйте DeleteTwoFiles сейчас. Также обратите внимание, что в каталоге, где я выполняю эту сборку, есть папка src с файлами, перечисленными в пункте «Файлы». На цели CopyFiles я указал входы и выходы. Входные данные просто @ (файлы), это файлы, на которые воздействует цель. Выходные данные содержат выражение @ (Files -> '$ (Dest)% (Filename)% (Extension)'). Который является тем же выражением из оператора Copy. Если папка Dest пуста, и я выполняю цель CopyFiles, результат показан ниже.

Так что, как и ожидалось, файлы были скопированы, так что все хорошо. Что произойдет, если я выполню это снова? Вывод показан ниже

Итак, как вы можете видеть, цель была пропущена, оператор сообщения «CopyFiles» не был выполнен, а копия не была получена в результате. Таким образом, это, в двух словах, наращивание.
Теперь, когда папка dest содержит все файлы, что, по вашему мнению, произойдет, я выполню команду msbuild.exe PartialBuilding01.proj / t: DeleteTwoFiles; CopyFiles? Эта команда сначала удалит два файла из выходного каталога, а затем снова вызовет цель CopyFiles. Давайте посмотрим на результат ниже.

Когда цель CopyFiles была выполнена, вы видите этот оператор «Построение цели partially CopyFiles’ частично,… ». Когда пришло время выполнить целевой объект, MSBuild проверил входные и выходные данные, он определил, что файлы 01.txt и 02.txt устарели (потому что их не было в целевом объекте), но 03.txt, 04.txt. и 05.txt были в курсе. Поэтому MSBuild передает целевым объектам CopyFiles значение для элемента Files, который содержит только 01.txt и 02.txt, и позволяет ему делать свое дело.
Теперь это относится к вашей проблеме во многих отношениях, некоторые не такие прямые, как вы могли бы надеяться. Во-первых, MSBuild будет постепенно создавать ваш проект, поэтому, если ваш проект обновлен, он не будет построен снова. Дело в том, что для того, чтобы MSBuild определил, что ваш проект обновлен, он должен загрузить проект, запустить целевой объект по умолчанию (обычно Build), а затем сами цели выяснят, что делать не нужно. Сам этот материал требует времени. Поэтому, если у вас есть огромное количество проектов или огромное количество файлов внутри проекта, вы можете взять дело в свои руки. Что вам нужно, это способ определить, являются ли ваши проекты современными или нет, и правильно выразить это внутри ваших входных и выходных атрибутов. После того, как вы это сделаете, вы сможете пропустить сборку актуальных проектов.
Суть проблемы заключается в том, как правильно настроить входы / выходы. Если вы можете придумать способ сделать это, вы получите то, что хотите. Как вы создадите это, будет зависеть от вашего сценария, но я мог видеть что-то вроде этого:
- После каждого профиject build перетащите файл в известное место, специфичное для этого проекта
- Прежде чем строить проект, просканируйте его каталог, найдите самый новый файл и затем обновите метку времени файла проекта до этого значения
- Затем вы можете поместить файлы проекта в качестве значений входов и файлы маркеров в качестве выходов
- Затем вызвать вашу цель
В этом случае вы предполагаете, что все зависимости полностьюсодержится в файлах в каталоге проекта (что не может быть правдой).Я не говорю, что это идеальное решение, но решение.
=============================================
Редактировать: Обновление на основе приведенных ниже квестов.
Вы захотите поместить проектыв элемент (хотя и не обязательный), например ProjectFiles, а затем используйте @ (ProjectFiles) для ввода.Для выводов это то, что я говорил, это сложная часть.Вы должны найти способ узнать (или указать вам через собственный процесс), что проекты актуальны.Для этого нет ничего встроенного.Забота о добавочной сборке против чистой сборки.В идеальном мире инкрементные и чистые сборки одинаковы.Но иногда это не так.Для многих проектов это так.Если вы начнете добавлять кучу целей в процесс сборки и настроите их на инкрементную сборку, но вы не реализуете это должным образом, вы можете пропустить цели, если MSBuild действительно устарела.Хороший пример этого может быть, когда вы создаете цель с Inputs, установленным в список файлов, а затем Outputs, равным списку созданных файлов.Если вы не расширили процесс очистки для удаления этих созданных файлов, то в следующий раз, когда вы перестроите (при условии, что вы не изменили файлы), цель будет пропущена, когда она должна быть очищена в предыдущей перестройке.