程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> MSBuild簡解

MSBuild簡解

編輯:關於.NET

從最原始的編譯器,逐漸到 Shell 命令組合、Make工具,到現在的針對性 Build 工具,Rake、Ant、MSBuild,甚至於 PowerShell 這樣的工具;都為我們 軟件開發以及系統管理做出了貢獻,我甚至不能想象幾十年前使用編譯器生成程 序的復雜步驟(其實就是把 makefile 拆開,相當恐怖)。

探討 Make、Ant 以及 MSBuild 無太多意義,甚至從純技術和擴展性上來說, 我認為 MSBuild 弱於 NAnt,但是軟件並不是這麼簡單,之所以深研 MSBuild, M$ 作為後盾讓人信任的無奈。

本文主要講述 MSBuild 的基本概念,以及如何使用它輔助開發。

首先我們來看一個最簡單的 Build:

<Project ToolsVersion="3.5" DefaultTargets="Build"  xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
  <Welcome>Hello MSBuild! </Welcome>
 </Property>

 <Target  Name="Build">
  <Message Text="$(Hello)" />
  </Target>
</Project>

假設我們把這個文件保存到 D:\build.proj ,然後在命令行切換工作目錄到 D:\,運行 msbuild.exe(msbuild 默認直接運行當前目錄下的 *.sln 或 *.*proj 文件),則命令行將會顯示詳細的 build 信息,當然也包括我們的消息 'Hello MSBuild!' 。

概念

Project

Project 代表一個 Build,有屬性 ToolsVersion、DefaultTargets、 InitialTargets,分別為 依賴的 MSBuild 版本、默認 Build 目標,初始化目標 。

Property

Property 是 MSBuild 中的基本單元,可以理解為變量,我們可以在大多數地 方使用它作為 Task 的參數以完成我們預期的目標。

下面的語句示范如何聲明 Property:

<PropertyGroup>
 <Name Condition="$(Name) ==  ''">Kate</Name>
  <WorkPath>D:\Workspace</WorkPath>
</PropertyGroup>

這裡定義了兩個 Property,我們可以使用 $(Name) 和 $(WorkPath) 來引用 它們,就和前面的范例一樣。

Property 可以使用 MSBuild 的 /p 參數定義,這裡就使用 Condition 屬性 判斷是否存在外部 Name,如果不存在則使用自定義的 "Kate"。

Target

Target 是 Build 的基本單元,也對應 MSBuild 的 /t 參數,可用參數有 DependOnTargets,代表依賴的目標。

Task

Task 即任務,Build 的過程就是若干 Task 的執行。上面的 <Message Text="..." /> 就是 MSBuild 內置的一個 Task,Text 則是參數。

Task 可以使用 Condition 屬性。

通常情況下,MSBuild 自帶的 Task 並不夠用,有以下 MSBuild 擴展,可以 幾乎不需要自己寫擴展:

* MSBuild Community Tasks

* SDC Tasks Library

* MSBuild Extension Pack

Item

我們可以簡單的把 Item 理解為 .Net 中的 Dictionary<string,Dictionary<string,string>> 類型,內層的字 典被稱作元數據表。

<ItemGroup>
 <Table Include="A;B;C;D" />

 <Game Include="StarCraft" />
 <Game  Include="WarCraft" />
 <Game  Include="CoderCraft" />
 <Program Include="MyApp">
   <Developer>Zealic</Developer>
   <Timestamp>2009-01-01T11:22:33</Timestamp>
  </Program>
</ItemGroup>

為方便理解,我們可以用 C# 來表述上述內容。

var Table = new  Dictionary<string,Dictionary<string,string>
{
 {"A",  new Dictionary<string,string>},
 {"B", new  Dictionary<string,string>},
 {"C", new  Dictionary<string,string>},
 {"D", new  Dictionary<string,string>}
};

var Game = new  Dictionary<string,Dictionary<string,string>
{
  {"StarCraft", new Dictionary<string,string>},
 {"WarCraft",  new Dictionary<string,string>},
 {"CoderCraft", new  Dictionary<string,string>}
}

var Program = new  Dictionary<string,Dictionary<string,string>
{
  {"MyApp", new Dictionary<string,string>
  {
    "Developer", "Zealic",
   "Timestamp", "2009-01- 01T11:22:33"
  }
 }
};

和使用 Property 不同,Item 有如下用法:

* @(Table) : 直接傳遞 Item 或展開為 A;B;C;D (視 Task 參數類型而定)。

* @(Table, '+') : 以指定的分隔符展開 Item,結果為 A+B+C+D。

* @(Table -> '%(Identity).dll') : 轉換 Item 為 A.dll;B.dll;C.dll;D.dll

* %(Program.Developer) : 引用 Program Item 的元數據 "Developer";此 外,以這種方式使用 Item 都會導致循環所有 Item 成員。比如 <Message Text="%(Game.Identity)"/>,會導致三次 Task 調用,分別輸出 StarCraft, WarCraft 以及 CoderCraft;Identity 代表 Item 的名稱,有關 Item 的更多預 定義元數據,請參考 MSDN。

Item 可以使用 Condition 屬性。

結語

可能有人會問,既然 MSBuild 和批處理能做的事都差不多,為什麼不直接使 用批處理呢?

有以下幾點原因:

* 與 .Net Framework 緊密集成。

* 易於擴展:你可以使用任何 CLR 上的語言編寫 MSBuild Task 進行擴展。

* 高效率:多個解決方案/項目可以在一個解決方案中編譯,甚至支持多核下 的並行編譯。

* 利於診斷:MSBuild 可擴展的日志系統使得 build 過程幾乎和白盒沒有區 別,你可以看到 build 的每一步細節。這也是 VS2003 轉到 VS2005 之間最大的 轉變 - IDE 對編譯過程的感知從黑盒轉變到白盒。

此外,利用眾多第三方 Task,MSBuild 可以完成諸如持續集成、管理服務器 、自動化部署等任務,解放我們的時間,讓我們可以有更多的時間  Coding 或 偷懶 -_-。

了解到這些內容以後,聰明的讀者,你是否已經打開一個正在開發的項目的 *.csproj 文件,用文本編輯器看看 MSBuild 究竟有什麼魔法呢?

PS:文章寫的比較簡單,不夠全面,有問題請給我妹兒 ,我將詳細為你解答。或訪問我的 Twitter,裡面有不少小技巧。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved