【发布时间】:2012-03-29 01:35:52
【问题描述】:
从定义各种 xml 内容文件的 .csproj 开始。 有代码生成目标,它接受一些 xml 文件(目标输入)并生成 .cs 文件,其名称由 xml 文件(目标输出)的转换确定。 为了让 MSBuild 确定代码构建目标是否需要运行,它需要检查目标输入和输出。 因此我假设这些目标输入和输出必须是全局的。
如果这不正确,应该还有一个关于如何创建输出基于动态项目的目标的问题;试过了,但目标一直被调用。
如果正确,那么如何在全局级别过滤内容? 具体来说,我想过滤项目中的内容项,以便只使用特定目录中的内容项。内容项将由其他开发人员通过 IDE 添加。
这可以使用创建动态项目的目标来实现,在条件属性中进行过滤。这需要目标批处理,这在全球范围内不可用。使用 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>
Why doesn't MSBuild ItemGroup conditional work in a global scope 解决了同样的问题,但从询问为什么这不起作用的角度,而不是寻找替代方法。
Filtering Item's Metadata in msbuild 使用目标中的动态项目和一个虚拟输出名称。
我最好的猜测是,如果不使用目标中的动态项目,这将无法完成,解决方法是使用需要条件的项目而不是使用需要条件的项目来写出具有预定义名称的文件并将其用作输出占位符。
【问题讨论】:
标签: msbuild