Условия MSBuild
MSBuild поддерживает определенный набор условий, которые можно применять везде, где разрешен атрибут Condition
; см. поддерживаемые элементы. В следующей таблице описаны эти условия.
Элемент Condition
является одной строкой, поэтому все строки, используемые в выражении, включая значения свойств, должны быть заключены в одинарный кавычки. Пробелы между операторами разрешены и часто используются для удобочитаемости, но они не требуются.
Чтобы использовать логические And
и операторы Or
, укажите операнды внутри строкового значения элемента Condition
, как показано в следующем примере:
Condition="'$(Configuration)' == 'Debug' And '$(MSBuildProjectExtension)' == '.csproj'"
Логические операторы можно цепочки. Оператор And
имеет более высокий приоритет, чем Or
, но для ясности рекомендуется использовать скобки при использовании нескольких логических операторов, чтобы сделать порядок вычисления явным. Если вы этого не сделали, MSBuild выдает предупреждение MSB4130.
Строковые методы можно использовать в условиях, как показано в следующем примере, в котором функция TrimEnd() используется для сравнения только соответствующей части строки, чтобы различать платформы целевых платформ .NET Framework и .NET Core.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net45;net48;netstandard2.1;netcoreapp2.1;netcoreapp3.1</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework.TrimEnd(`0123456789`))' == 'net'">
<!-- Properties for .NET Framework -->
</PropertyGroup>
</Project>
В файлах проекта MSBuild нет истинного логического типа. Логические данные представлены в свойствах, которые могут быть пустыми или заданы для любого значения. Таким образом, '$(Prop)' == 'true'
означает "если Prop true
", но '$(Prop)' != 'false'
означает "если Prop true
или не настроен или установлен на что-то другое".
Логическое значение логики вычисляется только в контексте условий, поэтому параметры свойств, такие как <Prop2>'$(Prop1)' == 'true'</Prop>
, представлены как строка (после расширения переменной), а не вычисляются как логические значения.
MSBuild реализует несколько специальных правил обработки, чтобы упростить работу со строковыми свойствами, которые используются в качестве логических значений. Логические литералы принимаются, поэтому Condition="true"
и Condition="false"
работать должным образом. MSBuild также включает специальные правила для поддержки логического оператора отрицания. Таким образом, если $(Prop)
имеет значение true, !$(Prop)
расширяется до !true
, и это значение сравнивается с false
, как и ожидалось.
Сравнение версий
Реляционные операторы <
, >
, <=
и >=
поддерживают версии, проанализированные System.Version, чтобы сравнить версии с четырьмя числовыми частями друг с другом. Например, '1.2.3.4' < '1.10.0.0'
true
.
Осторожность
System.Version
сравнения могут привести к удивительным результатам, если одна или обе версии не указывают все четыре части. Например, версия 1.1 старше версии 1.1.0.
MSBuild предоставляет функции свойств для сравнения версий с другим набором правил, совместимых с семантической версией (semver).
Расширения в условиях
В зависимости от позиции в файле проекта можно использовать расширения для свойств ($), списков элементов (@) и метаданных элементов (%). Расширения зависят от того, как MSBuild обрабатывает файлы проекта.
Свойства
Условие, содержащее выражение, например $(SomeProperty)
, вычисляется и преобразуется в значение свойства. Если условие находится за пределами целевого объекта, выражение вычисляется во время оценки файла проекта. Значение свойства зависит от позиции в файле проекта после расширения всех импортов. Если условие находится в целевом объекте, оно оценивается при выполнении целевого объекта, а значение влияет на любые изменения, происходящие во время выполнения сборки.
Свойство, которое не определено в точке в развернутом файле проекта, где выражение условия оценивается в пустую строку без каких-либо диагностических ошибок или предупреждений.
Списки элементов
Условие, содержащее выражение @-expression, например @(SomeItems)
, расширяется в группах элементов на верхнем уровне и в целевых объектах.
Элементы могут зависеть от любого свойства и могут зависеть от элементов, которые уже определены в последовательности.
Причина заключается в том, что MSBuild обрабатывает файлы проекта несколькими проходами. После начальной оценки свойства и прохождения расширения импорта выполняется проверка элемента. Таким образом, @-expressions разрешены в любом условии, которое вычисляется после того, как элементы начали определяться. То есть в элементах, группах элементов и в целевых объектах.
Метаданные
Условие, содержащее выражение метаданных, например %(ItemMetadata)
, расширяется в том же контексте, что и списки элементов, то есть в группах элементов на верхнем уровне и в целевых объектах. Однако расширение может иметь другое поведение в группе элементов в зависимости от того, находится ли группа элементов вне целевого объекта или внутри целевого объекта. Кроме того, из различных форм выражений метаданных, %(ItemName.MetadataName)
, %(JustTheMetadataName)
и @(ItemName->'%(MetadataName)')
, допускается только преобразование элемента (последний) за пределами целевого объекта. Значение %-expression в целевом объекте вычисляется во время выполнения и зависит от любых изменений состояния во время выполнения целевого объекта. Выполнение целевого объекта и значения любого %-expressions, содержащихся в нем, также зависит от пакетирования целевого объекта, а также может активировать пакетирование; см. пакетнойMSBuild.
Поддерживаемые элементы
Следующие элементы поддерживают атрибут Condition
:
- Импорт
- ImportGroup
- Пункт
- ItemDefinitionGroup
- ItemGroup
- ItemMetadata
- OnError
- Выпуск
- Свойство
- PropertyGroup
- Цель
- Задача
- UsingTask
- Когда
См. также
- справочник по MSBuild
- условные конструкции
- Пошаговое руководство. Создание файла проекта MSBuild с нуля