[zz] whidbey系列之一:MSBuild

.Net Framework 2.0 里有一个类似ANT的用来做项目编译工具 , MSBuild

介绍好友 Terry 的一篇文章:

(原文地址:http://terry.home.sjtu.info/docview.aspx?id=19 ,作者站点:http://terry.home.sjtu.info,强烈推荐!!)
whidbey系列之一:MSBuild


Author: Terry(www.sjtu.info)

Source: 原创

2005-2-21


链接:.NET Framework 2.0 Redistributable beta 1
链接:.NET Framework 2.0 SDK beta 1

MSBuild是.NET Framework 2.0的项目编译工具,在不使用Visual Studio.NET 2005(Codename Whidbey)的情况下,利用MSBuild,同样可以构建复杂的.NET工程。通过编写MSBuild的makefile文件(即*proj文件),我们能够处理比Visual Student.NET 2005工程更复杂的程序编译结构。MSBuild在安装好.NET Framework 2.0 SDK后就可以使用了,启动.NET Framework SDK Command Prompt后既可以使用MSBuild。与传统的make或nmake工具不同,MSBuild不是一个独立的工具,msbuild本身依赖于.NET Framework 2.0 CLR,当执行msbuild编译工程时,将调用Microsoft.Build.Engine.dll、Microsoft.Build.Framework.dll、Microsoft.Build.Utilities.dll、Microsoft.Build.Tasks.dll四个.NET程序集以及位于Framework中的一些配置文件和Schema。

MSBuild的使用方法在SDK文档中有大部分说明,位于.NET Framework SDK Documentation/General Reference/MSBuild Reference。

MSBuild没有提供对1.1版本编译器的支持,如果执行CSC任务,调用的是.NET Framework 2.0的C#编译器。通过编写自定义的MSBuild Task,我们可以让MSBuild执行任何你想执行的任务,只要该任务能用.NET语言描述出来。以下是一个例子,在这个例子中我们创建了一个MSBuild Task,这个Task调用.NET Framework 1.1中的C#编译器执行C#代码的编译任务。

注意,在这里MSBuild Task本身是运行在.NET Framework 2.0 CLR中,而MSBuild执行该Task后的C#代码编译目标是在1.1 CLR中执行的。另外,我们也通过使用MSbuild来创建这个MSBuild Task。

链接:工程Info.Sjtu.Home.Terry.Tasks源代码

Info.Sjtu.Home.Terry.Tasks.Csc1.cs

namespace Info.Sjtu.Home.Terry.Tasks
{
 public class Csc1 : Task
 {
  private const string COMPILER_PATH = @"C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322/csc.exe";
   ....

类从Microsoft.Build.Utilities.Task继承,成为MSBuild Task,通过常量COMPILER_PATH来执行调用V1.1.4322中的C#编译器。

Info.Sjtu.Home.Terry.Tasks.Csc1.cs

public string Sources {get { return sources; } set { sources = value; }}
public string OutputAssembly{ get { return outputAssembly; } set {outputAssembly = value; }}
public string TargetType { get { return targetType; } set { targetType = value; }}
public string Define { get { return define; } set { define = value; }}
public string Doc { get { return doc; } set { doc = value; }}
public string References { get { return references; } set { references = value; }}
public string AddModules { get { return addModules; } set { addModules = value; }}
public string Debug { get { return debug.ToString(); } set { debug = Boolean.Parse(value); }}
public string Unsafe { get { return _unsafe.ToString(); } set { _unsafe = Boolean.Parse(value); }}

MSBuild通过解析*proj文件,创建Csc1实例,并把*proj中的设置值传递给Csc1的这些属性,然后调用Csc1中覆盖的Execute()方法。在Csc1的Execute方法中,将会生成csc.exe的参数,并通过创建System.Diagnostics.Process来启动C#编译器。

在.NET Framework 2.0 SDK Command Prompt中把改MSBuild Task注册到GAC:

gacutil /i info.sjtu.home.terry.tasks.csc1.dll

另外还需要把这个全局缓存中的程序集注册到MSBuild。打开MSBuild的任务注册文件,一般是C:/WINDOWS/Microsoft.NET/Framework/v2.0.40607/Microsoft.Common.Tasks,在Project一节中添加一行:

<UsingTask TaskName="Info.Sjtu.Home.Terry.Tasks.Csc1" AssemblyName="Info.Sjtu.Home.Terry.Tasks, Version=1.0.0.0, Culture=neutral, PublicKeyToken=96e299cc8f119763"/>

现在通过编写*proj文件,我们就可以通过MSBuild来编译原来的1.1 C#工程了。

我给IMS 5.0 beta(http://terry.home.sjtu.info/ims5.aspx)编写了一个proj文件:

msbuild.proj

<Project xmlns = "http://schemas.microsoft.com/developer/msbuild/2003" DefaultTarget = "debug" >

  <ItemGroup>

   <basefiles Include = "IMS5.Base.Security.cs,IMS5.Base.DataService.cs" />
   <middlefiles Include = "IMS5.Middle.Backup.cs,IMS5.Middle.Module.cs,IMS5.Middle.User2Module.cs,IMS5.Middle.User.cs" />
   <uifiles Include = "IMS5.UI.AuthButton.cs,IMS5.UI.ErrBar.cs,IMS5.UI.Validator.cs" />

  </ItemGroup>

  <Target Name = "debug">

   <CSC1 Debug = "true" Sources = "@(basefiles)" OutputAssembly = "IMS5.Base.dll" TargetType = "library" />
   <CSC1 Debug = "true" Sources = "@(middlefiles)" OutputAssembly = "IMS5.Middle.dll" References = "IMS5.Base.dll" TargetType = "library" />
   <CSC1 Debug = "true" Sources = "@(uifiles)" OutputAssembly = "IMS5.UI.dll" TargetType = "library" References = "IMS5.Middle.dll"/>

  </Target>

  <Target Name = "release">

   <CSC1 Sources = "@(basefiles),@(middlefiles),@(uifiles)" OutputAssembly = "IMS5.dll" TargetType = "library" />

  </Target>

  <Target Name = "clean">

   <Delete Files = "IMS5.dll;IMS5.Base.dll;IMS5.Middle.dll;IMS5.UI.dll;IMS5.Base.pdb;IMS5.Middle.pdb;IMS5.UI.pdb" />

  </Target>

</Project>

下面是使用MSbuild执行上面PROJ文件中定义的debug目标的情况:

比起make工具的makefile文件来,proj文件更容易编写,它符合XML规范,我们可以开发一个应用程序来生成proj文件,msbuild在.NET Framework 2的开发中也将是一种主流的编译方式。使用本文提供的Csc1,可以使用msbuild编译大部分1.1的C#工程。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值