Как переопределить параметр CopyLocal (Private) для ссылок в .NET из MSBUILD

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

То, что я хочу сделать, - это создать проект MSBUILD, который будет строить все наше приложение .NET(constst из 8 решений и, возможно, 250 проектов, разделенных между ними) с несколькими настройками, переопределенными из отдельных файлов проекта, чтобы сделать сборка отладки для себя.

В частности, я хочу построить нашу конфигурацию выпуска с отключенными оптимизациями и полной информацией об отладке /pdbs. Кроме того, для сокращения нашего времени сверхбыстрого построения я хочу, чтобы "копировать локальную" (или частную в фактическом файле proj file xml) false для каждой ссылки каждого проекта.

Первые вещи были довольно легкими, я могу довольно легко переопределить свойство уровня проекта (вы даже можете сделать это из командной строки MSBuild с помощью /p ), но я не могу понять, как переопределить свойство на ссылка. Я пробовал несколько вещей, которые я видел здесь, на StackOverflow и в Интернете, но пока ничего не найдено.

Я могу сделать то, что хочу, изменив Microsoft.Common.targets, комментируя код цели _CopyFilesMarkedCopyLocal, полностью пропускает копирование этих файлов. Но я не хочу изменять свою глобальную конфигурацию и делать это при любых обстоятельствах. Я создал собственный файл альтернативных целей, который работает, если я изменяю отдельный файл проекта, чтобы указать на него, но я не могу понять, как указать, что это будет использоваться на верхнем уровне (мой .proj файл, который просто строит все 8 решений). Было бы здорово, если бы я мог каким-то образом переопределить цель _CopyFilesMarkedCopyLocal на верхнем уровне, чтобы, если MS изменит файл целевых объектов по умолчанию, моя сборка не испортилась, но я не могу понять, как сделать эту работу.

Лучше всего было бы, если бы можно было просто переопределить свойства ссылочного уровня, например, вы можете проектировать свойства уровня, не переписывая/не переопределяя объекты целей сборки, но я не нашел информации о том, что это возможно.

Заранее благодарим за помощь.

P.S. Невозможно, чтобы я фактически просматривал все файлы проектов и менял их; Мне нужно решение, которое оставляет существующий код на месте, как есть.

Ответ 1

Попробуйте следующее:

Задайте CustomAfterMicrosoftCommonTargets для C:\foo\filter.targets(или того, что вы называете файлом) и имеете параметры filter.targets:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemDefinitionGroup>
      <Reference>
        <Private>False</Private>
      </Reference>
    </ItemDefinitionGroup>
</Project>

Ответ 2

В файле типа filter.targets добавьте цель:

<Target Name="BeforeBuild">
  <ItemGroup>
        <ReferenceNew Include="@(Reference)">
           <Private>False</Private>
        </ReferenceNew>
        <Reference Remove="@(Reference)"/>
        <Reference Include="@(ReferenceNew)"/>
  </ItemGroup>
</Target>

Это воссоздает список @(Reference), если для метаданных 'Private' установлено значение false, что гарантирует, что ссылка не будет скопирована. Затем запустите построение своего решения или проекта с помощью свойства $(CustomAfterMicrosoftCommonTargets), установленного в путь к этому файлу filter.targets.

msbuild foo.sln /p:CustomAfterMicrosoftCommonTargets=c:\foo\filter.targets

Таким образом, перед созданием проекта будет вызвана цель BeforeBuild, и все ссылки будут установлены соответствующим образом. Если вам нужно больше контроля над тем, когда или ли Private должен быть ложным или истинным, вы можете изменить цель BeforeBuild и управлять им через свойства.

Изменить: может быть лучший способ установить метаданные в целевой программе BeforeBuild.