2013-05-15 2 views
2

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

<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> 

Что будет предпочтительный способ скопировать все двоичные файлы вместе с необходимыми зависимостями общей папки вывода?

ответ

2

Не отменяет ли OutputPath трюк в одиночку?

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

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

0

Процесс сборки поместит конечный результат в каталог, представленный 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. Абсолютный путь тоже хорош, или переменная. Трюк заключается в том, чтобы заставить его работать на всех dev-машинах, а также на агентах сборки.

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

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

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

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

--Jesper