Начиная с .csproj, который определяет различные файлы содержимого XML.
Имейте генерацию кода Target, которая принимает некоторые xml-файлы (Target Inputs) и генерирует .cs-файлы, имена которых определяются путем преобразования из xml-файлов (Target Outputs).
Для того чтобы MSBuild мог определить, нужно ли запускать сборку кода Target, он должен проверить целевые входы и выходы. Поэтому я предполагаю, что эти целевые входы и выходы должны быть глобальными.
Если это неверно, должен возникнуть еще один вопрос о том, как создать цель, выходы которой основаны на динамических элементах; попробовал, но цель продолжает вызываться.
Если это правильно, то как фильтровать контент на глобальном уровне?
В частности, я хочу отфильтровать элементы контента в проекте, чтобы использовались только те, которые находятся в определенном каталоге. Элементы контента будут добавлены другими разработчиками через IDE.
Это может быть достигнуто с помощью Target, который создает динамические элементы, выполняя фильтрацию в атрибуте Condition. Это требует целевого пакетирования, которое не доступно во всем мире. Использование MSBuild 3.5 и Visual Studio 2008.
<?xml version="1.0" encoding="utf-8"?>
<Project
DefaultTargets="Show" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Content Include="badxml\somebadxml1.xml" />
<!-- Note xml\somexml2.xml exists on disk, it just isn't used in this project. -->
<Content Include="xml\somexml1.xml" />
<Content Include="xml\somexml3.xml" />
</ItemGroup>
<!-- Foo should only be defined for Content Items in the "xml" directory. -->
<ItemGroup>
<Foo Include="@(Content->'%(Filename)')"/>
<!-- The line below doesn't work -->
<!-- TestFilter.proj(10,10): error MSB4090: Found an unexpected character '%' at position 3 in condition " '%(Content.RelativeDir)'=='xml' ". -->
<!-- <Foo Condition=" '%(Content.RelativeDir)'=='xml' " Include="@(Content->'%(Filename)')"/> -->
</ItemGroup>
<Target Name="ShowContent">
<Message Text="Content: %(Content.Identity)" />
<Message Text="Content RelDir: %(Content.RelativeDir)" />
</Target>
<Target Name="ShowFoo">
<Message Text="Foo: %(Foo.Identity)" />
</Target>
<Target Name="Show">
<CallTarget Targets="ShowContent;ShowFoo" />
</Target>
</Project>
Почему условная работа MSBuild ItemGroup в глобальной области действия не решает ту же проблему, но с точки зрения вопроса, почему это не работает, вместо поиска альтернативных подходов.
Фильтрация метаданных элемента в msbuild использует динамические элементы в цели и фиктивное имя вывода.
Мое лучшее предположение состоит в том, что этого нельзя сделать без использования динамических элементов в цели, и обходной путь будет заключаться в том, чтобы вместо использования элементов, требующих условия, выписать файл с предварительно определенным именем и использовать его в качестве выходного заполнитель.