Как изменить/заменить файл набора параметров при сборке из командной строки?

Я создаю пакеты из командного файла, используя такие команды, как:

msbuild ..\lib\Package.dproj /target:Build /p:config=%1

Настройки пакетов зависят от набора параметров:

<Import Project="..\optionsets\COND_Defined.optset" Condition="'$(Base)'!='' And Exists('..\optionsets\COND_Defined.optset')"/>

Этот набор параметров определяет условный символ, от которого зависят многие из моих пакетов. Файл выглядит так:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <DCC_Define>CONDITION;$(DCC_Define)</DCC_Define>
    </PropertyGroup>
    <ProjectExtensions>
        <Borland.Personality>Delphi.Personality.12</Borland.Personality>
        <Borland.ProjectType>OptionSet</Borland.ProjectType>
        <BorlandProject>
            <Delphi.Personality/>
        </BorlandProject>
        <ProjectFileVersion>12</ProjectFileVersion>
    </ProjectExtensions>
</Project>

Теперь мне нужны две сборки: одна с определенным условием и одна без. Моим вектором атаки будет файл с набором опций. У меня есть несколько идей, что делать:

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

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


person Heinrich Ulbricht    schedule 29.11.2011    source источник


Ответы (2)


Я подхожу к этому так: определяю несколько конфигураций сборки, а затем выбираю подходящую во время сборки с помощью /p:config=XXX. Это также хорошо работает в среде IDE, потому что вы можете просто дважды щелкнуть конфигурацию сборки в менеджере проектов, чтобы активировать ее.

Я лично использую наследование конфигураций сборки, когда делаю это, чтобы мне не приходилось повторяться. Например, у меня есть конфигурация сборки с именем Debug DCUs, которая наследуется от конфигурации Debug и просто изменяет параметр Debug DCUs на True.

Чтобы помочь объяснить, что я имею в виду, вот как выглядит дерево конфигурации сборки в моем проекте:

введите здесь описание изображения

Конфигурация Debug DCUs осуществляется с помощью этого набора опций:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <DCC_DebugDCUs>true</DCC_DebugDCUs>
    </PropertyGroup>
    <ProjectExtensions>
        <Borland.Personality>Delphi.Personality.12</Borland.Personality>
        <Borland.ProjectType>OptionSet</Borland.ProjectType>
        <BorlandProject>
            <Delphi.Personality/>
        </BorlandProject>
        <ProjectFileVersion>12</ProjectFileVersion>
    </ProjectExtensions>
</Project>

Теперь я уверен, что вы могли бы сделать это с помощью /p:DCC_Define=XXX, но я думаю, что будет чище использовать конфигурации сборки, чтобы вы могли быть уверены, что то, что вы получаете в IDE, совпадает с тем, что вы получаете при сборке из командной строки.

Я бы не рекомендовал ни один из подходов в вашем списке пунктов. Эти подходы кажутся мне чрезвычайно хрупкими.

person David Heffernan    schedule 29.11.2011
comment
Набор опций казался хорошим способом подняться еще на один уровень выше в иерархии конфигурации, потому что я мог в одном месте изменить конфигурацию для всех зависимых пакетов. Но, возможно, это не такая уж большая разница по сравнению с использованием Configuration Manager. - person Heinrich Ulbricht; 29.11.2011
comment
Конфигурации сборки отлично подходят для контроля качества и повторяемости. Я их люблю! Я до сих пор не понимаю, как с ними идеально работать, но это уже другая история!! - person David Heffernan; 29.11.2011
comment
Означает ли это, что вы ничего не изменяете непосредственно в конфигурациях сборки (например, отладка), а скорее определяете настройки в наборах параметров, которые добавляются в качестве ссылки? Итак, конфигурации сборки создают иерархию, а наборы параметров содержат настройки? - person Heinrich Ulbricht; 29.11.2011
comment
Да это верно. Таким образом, я могу поделиться своими наборами опций во всех моих различных проектах. - person David Heffernan; 29.11.2011
comment
Это решает проблему несогласованных настроек проекта раз и навсегда! Мне это и вправду нравится! - person Heinrich Ulbricht; 29.11.2011
comment
У меня была только одна проблема: случай, когда у вас есть, например. четыре разных условных символа и нужно их комбинировать по-разному. Мне пришлось бы создать множество конфигураций сборки для каждой комбинации. Это заставило меня задуматься о генерации набора опций. Что Вы думаете об этом? Или это все-таки ошибка в дизайне? - person Heinrich Ulbricht; 29.11.2011
comment
Я согласен с тем, что выбор из большого количества вариантов быстро становится громоздким из-за конфигураций сборки. - person David Heffernan; 30.11.2011

Один обходной путь — временно переименовать файл .optset; это эффективно отключает его, поскольку указанный файл не может быть найден. Вы можете сделать это из своего пакетного файла перед вызовом msbuild. Это работает только для наборов опций, используемых в качестве эталона, как в вашем случае.

Другой вариант — вручную вставить директиву <Import> в файл .dproj:

<Import Condition="Exists('$(OptSet)')" Project="$(OptSet)"/>

Затем вы можете установить свойство OptSet из командной строки, которая будет импортировать набор параметров:

msbuild /t:Build /p:Config=Release /p:OptSet=myoptset.optset myproject.dproj

Без установки свойства OptSet набор опций не будет импортирован:

msbuild /t:Build /p:Config=Release myproject.dproj
person Ondrej Kelle    schedule 29.11.2011