介绍好友 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 |
类从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; }} |
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" /> </ItemGroup> <Target Name = "debug"> <CSC1 Debug = "true" Sources = "@(basefiles)" OutputAssembly = "IMS5.Base.dll" TargetType = "library" /> </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#工程。