MSBuild 腳本往往數月不動,一旦需修改,面對 $(...)、@(...)、%(...) 等符號往往令人頭大。本文系統梳理三大核心結構,助你快速掌握 MSBuild 語法精髓。
$ 符號:純量屬性PropertyGroup 定義單一值屬性(鍵值對),屬性名可任意命名,值為字串。屬性間可透過 $(PropertyName) 相互引用。
<PropertyGroup>
<BaseFolder>C:\my\folder</BaseFolder>
<SettingsFile>$(BaseFolder)\settings\app.xml</SettingsFile>
</PropertyGroup>
<Message Text="Using settings file found at $(SettingsFile)" />
<!-- 輸出: Using settings file found at C:\my\folder\settings\app.xml -->
關鍵特性:
<OutputPath Condition="'$(Configuration)'=='Release'">bin\Release</OutputPath>。@ 符號:項目清單ItemGroup 定義項目集合,每個項目擁有身分識別(Identity,即 Include 值)與零或多個中繼資料。項目集合以 @(ItemType) 參考。
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Utils.cs">
<SubType>Code</SubType>
</Compile>
<Content Include="Config\*.json" />
</ItemGroup>
<Message Text="Compile files: @(Compile)" />
<!-- 輸出: Compile files: Program.cs;Utils.cs -->
項目轉換:@(ItemType -> '新格式') 可將項目集合投射為新字串集合。
<Copy SourceFiles="@(Compile)"
DestinationFiles="@(Compile -> 'obj\$(Configuration)\%(Filename)%(Extension)')" />
上例中 %(Filename)、%(Extension) 即為項目中繼資料存取。
% 符號:項目中繼資料每個項目可攜帶任意中繼資料(Metadata),格式:<ItemType Include="..."><MetadataName>Value</MetadataName></ItemType>。存取語法:%(ItemType.MetadataName) 或在 Target 批次處理時簡寫 %(MetadataName)。
<ItemGroup>
<MyFiles Include="a.txt;b.txt">
<Category>Doc</Category>
<Priority>High</Priority>
</MyFiles>
</ItemGroup>
<Target Name="PrintMeta">
<Message Text="File: %(MyFiles.Identity), Category: %(MyFiles.Category), Priority: %(MyFiles.Priority)" />
</Target>
批次處理:MSBuild 會針對每個唯一的中繼資料值組合執行 Target 內任務,實現「對每個項目/群組執行一次」的邏輯。
<Project xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SourceRoot>Src</SourceRoot>
<DestRoot>Dist</DestRoot>
</PropertyGroup>
<ItemGroup>
<SourceFiles Include="$(SourceRoot)\**\*.cs" />
</ItemGroup>
<Target Name="Deploy">
<!-- %(RecursiveDir) 保留相對目錄結構 -->
<Copy SourceFiles="@(SourceFiles)"
DestinationFiles="@(SourceFiles -> '$(DestRoot)\%(RecursiveDir)%(Filename)%(Extension)')"
SkipUnchangedFiles="true" />
</Target>
</Project>
%(Filename) 與 %(filename) 不同。Condition 屬性控制 Target/Item/Property 的啟用。$(MSBuildProjectDirectory)、$(MSBuildThisFileDirectory) 等。掌握 Property(純量)、Item(集合)、Metadata(項目屬性) 三位一體,並熟悉 $、@、% 三種參考符號的適用場景,即可輕鬆閱讀、編寫、除錯複雜 MSBuild 腳本。