Использование MSBuild для построения нескольких конфигураций
Я пытаюсь отредактировать файл проекта, чтобы позволить мне иметь проект, который строит несколько конфигураций сборки одновременно. Я сделал это, используя пакетный подход и используя задачу MSBuild (см. ниже).
Если я запускаю скрипт, я получаю эту ошибку:
ошибка 103 свойство OutputPath не задано для проекта "ThisMSBuildProjectFile.csproj файл". Пожалуйста, убедитесь, что вы указали допустимую комбинацию Конфигурация и платформа для этот проект. Отладка Настройка='' Platform= 'AnyCPU'.
Я получаю это, если я добавляю или опускаю OutputPath из задачи MSBuild. Если используется отладчик VS2010 для перехода через скрипт и вызывается задача MSBuild-отладчик снова входит в файл, а затем переходит в OutputPath, поэтому afaik, it должны Выберите это значение, нет?
любая помощь для этого была бы очень признательна - это сводит меня с ума. Спасибо, Пол.
ThisMSBuildProjectFile.csproj (излишки вывезены):
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<!-- Only Import normal targets if not building multiple projects -->
<Import Project="$(MSBuildToolsPath)Microsoft.CSharp.targets" Condition="'$(Configuration)|$(Platform)' != 'AllBuild|AnyCPU' "/>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == '' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>C:FolderEtcOutput$(Configuration)</OutputPath>
<OutDir>C:FolderEtcOutput$(Configuration)</OutDir>
<BaseOutputPath>C:FolderEtcOutput$(Configuration)</BaseOutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<!-- Common -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<Platform>AnyCPU</Platform>
<!-- Repeated properties from above here (including, of course, OutputPath) -->
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<!-- Repeated properties from above here (including, of course, OutputPath) -->
</PropertyGroup>
<ItemGroup>
<Projects Include="C:FolderEtcThisMSBuildProjectFile.csproj" />
</ItemGroup>
<!-- Call this project file again, but with a different configuration - if this was working, this would call multiple build configs -->
<Target Name="Build" Condition="'$(Configuration)|$(Platform)' == 'AllBuild|AnyCPU' ">
<Message Text="hm!"/>
<!-- Tried thiswith and without the OutputPath property - makes no difference. -->
<MSBuild Projects="@(Projects)" Properties="Configuration=Debug;OutputPath=C:FolderEtcOutput" ToolsVersion="4.0" Condition="'$(Configuration)|$(Platform)' == 'AllBuild|AnyCPU' "/>
</Target>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'AllBuild|AnyCPU' ">
<!-- Repeated properties from above here (including, of course, OutputPath) -->
</PropertyGroup>
<!-- Project files -->
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Compile Include="PropertiesAssemblyInfo.cs" />
<Compile Include="BlahBlah.cs" />
</ItemGroup>
3 ответов
важно понимать, что при использовании задачи "MSBuild" будет запущен новый дочерний процесс MSBuild. Подразумевается, что любые элементы и свойства, определенные в Родительском процессе MSBuild, будут не автоматически передается в / видимый из дочернего процесса MSBuild если вы явно передаете их через Properties
атрибут on MSBuild
элемент (например,<MSbuild Properties="..." />
).
чтобы ответить на ваш вопрос, я написал следующее автономный пример, который запускает Дочерний проект MSBuild для всех указанных конфигураций:
сначала создайте каталог для вашего эксперимента MSBuild (например, я использовал
C:\temp\msbuildtest
)-
в этом каталоге создайте первый файл,
main.proj
:<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build" ToolsVersion="4.0"> <ItemGroup> <ConfigList Condition=" '@(ConfigList)' == '' and $(Config) != '' " Include="$(Config.Split('+'))" /><!-- parse all requested configurations into a list --> <ConfigList Condition=" '@(ConfigList)' == '' " Include="Debug" /><!-- if no configurations were specified, default to Debug --> </ItemGroup> <!-- Build the child project for each requested configuration. --> <Target Name="Build"> <MSBuild Projects="$(MSBuildProjectDirectory)\child.proj" Properties="Configuration=%(ConfigList.Identity);OutputPath=$(MSBuildProjectDirectory)\bin\%(ConfigList.Identity)" Targets="Build" /> </Target> </Project>
-
в том же каталоге, создайте второй файл,
child.proj
(в вашем случае это будет фактический проект C#, который вы пытаетесь построить, но потому что Я пытаюсь проиллюстрировать свою точку зрения, я использую простой Дочерний проект, который вместо запуска компилятора C# просто печатает значения свойств :-) )<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build" ToolsVersion="4.0"> <Target Name="Build"> <Message Text="Building configuration $(Configuration) with output path $(OutputPath)" Importance="High" /> </Target> </Project>
-
теперь вы можете запустить пример. Сначала значение по умолчанию, если явно не указать конфигурации для построения:
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\msbuild main.proj > (cut the noise) > Build: > Building configuration Debug with output path C:\temp_c\d\bin\Debug
а затем явно указано несколько конфигураций:
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\msbuild main.proj /property:Config=Debug+Release+Staging+Production > (cut the noise) > Build: > Building configuration Debug with output path C:\temp_c\d\bin\Debug > Build: > Building configuration Release with output path C:\temp_c\d\bin\Release > Build: > Building configuration Staging with output path C:\temp_c\d\bin\Staging > Build: > Building configuration Production with output path C:\temp_c\d\bin\Production
вы должны быть в состоянии адаптировать эту технику к вашей ситуация.
Я не совсем уверен, хочу ли я пройти через такую запутанную конфигурацию самого файла csproj проекта. Я бы предпочел настроить отдельный MSBuild " BuildBoth.proj "файл, который имеет определенную цель под названием "оба", который строит решение в обеих конфигурациях.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Both">
<!-- Calls twice for both configs -->
<Target Name="Both">
<MSBuild Projects="buildboth.sln" Targets="Rebuild" Properties="Configuration=Debug"
StopOnFirstFailure="true">
</MSBuild>
<MSBuild Projects="buildboth.sln" Targets="Rebuild" Properties="Configuration=Release"
StopOnFirstFailure="true">
</MSBuild>
</Target>
<!-- single config targets
<Target Name="Debug">
<MSBuild Projects="buildboth.sln" Targets="Rebuild" Properties="Configuration=Debug"
StopOnFirstFailure="true">
</MSBuild>
</Target>
<Target Name="Release">
<MSBuild Projects="buildboth.sln" Targets="Rebuild" Properties="Configuration=Release"
StopOnFirstFailure="true">
</MSBuild>
</Target>
-->
</Project>
затем я бы запустил команду (многословие минимально), чтобы нацелить оба
C:\Projects\experiments\BuildBoth>msbuild /v:m /target:Both BuildBoth.proj
Microsoft (R) Build Engine Version 4.0.30319.1
[Microsoft .NET Framework, Version 4.0.30319.225]
Copyright (C) Microsoft Corporation 2007. All rights reserved.
BothWpf -> C:\Projects\experiments\BuildBoth\BothWpf\bin\Debug\BothWpf.exe
BothWpf -> C:\Projects\experiments\BuildBoth\BothWpf\bin\Release\BothWpf.exe
что-то не так в вашем файле проекта. Рассмотрим этот XML-код:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == '' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>C:\Folder\Etc\Output$(Configuration)\</OutputPath>
...
</PropertyGroup>
эти свойства никогда не могут быть установлены, так как даже если $(конфигурация) и $(платформа) пусты, они никогда не могут соответствовать пустой строке при конкатинировании с символом бара; минимальное значение для этого условия -'|', а не ". Даже если исправлено путем сравнения условия с'|', ВЫ затем продолжаете пытаться использовать $(Configuration) в пути вывода в этой PropertyGroup, но $(Configuration) никогда не будет иметь значения в момент его использования. Аналогично, когда вы пытаетесь установить $(Platform) в "AnyCPU", он уже должен иметь это значение. Вероятно, вы вообще хотели опустить условие в первой PropertyGroup, и вам может потребоваться предоставить значения по умолчанию для $(Configuration) и $(Platform) в ранней PropertyGroup без условий. Выделите весь свой проект против нового проекта и посмотрите, есть ли какие-либо другие странности, подобные этому.
также обратите внимание, что на ваше переопределение цели "Build", у вас есть избыточное условие для задачи MSBuild; с тем же условием вы не нуждаетесь в нем ни для одной из задач.