Можете ли вы сделать параллельное добавочное построение списка проектов? - PullRequest
2 голосов
/ 22 сентября 2010

Можно ли составить список проектов и построить их параллельно, только если они не обновлены?

<Target Name="DependenciesLevel7" DependsOnTargets="DependenciesLevel6">
<Message Text="5 items to build" />
<MSBuild Projects="C:\Projects\ApplicationManager.csproj;C:\Projects\Metrics.csproj" Properties="$(CustomAllProperties)" BuildInParallel="true">
  <Output TaskParameter="TargetOutputs" ItemName="built_DependenciesLevel7" />
</MSBuild>

Это пример формата, в котором я собираюсь, я надеялся, что смогу параллельно создавать только те элементы, которые здесь не актуальны? Возможно, внутренние вызовы msbuild автоматически параллельны? Если это так, как бы я настроить это так, чтобы это было основано на предыдущей задаче сборки? (Target DependenciesLevel6) Я полагал, что для инкрементного построения вы должны использовать входы / выходы в вашей цели.

Сводка вопроса:

  • Является ли список проектов, передаваемых в задачу msbuild, автоматически инкрементным (сборка пропускается, если сборка уже обновлена)?
    • Если нет, то можно ли делать приращения в списке проектов при распараллеливании?
  • Можете ли вы сделать между приращением цели, где каждая цель является параллельной сборкой?

Ответы [ 3 ]

9 голосов
/ 23 сентября 2010

то, что вы описываете "параллельное инкрементное здание", уже встроено в (вроде) , но вам действительно нужно параллельное частичное построение.

Позвольте мне сначала объяснить концепции, а затем я вернусь к тому, как это работает в вашем сценарии. Есть две вещи, о которых вам нужно знать; добавочное строительство и частичное строительство. Я только что написал сообщение в блоге, обсуждающее это в 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, результат показан ниже.

alt text

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

alt text

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

alt text

Когда цель CopyFiles была выполнена, вы видите этот оператор «Построение цели partially CopyFiles’ частично,… ». Когда пришло время выполнить целевой объект, MSBuild проверил входные и выходные данные, он определил, что файлы 01.txt и 02.txt устарели (потому что их не было в целевом объекте), но 03.txt, 04.txt. и 05.txt были в курсе. Поэтому MSBuild передает целевым объектам CopyFiles значение для элемента Files, который содержит только 01.txt и 02.txt, и позволяет ему делать свое дело.

Теперь это относится к вашей проблеме во многих отношениях, некоторые не такие прямые, как вы могли бы надеяться. Во-первых, MSBuild будет постепенно создавать ваш проект, поэтому, если ваш проект обновлен, он не будет построен снова. Дело в том, что для того, чтобы MSBuild определил, что ваш проект обновлен, он должен загрузить проект, запустить целевой объект по умолчанию (обычно Build), а затем сами цели выяснят, что делать не нужно. Сам этот материал требует времени. Поэтому, если у вас есть огромное количество проектов или огромное количество файлов внутри проекта, вы можете взять дело в свои руки. Что вам нужно, это способ определить, являются ли ваши проекты современными или нет, и правильно выразить это внутри ваших входных и выходных атрибутов. После того, как вы это сделаете, вы сможете пропустить сборку актуальных проектов.

Суть проблемы заключается в том, как правильно настроить входы / выходы. Если вы можете придумать способ сделать это, вы получите то, что хотите. Как вы создадите это, будет зависеть от вашего сценария, но я мог видеть что-то вроде этого:

  1. После каждого профиject build перетащите файл в известное место, специфичное для этого проекта
  2. Прежде чем строить проект, просканируйте его каталог, найдите самый новый файл и затем обновите метку времени файла проекта до этого значения
  3. Затем вы можете поместить файлы проекта в качестве значений входов и файлы маркеров в качестве выходов
  4. Затем вызвать вашу цель

В этом случае вы предполагаете, что все зависимости полностьюсодержится в файлах в каталоге проекта (что не может быть правдой).Я не говорю, что это идеальное решение, но решение.

=============================================

Редактировать: Обновление на основе приведенных ниже квестов.

Вы захотите поместить проектыв элемент (хотя и не обязательный), например ProjectFiles, а затем используйте @ (ProjectFiles) для ввода.Для выводов это то, что я говорил, это сложная часть.Вы должны найти способ узнать (или указать вам через собственный процесс), что проекты актуальны.Для этого нет ничего встроенного.Забота о добавочной сборке против чистой сборки.В идеальном мире инкрементные и чистые сборки одинаковы.Но иногда это не так.Для многих проектов это так.Если вы начнете добавлять кучу целей в процесс сборки и настроите их на инкрементную сборку, но вы не реализуете это должным образом, вы можете пропустить цели, если MSBuild действительно устарела.Хороший пример этого может быть, когда вы создаете цель с Inputs, установленным в список файлов, а затем Outputs, равным списку созданных файлов.Если вы не расширили процесс очистки для удаления этих созданных файлов, то в следующий раз, когда вы перестроите (при условии, что вы не изменили файлы), цель будет пропущена, когда она должна быть очищена в предыдущей перестройке.

0 голосов
/ 22 сентября 2010

Я не уверен насчет инкрементной части, но я читал, что она проверяет входы / выходы.

Я делаю параллельные сборки с MsBuild с конфигурацией, аналогичной вашей, не забудьте запустить msbuild с параметром / m.

Вы можете примерить простой проект и проверить журналы, чтобы увидеть, является ли он инкрементным или нет.

0 голосов
/ 22 сентября 2010

Вы, вероятно, ищете IncrediBuild .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...