在Ant或MSBuild中编写构建脚本的任何最佳实践

时间:2011-09-07 06:14:05

标签: ant msbuild build build-automation

我正在尝试使用Ant和MSBuild自动化我的项目(包括java和.net)的构建过程。我已经阅读了它们并知道如何在Ant和MSBuild中编写构建脚本。但我想知道,是否有编写构建脚本的指南或最佳实践?以下是我发现的两个,但我想听听其他开发者的更多信息。

  • 在编写构建脚本时,只需依赖位于其中的项目 源控件,并在工作文件夹中可用 查看来源。不要编写构建脚本 依赖于未保留在源代码管理中的项目。
  • 如果项目包含一组子系统且每个子系统都有 它自己的构建脚本,项目的构建文件应该只调用 子系统的构建脚本。此外,这些文件应导入包含目标(如compile,test,package等)的公共构建文件。

我也见过this post,但它在编写任务的过程中有详细说明。如上所述,我需要更高级别的指导方针。

以下是我从答案中收集的指南:

  1. 在干净的环境中运行每个构建。这意味着每个构建脚本都需要clean目标。
  2. 构建脚本通常应包含compilepackagetest目标。
  3. 如果产品具有不同的开发线(例如开发,发布), 所有这些都应该具有相同的构建脚本。但是,不同 参数应该传递给这些脚本。
  4. 在开发线上执行的构建通常包含编译, 包装,部署和安装步骤。但建立在发布之上 行包括进一步的步骤,例如标记产品和 生成更改日志/发布说明。
  5. 构建脚本也应保留在源代码管理中。
  6. 尝试将所有构建信息保留在构建脚本中,而不是 持续集成服务器(Bamboo,TeamCity等)
  7. 如果您的构建使用的参数可能会在将来发生变化(例如 网络地址复制构建结果),不要硬编码成 你的构建脚本。相反,使用构建参数来控制它 容易。

3 个答案:

答案 0 :(得分:4)

对上面提到的第二个要点进行评论:

  

如果项目包含一组子系统,并且每个子系统都有   自己的构建脚本,项目的构建文件应该只调用   构建子系统的脚本。

每个子系统都应该有自己的构建文件,但该文件应该导入一个公共构建文件。公共构建文件将包含诸如编译,测试,包等目标。

http://ant.apache.org/manual/Tasks/import.html

子系统构建文件非常简单,不包含重复,只包含特定于该子系统的信息(例如compile.classpath)。

答案 1 :(得分:4)

如果您正在构建VisualStudio应用程序,最好使用msbuild而不是Ant。 msbuild命令将使用开发人员创建的解决方案文件进行构建,并基本上模拟他们所做的相同构建。

如果您真的想要自动化所有内容,请查看Jenkins。它有一个可以执行msbuild的插件,并会在每次有人进行更改时自动触发构建。我使用了msbuild和Ant与Jenkins的组合。我使用msbuild进行构建,然后使用Ant来收集和压缩所有构建的工件。然后,人们可以直接从Jenkins下载构建的工件。

现在,使用Java应用程序,您将不得不使用Ant。我使用以下指南

  • 每个构建脚本都需要一个clean目标。此目标将删除在构建过程中添加的所有文件,并将工作目录返回到clean之前的状态。
  • 我遵循Maven在使用目标名称时所做的事情,因此我的目标是名称,如 clean compile package
  • 同样遵循Maven指南,我的所有构建文件都放在target目录中。这样,我的清洁命令可以简单地执行<delete dir="${target.dir}/>并清理所有内容,并且闪闪发光。
  • 如果我有子项目,则每个子项目都有自己的build.xml文件。我的主build.xml文件只调用所有子项目'build.xml文件。
  • 使用Ivy。它易于设置且易于使用。您不再需要在源存储库中存储jar文件,或丢失您依赖的jar文件的版本。
  • 哎呀,如果可以,请使用Maven并完成它。不幸的是,大多数旧项目难以 mavenize 而不是它的价值。
  • 使用Jenkins作为连续构建服务器来构建您的构建。并且,离开部门的所有构建(UAT,QA和保护构建)必须是Jenkins构建。
  • 鼓励开发人员编写单元测试。事实上,Jenkins可以执行单元测试并在其构建页面上显示结果。
  • 使用checkstyle,PMD,CPD,Findbugs和其他代码验证产品等其他内容。当然,詹金斯可以运行其中的每一个,并显示漂亮的图表,可以用来向经理展示你的工作有多难。

答案 2 :(得分:1)

在MSBuild中,目标应尽可能指定输入和输出(以启用依赖项计算)。如有必要,请使用Returns属性指定返回与用于依赖项计算的项目不同的项目。

应使用项目转换(用于简单的基于路径的转换)或其他目标(用于更复杂的转换)生成给定目标的输入和输出项目。

对于MSBuild pre-4.x,对于您在.targets文件中定义的目标,请考虑使用以下模式使消费者能够在您定义的目标之前注入自己的目标:

<PropertyGroup>
  <MyTargetDependsOn>
    Target1;
    Target2;
    SomeOtherTarget
  </MyTargetDependsOn>
</PropertyGroup>
<Target
  Name="MyTarget"
  DependsOnTargets="$(MyTargetDependsOn)">

</Target>

这使消费者只需修改MyTargetsDependsOn属性的值,就可以在指定目标之前注入自己的目标:

<PropertyGroup>
  <MyTargetDependsOn>
    $(MyTargetDependsOn);
    YetAnotherTarget
  </MyTargetDependsOn>
</PropertyGroup>
<Target
  Name="YetAnotherTarget">

</Target>

在MSBuild 4.x中,您只需使用BeforeTargets和AfterTargets属性。