艾伟:MSBuild 简解

  从最原始的编译器,逐渐到 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) == ''">KateName>
<WorkPath>D:\WorkspaceWorkPath>
PropertyGroup>

  这里定义了两个 Property,我们可以使用 $(Name) 和 $(WorkPath) 来引用它们,就和前面的范例一样。
  Property 可以使用 MSBuild 的 /p 参数定义,这里就使用 Condition 属性判断是否存在外部 Name,如果不存在则使用自定义的 "Kate"。

Target
  Target 是 Build 的基本单元,也对应 MSBuild 的 /t 参数,可用参数有 DependOnTargets,代表依赖的目标。

Task
  Task 即任务,Build 的过程就是若干 Task 的执行。上面的 就是 MSBuild 内置的一个 Task,Text 则是参数。
  Task 可以使用 Condition 属性。
  通常情况下,MSBuild 自带的 Task 并不够用,有以下 MSBuild 扩展,可以几乎不需要自己写扩展:
  * MSBuild Community Tasks
  * SDC Tasks Library
  * MSBuild Extension Pack

Item
  我们可以简单的把 Item 理解为 .Net 中的 Dictionary> 类型,内层的字典被称作元数据表。

 


<ItemGroup>
<Table Include="A;B;C;D" />
<Game Include="StarCraft" />
<Game Include="WarCraft" />
<Game Include="CoderCraft" />
<Program Include="MyApp">
<Developer>ZealicDeveloper>
<Timestamp>2009-01-01T11:22:33Timestamp>
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 成员。比如 ,会导致三次 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,里面有不少小技巧。

2009-3-28 Zealic

时间: 2024-10-30 21:54:11

艾伟:MSBuild 简解的相关文章

MSBuild简解

从最原始的编译器,逐渐到 Shell 命令组合.Make工具,到现在的针对性 Build 工具,Rake.Ant.MSBuild,甚至于 PowerShell 这样的工具:都为我们 软件开发以及系统管理做出了贡献,我甚至不能想象几十年前使用编译器生成程 序的复杂步骤(其实就是把 makefile 拆开,相当恐怖). 探讨 Make.Ant 以及 MSBuild 无太多意义,甚至从纯技术和扩展性上来说, 我认为 MSBuild 弱于 NAnt,但是软件并不是这么简单,之所以深研 MSBuild,

MSBuild 简解

从最原始的编译器,逐渐到 Shell 命令组合.Make工具,到现在的针对性 Build 工具,Rake.Ant.MSBuild,甚至于 PowerShell 这样的工具:都为我们软件开发以及系统管理做出了贡献,我甚至不能想象几十年前使用编译器生成程序的复杂步骤(其实就是把 makefile 拆开,相当恐怖). 探讨 Make.Ant 以及 MSBuild 无太多意义,甚至从纯技术和扩展性上来说,我认为 MSBuild 弱于 NAnt,但是软件并不是这么简单,之所以深研 MSBuild,M$ 作

艾伟:详解AJAX核心 —— XMLHttpRequest 对象 (下)

继续上一篇的内容上一篇关于XMLHttpRequest 对象发送对服务器的请求只说到了用Get方式,没有说Post方式的.那是因为要说Post方式就需要先说另外一个东西,那就是DOM(Document Object Model)文档对象模型.JavaScript通过DOM读取.改变或者删除 HTML.XHTML 以及 XML中的元素,可以重构整个 HTML 文档.可以添加.移除.改变或重排页面上的项目,而且这样的操作会马上显示在页面上.另外,所有浏览器执行W3C 发布的 DOM 标准规范,DOM

艾伟:详解AJAX核心 —— XMLHttpRequest 对象 (上)

我要说的内容都是非常基础的内容,高手就免看了,如果看了欢迎给点意见啊.新手或者对低层还不是很了解的人可以看看,帮助理解与记忆. XMLHttpRequest 对象是AJAX功能的核心,要开发AJAX程序必须从了解XMLHttpRequest 对象开始. 了解XMLHttpRequest 对象就先从创建XMLHttpRequest 对象开始,在不同的浏览器中创建XMLHttpRequest 对象使用不同的方法: 先看看IE创建XMLHttpRequest 对象的方法(方法1): var xmlht

特许经营的常用术语简解

1.特许人(franchisor),也称盟主,指将特许权授予出去的主体,亦即在特许经营活动中,将自己所拥有的商标.商号.产品.专利和专有技术.经营模式及其它营业标志等授予受许人使用的一方,通常为法人.特许人是特许权的真正所有者. 2.受许人(franchisee),亦称为加盟商.被特许人等,指加盟某一特许经营体系的独立法人或自然人,亦即在特许经营活动中,通过付出一定的费用来获得其它商业单位的商标.商号.产品.专利和专有技术.经营模式及其它营业标志等一定期限使用权的自然人或法人. 3.特许权(fr

Wix 安装部署(一)同MSBuild 自动生成打包文件

原文:Wix 安装部署(一)同MSBuild 自动生成打包文件       因为项目需要,最近在研究Wix打包部署,园子里也有一些关于wix的博客,方方面面,讲的点各不同.我自己也在测试过程中,写下过程,以供参考.最新版本WiX Toolset v3.7,如何安装的就不说了,可以参考 http://blog.csdn.net/rryqsh/article/details/8274832         打包关心的问题有 1).Net版本检查  2)桌面和菜单栏的快捷方式 3)更换图标画面,进度条

代理和AOP

代理和AOP一.起源 有时,我们在写一些功能方法的时候,需要加上特定的功能.比如说在方法调用的前后加上日志的操作,或者是事务的开启与关闭.对于一个方法来说,很简单,只要在需要的地方增加一些代码就OK.但是如果有很多方法都需要增加这种特定的操作呢? 没错,将这些特定的代码抽象出来,并且提供一个接口供调用者使用: Java代码 复制代码 收藏代码 public class RecordLog { public static void recordLog() { // 记录日志的操作 System.o

《Android 网络开发与应用实战详解》——2.1节简析Android安装文件

2.1 简析Android安装文件 Android 网络开发与应用实战详解 当我们下载并安装Android后,会在其安装目录中看到一些安装文件.这些文件具体是干什么用的,了解这些对学习后面的开发知识十分有用.所以在本节的内容中将简要介绍这些安装文件的基本知识. 2.1.1 Android SDK目录结构 安装Android SDK后,其安装目录的具体结构如图2-1所示. temp:里面包含了一些常用的文件模板. tools:包含了一些通用的工具文件. usb_driver:包含了AMD64和X8

《Android多媒体应用开发实战详解:图像、音频、视频、2D和3D》——2.1节简析Android安装文件

2.1 简析Android安装文件 Android多媒体应用开发实战详解:图像.音频.视频.2D和3D 当下载并安装Android后,会在其安装目录中看到一些安装文件.了解这些文件具体是干什么用的,对于我们后面的驱动开发知识学习十分有用,所以在本节的内容中将简要介绍这些安装文件的基本知识. 2.1.1 Android SDK目录结构 安装Android SDK后,其安装目录的具体结构如图2-1所示. temp:里面包含了一些常用的文件模板. tools:包含了一些通用的工具文件. usb_dri