Проблема с использованием MSBuild для создания и копирования всех выходных данных в общую папку

Мы пытаемся написать сценарий msbuild, который построит решение и скопирует все скомпилированные двоичные файлы и зависимости в определенную папку вывода. Хотя сценарий сборки, который у нас есть, создает и копирует двоичные файлы в общую папку, мы не получаем копирование зависимостей. Вероятно, это связано с тем, как мы использовали задачу msbuild для создания решения, и мы принимаем целевые выходные данные задачи в группу элементов и выполняем итерацию по группе элементов, чтобы скопировать все скомпилированные библиотеки DLL и exes в общую папку. Но это не включает библиотеки зависимостей, которые помещаются в отдельную папку bin каждого проекта.

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
    <ParentSolutionFile />
</PropertyGroup>
<ItemGroup>
    <Assemblies Include="*.dll, *.exe" />
</ItemGroup>
<Target Name="BuildAll">
    <CombinePath BasePath="$(MSBuildProjectDirectory)" Paths="Source\Solutions\xxx.sln">
        <Output TaskParameter="CombinedPaths" PropertyName="ParentSolutionFile" />
    </CombinePath>
    <Message Text="$(ParentSolutionFile)" />
    <MSBuild Projects="$(ParentSolutionFile)">
        <Output TaskParameter="TargetOutputs" ItemName="Assemblies" />
    </MSBuild>
    <Message Text="%(Assemblies.Identity)" />
    <Copy SourceFiles="%(Assemblies.Identity)" DestinationFolder="$(MSBuildProjectDirectory)\Binary" OverwriteReadOnlyFiles="True" SkipUnchangedFiles="True" />
</Target>

What will be the preferred way to copy over all the binaries along with the necessary dependencies to a common output folder?


person koder    schedule 15.05.2013    source источник


Ответы (2)


Разве переопределение OutputPath не помогает?

<MSBuild Projects="$(ParentSolutionFile)" Properties="OutputPath=$(MSBuildProjectDirectory)\Binary">
  <Output TaskParameter="TargetOutputs" ItemName="Assemblies" />
</MSBuild>

И вообще исключить задачу копирования?

person James Woolfenden    schedule 15.05.2013

В процессе сборки конечный результат помещается в каталог, представленный OutputPath - по крайней мере, если вы создаете проекты C #. Для C / C ++ внутренняя структура и имена переменных совершенно разные.

Таким образом, теоретически вы можете передать OutputPath в задаче MsBuild, которая создает решение.

<MsBuild Projects="$(ParentSolutionFile)"
    Properties="OutputPath=$(MSBuildProjectDirectory)\Binary"/>

Однако csproj-файлы безоговорочно перезапишут это значение следующим кодом:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <OutputPath>bin\Debug\</OutputPath>

Я решил эту проблему, внедрив свою собственную систему сборки в каждый файл csproj.

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\..\build\buildsystem.targets" />

Путь указан относительно csproj-файла. Абсолютный путь тоже подойдет или переменная. Хитрость заключается в том, чтобы заставить его работать на всех машинах разработки, а также на агентах сборки.

Теперь в buildsystem.targets просто переопределите OutputPath сколько угодно. Опять же, хитрость заключается в том, чтобы убедиться, что вы получаете одно и то же - или, по крайней мере, четко определенное - местоположение, независимо от того, кто его строит (разработчик, агент сборки) и независимо от того, как была инициирована сборка (VS, командная строка).

Простым способом обработки различий является условный импорт.

<Import Project="..\..\..\build\buildsystem.targets"
    Condition="'$(BuildingInsideVisualStudio)'!='true'"/>

Это не даст вам никаких изменений при запуске сборки из VS и любых изменений, которые вы кодируете, если вы строите из командной строки.

- Джеспер

person jesper    schedule 15.11.2013