NAnt还是MSBuild,该如何选择以及何时使用?

164

我知道在Stack Overflow上还有其他与NAntMSBuild相关的问题,但我没有找到两者之间的直接比较,所以这里是问题。

何时应该选择NAnt而不是MSBuild?哪个更适合什么?NAnt是否更适合家庭/开源项目,而MSBuild则适用于工作项目?使用其中任何一个的经验如何?

14个回答

100

我这周进行了类似的调查,以下是我的研究结果:

NAnt:

  • 跨平台(支持Linux/Mono)。例如,安装网站到多个目标(即Linux Apache和Windows IIS)可能非常方便。
  • 在语法上与Ant相似度达95%(对于当前Ant用户或Java构建者来说很容易上手)
  • 集成了NUnit,可作为构建的一部分运行单元测试,并与NDoc集成以生成文档。

MSBuild:

  • .NET内置。
  • 与Visual Studio集成
  • 在Visual Studio中很容易开始使用MSBuild——它全部都在幕后。如果你想深入学习,可以手动编辑文件。

主观差异: (YMMV)

  • NAnt文档更加简明。例如,MSBuild任务参考 列出了“Csc Task-描述Csc任务及其参数”。(感谢“帮助”?),而NAnt任务参考“csc-编译C#程序。”更新:我注意到MSBuild文档已经得到改进,现在已经好多了(可能与NAnt相当)。
  • 不容易从Visual Studio中直接编辑构建脚本源代码(*.*proj文件)。对于NAnt,我只需让Visual Studio将.build脚本视为XML文件即可。
  • 显然,在Visual Studio中,Web应用程序项目默认没有*.*proj文件,因此我很难弄清楚如何运行MSBuild来创建部署脚本。
  • NAnt没有集成到Visual Studio中,需要添加,可以使用插件或者作为“外部工具”进行添加,但这个过程有点麻烦。
  • (编辑:) 我的一位同事提出了这个问题--如果你想要使用CruiseControl进行持续集成构建,它可以直接与NAnt集成。 更新: CruiseControl还有一个MSBuild任务
  • 请参阅下面的评论以获取主观差异的完整和最新讨论。

  • 你可以编辑 .proj 文件,但在卸载项目后(项目的上下文菜单中应该有一个“卸载”选项)。 - Yordan Pavlov
    19
    可以将你的定制内容放到一个单独的.build文件(或其他文件)中,并从你的.csproj文件中导入+执行它。这样,您只需要编辑一次.csproj文件,并将.build文件添加到您的解决方案中。双击即可像编辑任何其他文件一样进行编辑。您可以将.build文件映射到选项中的XML编辑器。 - Kent Boogaart
    9
    有一个MSBuild CCNet任务 - 详细信息可在以下链接找到:http://confluence.public.thoughtworks.org/display/CCNET/MsBuild+Task - Gavin Miller
    2
    值得注意的是,您不需要修改.csproj文件本身。 您可以使用MyProject.csproj.user文件进行这些修改,使您的.csproj文件保持干净和原始状态。MSBuild知道要查找那些.user文件,并将它们自动导入构建过程中。请参阅:http://ahmed0192.blogspot.com/2006/11/customize-msbuild-without-modifying.html - CleverPatrick
    MSBuild现在完全兼容XML。如果您将解决方案迁移到VS 2010,则会添加XML头。 - Stefan Papp
    3
    @CleverHuman,.user文件通常包含用户对项目进行的特定修改,这些修改通常不会与项目的其余部分一起检入。我多年来一直使用Kent的建议,效果非常好。您只需一次在PROJ文件中进行修改,将第二个PROJ文件添加到您的项目中即可。从那时起,您可以轻松自定义第二个PROJ文件,而无需经历卸载/重新加载过程。出于这个原因,我倾向于使用MSBuild。 - DarinH

    77

    对我来说,MSBuild(在Windows平台上)的主要优点之一是它作为.NET本身的一部分提供。这意味着任何已更新至Windows Update的Windows计算机都将拥有MSBuild。再加上C#编译器也是.NET本身的一部分,您就可以在干净的机器上构建项目。无需安装Visual Studio庞然大物。另一方面,必须显式安装NAnt才能触发构建。

    仅供参考,我以往在非微不足道的构建中使用过NMake、Make、Ant、Rake、NAnt和MSBuild(按此顺序)。毫不犹豫,我最喜欢MSBuild(而且我不因为“那是Visual Studio使用的”而偏爱它)。在我看来,它是一个非常被低估的构建工具。

    我会将NAnt与MSBuild进行比较,就像比较过程式编程和函数编程的区别一样。NAnt非常简单直接,您得到的就是您看到的。另一方面,MSBuild需要更多的思考。学习曲线更陡峭。但是,一旦你“get it”,你就可以用它做一些惊人的事情。

    因此,如果您也倾向于函数式或逻辑式编程,并且愿意在看到有形结果之前投入一些时间和精力,我建议您查看MSBuild(当然,我也坚信这种投资最终会得到回报,您可以更有效地做更强大的事情)。


    11
    哇!没想到 MSBuild 已经和运行时一起打包安装了。这很酷,我确实看到了其中的好处。不过,我不理解函数式/过程式之间的比较。当人们“明白它”的时候,MSBuild 为什么会更强大,这一点很有趣。 - Scott Saad
    2
    Msbuild 实际上依赖于各种 SDK 中的文件,这些文件只有在调用某些目标时才会变得明显。因此,虽然 msbuild 可以直接使用,但它可能无法运行。 - Sam Shiles
    6
    应该补充一件事情:不仅可以从msbuild中调用.NET程序集,从而让人们可以访问很多非常方便的函数(例如,在构建脚本中使用Systme.IO.Path中的所有内容非常方便),还可以在msbuild文件中编写纯C#代码并执行。这非常棒。如果事情变得太复杂,编写自定义任务也很容易。http://msdn.microsoft.com/en-us/library/dd722601.aspx - stijn
    1
    从维基百科:"MSBuild以前是与.NET Framework捆绑在一起的;然而,从Visual Studio 2013开始,它与Visual Studio捆绑在一起。" - DavidRR
    MSBuild(Microsoft Build Tools 2013)也可以独立于Visual Studio 2013下载此处 - DavidRR

    45

    就我个人而言,我会同时使用这两种工具来完成同一个项目。

    MSBuild非常适合构建Visual Studio解决方案和项目 - 这是它的专长所在。

    在我看来,NAnt更容易手动编辑 - 特别是如果你已经了解Ant。NAnt可以使用NAntContrib轻松调用MSBuild。因此,我手工编写NAnt脚本来执行诸如复制已构建文件、清理等操作 - 然后调用MSBuild来完成实际的“将我的C#源代码转换为程序集”的部分。

    如果您想要一个示例,请查看我的Protocol Buffers构建文件。(我不会声称它是一个绝妙的NAnt脚本,但它能够胜任工作。)


    2
    它确实支持Mono。Mono的MSBuild支持很糟糕。 - Mehrdad Afshari
    @Mehrdad:是的,某个时候我真的必须尝试让Protocol Buffers在Mono上编译...目前存在一个gmcs错误导致它无法工作:(但这个想法始终是它最终会在Mono上工作。 - Jon Skeet
    1
    大家好,Mono使用XBuild,将MSBuild移植到XBuild很容易。请查看此链接:http://www.mono-project.com/Porting_MSBuild_Projects_To_XBuild。 - fyasar

    20

    NAnt拥有更多的开箱即用功能,但是MSBuild拥有更好的基本结构(元数据非常实用),这使得构建可重用的MSBuild脚本变得更加容易。

    要理解MSBuild可能需要一些时间,但一旦理解,就会发现它很好用。

    学习材料:


    38
    嗨,我听说过那些书籍 :) - Sayed Ibrahim Hashimi

    19

    KISS = 使用MSBuild。

    当你有一个“开箱即用”的工具能够胜任任务时,为什么要再添加其他东西呢?MSBuild出现后,NAnt就被取代了。而Mono将会有一个MSBuild实现(xbuild)。

    DRY = 使用MSBuild。

    问问自己,您需要哪些构建系统功能?我需要的是一个构建系统,可以由我的IDE使用,而不是维护两个不同的配置。

    个人而言,我很想听听关于NAnt的真正论据,因为我真的想不到任何一个真正站得住脚的理由。


    2
    当MSBuild出现时,Nant就已经死了。我认为这是关键,即使没有使用VS(我不使用)。 - harpo
    我同意。DotNet 1.1没有msbuild.exe,所以我们当时很被动。自从2.0版本以来,msbuild.exe和额外的库做了很多工作。编写自定义MsBuild-Task有一个学习曲线,但是这些年我已经写了大约10个。 - granadaCoder
    1
    我必须同意,作为开发人员,您应该使用与构建服务器相同的工具,以便能够更快地失败。 - krystan honour

    14

    我注意到几篇帖子提到需要手动编辑.csproj(或.vbproj等)文件。

    MSBuild允许通过使用.user文件自定义这些.*proj文件。如果我有一个名为MyCreativelyNamedProject.csproj的项目,并想要自定义其中的MSBuild任务,我可以创建一个名为MyCreativelyNamedProject.csproj.user的文件,并使用CustomBeforeMicrosoftCommonTargetsCustomAfterMicrosoftCommonTargets来自定义这些文件。

    此外,NAnt和MSBuild都可以通过自定义MSBuild任务和通过NantContrib扩展进行自定义。

    因此,使用NAnt或MSBuild真正取决于熟悉度:

    • 如果您已经熟悉Ant,请使用NAnt。学习曲线将非常简单。
    • 如果您对这两个工具都不熟悉,则MSBuild已经与Visual Studio集成,无需额外工具。

    值得补充的是,MSBuild几乎保证可以立即与所有新版本的.NET和Visual Studio一起使用,而NAnt可能会有一些滞后。


    1
    +1 指出 .NET 发布和 NAnt 发布之间的滞后。我还记得当 .NET 3.5 发布时,不得不使用从网络上获取的破解的 nant.exe.config 才能使事情正常运行。这并不好玩。 - mmacaulay
    10
    根据这里的许多帖子,那些 .USER 文件包含用户特定信息,不应该被检入版本控制。因此,那将是我最不想放置构建自定义的地方。任何构建自定义都不应该是用户特定的,因此也不应该放在那些 .user 文件中。 - DarinH
    1
    同意drventure的观点;.user-files正如其名称所示是针对用户的,它们甚至不应该被检入您的源代码控制存储库。这不是自动化构建的地方。 - Kjetil Klaussen

    10
    我在NAnt脚本中同时使用了MSBuild。我坚持使用NAnt的主要原因是隔离性。让我解释一下为什么我认为这很重要:
    1. 将依赖项添加到项目中。 NAnt构建文件与Visual Studio不兼容(在我的情况下,我认为这是优点),因此Visual Studio不会尝试对其进行任何操作。MSBuild任务被嵌入到解决方案中,可以引用其他MSBuild任务。我曾经收到过来自其他人的源代码,结果发现无法构建,因为MSBuild社区任务未安装。我感到特别沮丧的是,即使请求的构建可以继续进行(例如调试构建),Visual Studio也会抛出一堆错误,浪费我调试的时间。简而言之:如果可能,我不喜欢向我的项目添加依赖项

    2. 我不相信Visual Studio的开发团队。这源于Visual Studio早期时会破坏我的HTML。例如,我仍然不使用设计师(最近在会议上我发现同事们也是这样做的)。我发现Visual Studio可能会搞乱DLL文件中的依赖项和版本号(我无法复制此问题,但它在一个项目中始终发生,并导致了很多痛苦和时间的浪费)。我已经采用了一个构建过程,只使用Visual Studio以调试模式构建。对于生产,我使用NAnt来控制一切外部。如果我使用NAnt构建,Visual Studio就不会再干扰。

    PS: 我是一名网页开发者,不从事Windows Forms开发。


    6

    虽然我对MsBuild不是很熟悉,但我认为双方的一些关键差异可以通过以下方式进行补充:

    最近我需要在Nant中构建一个Silverlight项目。我发现如果我只使用MsBuild会更容易 - 最终我在Nant脚本中调用了一个MsBuild任务,所以混合使用两者并不太出奇。

    除此之外,我认为这将是个人喜好的问题 - 如果你习惯于在Visual Studio中管理部分/大部分MsBuild功能,那么显然你可以做到这一点。如果你更喜欢手写脚本,并且来自Java世界,那么Nant似乎更灵活、更适合你。


    好的观点。这两种解决方案都可以轻松地扩展和定制,以任何所需的方式。 - CleverPatrick

    2
    我最终使用了两种方式。在重新设计我们的构建系统时,我遇到了一个棘手的问题。也就是说,我无法摆脱 .vcproj(以及家族成员),因为我们所有人都使用VS更新项目文件、设置和配置。因此,如果不经过巨大的复制和容易出错的过程,我们就不能基于一组新文件构建我们的构建系统。
    因此,我决定保留 VS 的 'proj' 文件,并使用 MSBuild(它们是 MSBuild 文件,至少 VS2005 和 VS2008 使用 MSBuild 项目文件)。对于其他所有任务(自定义配置、单元测试、打包、准备文档等),我使用 NAnt。
    对于持续集成,我使用了 CruiseControl。因此,我们有 CC 脚本触发 NAnt 作业,而构建过程则使用 MSBuild。
    最后请注意:MSBuild 不支持安装程序项目!因此,您只能调用 DevEnv.com 或直接使用 Visual Studio。这就是我最终所做的,但我默认禁用了所有解决方案配置中的安装项目,因为开发人员通常不需要构建它们,如果他们需要可以手动选择构建它们。

    1

    NAnt的文档和教程使得学习使用NAnt构建脚本变得更加容易。一旦我掌握了NAnt和创建构建脚本的技能,我开始将这些知识应用到MSBuild中(我在NAnt中做了X,我该如何在MSBuild中做X?)。微软的文档通常假定读者具有相当高的知识水平才能派上用场。

    从NAnt转向MSBuild的原因是因为MSBuild更加现代化。不幸的是,NAnt的最后一个版本发布于2007年12月8日,而MSBuild 4.0(.NET 4.0)已经问世。看起来NAnt项目已经停滞不前。

    如果你找到了适合初学者学习使用MSBuild创建构建脚本的好文档,那么就跳过NAnt,直接使用MSBuild。如果NAnt发布了新版本,那么我会考虑继续使用NAnt,但现在他们已经落后了。


    1
    截至2012年6月,版本0.92的NAnt可从网站http://nant.sourceforge.net/下载,并支持.Net 4.0。 - Brett Rigby

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接