MSBuild 中的 PropertyGroup、ItemGroup 和 ItemMetadata
在软件项目不断的进展中,MSBuild 脚本可能几个月都不会被修改,因为通常编译和发布的目录是不经常变化的。
但,一旦某天你需要修改了,看到那一堆 $(Something)、 @(Something)、%(Something) 是相当的头大,不得不搜索 MSDN 才能找到合理的用法。
每次看到下面这样的语法,我都感觉,有必要把语法设计成这样吗?
1 <Copy SourceFiles="@(SrcFiles)" DestinationFiles="@(SrcFiles->'c:\DestDir\%(RecursiveDir)%(Filename)%(Extension)')" />
这篇文章将对 PropertyGroup、ItemGroup 和 ItemMetadata 做简单的语法介绍,解救未来的自己。
PropertyGroup 和 $ 符号
PropertyGroup 用于标记一个或多个变量值。ProperyGroup 内的 XML 节点属性(Property)可以用任何字符串命名。
属性可以通过 $(OtherPropertyName) 语法来引用其他属性的的值。同样,在其他位置使用相同方式引用属性值。
1 <PropertyGroup> 2 <BaseFolder>C:\my\folder</BaseFolder> 3 <SettingsFile>$(BaseFolder)\settings\app.xml</SettingsFile> 4 </PropertyGroup> 5 <Message Text="Using settings file found at $(SettingsFile)"/>
上面的 Message 命令的输出结果为:
1 Using settings file found at C:\my\folder\settings\app.xml
ItemGroup 和 @ 符号
ItemGroup 用于标记一个包含多个值的变量,类似于 C# 中的 Array 或 Dictionary 等。
1 <ItemGroup> 2 <MyItems Include="First" /> 3 <MyItems Include="Second;Third;" /> 4 <MyItems Include=";;;;Fourth;;" /> 5 </ItemGroup> 6 <Message Text="My items using dollar: $(MyItems)"/> 7 <Message Text="My items using at symbol: @(MyItems)"/>
上面的命令输出的结果为:
1 My items using dollar: 2 My items using at symbol: First;Second;Third;Fourth
我们看到,如果使用 $ 符号只能得到一个空字符串。而使用 @ 符号则将输出以 ";" 分号分割的字符串。
同时,MSBuild 也帮我们过滤了多余的 ";" 字符。
ItemMetadata 和 % 符号
ItemGroup 不但可以被用于列表数据,还可以用于 key/value 字典。
在 MSBuild 中 key/value 被称为 ItemMetadata。
1 <ItemGroup> 2 <People Include="Joe"> 3 <Email>joe@example.com</Email> 4 </People> 5 <People Include="Bill"> 6 <Email>bill@example.com</Email> 7 </People> 8 <People Include="Oscar"> 9 <Email>oscar@example.com</Email> 10 </People> 11 </ItemGroup> 12 <Message Text="Processing person %(People.Identity) with email %(People.Email)"/>
上面的命令输出的结果为:
1 Processing person Joe with email joe@example.com 2 Processing person Bill with email bill@example.com 3 Processing person Oscar with email oscar@example.com
在 %(ItemGroup.MetadataKey) 语法中,"Identity" 代表着 XML 节点中的 "Include" 属性中的值。
同时,我们发现,虽然只写了一句 Message 命令,但是有 3 条输出。这是利用的 MSBuild 中的 Task Batching 功能。
那还有哪些 Item Metadata Key 呢?参考这里 :MSBuild Well-known Item Metadata
参考资料
- MSBuild Overview
- MSBuild Batching
- MSBuild Items
- MSBuild Tasks
- MSBuild Targets
- MSBuild Well-known Item Metadata
- Item Metadata in Task Batching
- Microsoft.Build.Tasks Namespace
- TaskExtension Class
- How to: Specify Which Target to Build First