Почему MSBuild ItemGroup не работает в глобальном масштабе?
Мне отчаянно любопытно, почему я не могу создать элемент в глобальной области видимости, основанный на условии метаданных, который работает как положено внутри цели. Например, это работает как ожидалось:
<ItemGroup>
<TestItems Include="TestItem1">
<TestFlag>true</TestFlag>
</TestItems>
<TestItems Include="TestItem2">
<TestFlag>false</TestFlag>
</TestItems>
</ItemGroup>
<Target Name="Default">
<Message Text="@(TestItems)" />
<Message Text="@(TestItems)" Condition="'%(TestItems.TestFlag)'=='true'" />
<ItemGroup>
<FilteredTestItems Include="@(TestItems)" Condition="'%(TestItems.TestFlag)'=='true'" />
</ItemGroup>
<Message Text="@(FilteredTestItems)" />
<Message Text="@(FilteredTestItems)" Condition="'%(FilteredTestItems.TestFlag)'=='true'" />
</Target>
и производит следующий вывод:
TestItem1; TestItem2 TestItem1 TestItem1 TestItem1
И это работает как ожидалось:
<ItemGroup>
<TestItems Include="TestItem1">
<TestFlag>true</TestFlag>
</TestItems>
<TestItems Include="TestItem2">
<TestFlag>false</TestFlag>
</TestItems>
</ItemGroup>
<ItemGroup>
<FilteredTestItems Include="@(TestItems)" Condition="'false'=='true'" />
</ItemGroup>
<Target Name="Default">
<Message Text="@(TestItems)" />
<Message Text="@(TestItems)" Condition="'%(TestItems.TestFlag)'=='true'" />
<Message Text="@(FilteredTestItems)" />
<Message Text="@(FilteredTestItems)" Condition="'%(FilteredTestItems.TestFlag)'=='true'" />
</Target>
Производим следующий вывод:
TestItem1; TestItem2 TestItem1
Но это:
<ItemGroup>
<TestItems Include="TestItem1">
<TestFlag>true</TestFlag>
</TestItems>
<TestItems Include="TestItem2">
<TestFlag>false</TestFlag>
</TestItems>
</ItemGroup>
<ItemGroup>
<FilteredTestItems Include="@(TestItems)" Condition="'%(TestItems.TestFlag)'=='true'" />
</ItemGroup>
Выдает следующую ошибку MSBuild:
temp.proj (13,45): ошибка MSB4090: обнаружен неожиданный символ "%" в позиции 2 в состоянии ""%(TestItems.TestFlag)'=='true'".
Так что же дает? Конечно, я могу обойти это, но что именно я не понимаю в ItemGroup, метаданных и / или глобальной области видимости?
1 ответ
Условие группы элементов работает за пределами цели, но пакетирование - нет (это оператор "%"). Пакетирование используется, когда вы вызываете задачу, и поскольку вы можете вызывать задачу только из цели, имеет смысл, чтобы пакетирование также работало только внутри цели.
Вы можете спросить, почему группа предметов работает внутри цели, поскольку это не задача. До MSBuild 3.5 вы вообще не допускали групп предметов внутри целей; ты должен был позвонить CreateItem
вместо. В версиях 3.5 и 4.0 использование групп элементов таким способом разрешено, но я думаю, что это просто синтаксический сахар для вызова CreateItem
задача, так что ваше состояние работает, потому что есть задача за кадром.