编程项目构建工具简介在进行编程操作的时候,我们常常会遇到很多与编程无关的项目管理工作,如下载依赖、编译源码、单元测试、项目部署等操作。一般的,小型项目我们可以手动实现这些操作,然而大型项目这些工作则相对复杂。构建工具是帮助我们实现一系列项目管理、测试和部署操作的工具。 软件构建(Software Build)是指软件开发过程中涉及到的一系列处理工作,如将源代码编译成二进制代码,打包二进制代码,运行自动化测试等。为了方便编程人员的操作,人们开发了自动构建(Build Automation)工具来帮助人们处理这些工作。这篇博客将简单介绍构建工具的概念。 一、为什么需要构建工具 在国内高校的编程课中,比如,以合肥工业大学管理学院电子商务专业的编程课为例。一般都是从Java编程基础教起,在安装好JDK之后,开始使用一个记事本编写一个HelloWorld.java,里面内容是打印出Hello World。接下来教大家使用JCreator工具来编写程序,实现输出。之后的教学主要内容在Java知识上,对于项目开发的经验和知识则很少描述。于是很多同学不理解,为什么要用JCreator编写程序,或者是JCreator很好用,为什么后面大家用Eclipse、IntelliJ IDEA这种工具来开发Java。 这些工具都是IDE,也就是为了方便开发人员组织代码文件,管理项目而开发的。IDE其实也可以实现编译、打包的功能。既然如此为何还需要构建工具呢?为什么很多IDE软件都提供了各种构建工具插件呢?个人认为,IDE本身是为了提供开发人员编程的工具,因此整合了项目管理和构建的一些功能。而构建工具的目标是为了管理依赖、编译、打包和部署。因此,后者更像是提供编程的依赖环境和外部包,并帮助发布部署项目的。它的对项目管理支持的功能和目标比IDE更纯粹也更强大(比如大部分构建工具都有中央库,收集了几乎所有开源的外部包提供给开发者自动导入外部包的功能,而一般IDE的这方面功能也是通过构建工具实现的。同时,构建工具几乎都支持命令行运行,来帮助我们打包、编译和发布等,证明它并不是提供一个编写代码的环境,而是作为管理的工具存在。而IDE几乎都是有界面,可以提供代码编写的)。此外,网络上还有一些说法(https://www.oschina.net/question/558461_117208):
对于小型的项目而言,比如大学开始的Java课可能要求我们写一个简单的计算器等。该项目依赖的外部的代码很少,几乎使用Java自带的SDK就可以了。但是,对于大中型的项目,都会依赖很多外部开发资源。网络上开源了大量的代码,在我们编写程序的时候可以帮助我们减少重复性的工作,大大提升复用情况,降低编程难度。对于这种项目的代码维护,以及依赖维护是很复杂的。什么程序依赖什么版本的什么外部包,如果不使用构建工具帮助我们管理这些依赖,那将增加开发人员大量的负担。因此,包括上述编译、打包和发布等功能,构建工具在帮助我们管理这些东西,大大提升编程效率。 二、构建工具的功能 基本上构建的自动化是编写或使一大部分任务自动执行的一个动作,而这些任务则是软件开发者的日常,像是
三、流行的构建工具 历史上,自动构建工具主要是通过makefiles(环境变量文件)进行,它是一个文件,包含了自动构建的指令。大多数情况下,makefile都是指示如何编译并连接项目的。目前,不同的编程语言有不同的构建工具。主要包括如下:
在Java的世界里,目前在被使用的常用构建工具有三个:Ant,Maven,Gradle。 Ant的核心是由Java编写,采用XML作为构建脚本,这样就允许你在任何环境下,运行构建。Ant基于任务链思想,任务之间定义依赖,形成先后顺序。缺点是使用XML定义构建脚本,导致脚本臃肿,Ant自身没有为项目构建提供指导,导致每个build脚本都不一样,开发人员对于每个项目都需要去熟悉脚本内容,没有提供在Ant生态环境内的依赖管理工具。 Maven团队意识到Ant的缺陷,采用标准的项目布局,和统一的生命周期,采用约定由于配置的思想,减少构建脚本需要的编写内容,活跃的社区,可以方便找到合适的插件,强大的依赖管理工具。缺点是采用默认的结构和生命周期,太过限制,编写插件扩展麻烦,XML作为构建脚本。 而Gradle同时拥有Ant和Maven的优点,它是基于Groovy的DSL,提供声明式的构建语言,采用标准的项目布局,但拥有完全的可配置性,就是可以改,通过插件,提供默认的构建生命周期,也可以自己定义任务,单独运行任务,定义任务间的依赖,强大的依赖管理工具,与Maven和Ivy仓库结合,与Ant天生兼容,有效的重用Ant的任务,多种实现插件的方式,强大的官方插件库,从构建级别,支持从Ant或者Maven的逐步迁移,通过包装器,无缝的在各个平台运行。 四、如何识别项目构建工具 一般地,一个项目的根目录中就会包含构建工具的配置文件信息,也表明了该项目使用的构建工具,通常有如下的对应关系:
接下来介绍一下Maven
背景
是什么
优点
Maven编译项目流程
最原始的java程序运行:
使用maven编译项目的流程:
基本概念
一个Maven编译实例
<span style="font-size: small;">[INFO] Scanning for projects... 2. [INFO] ------------------------------------------------------------------------ 3. [INFO] Building Maven Hello World Project 4. [INFO] task-segment: [clean, compile] 5. [INFO] ------------------------------------------------------------------------ 6. [INFO] [clean:clean {execution: default-clean}] 7. [INFO] Deleting directory D:\code\hello-world\target 8. [INFO] [resources:resources {execution: default-resources}] 9. [INFO] skip non existing resourceDirectory D: \code\hello-world\src\main\resources 10. [INFO] [compiler:compile {execution: default-compile}] 11. [INFO] Compiling 1 source file to D: \code\hello-world\target\classes 12. [INFO] ------------------------------------------------------------------------ 13. [INFO] BUILD SUCCESSFUL 14. [INFO] ------------------------------------------------------------------------ 15. [INFO] Total time: 1 second 16. [INFO] Finished at: Fri Oct 09 02:08:09 CST 2009 17. [INFO] Final Memory: 9M/16M 18. [INFO] ------------------------------------------------------------------------ 19. </span>
clean告诉Maven清理输出目录target/,compile告诉Maven编译项目主代码,从输出中我们看到Maven首先执行了clean:clean任务,删除target/目录,默认情况下Maven构建的所有输出都在target/目录中;接着执行resources:resources任务(未定义项目资源,暂且略过);最后执行compiler:compile任务,将项目主代码编译至target/classes目录(编译好的类为com/juvenxu/mvnbook/helloworld/HelloWorld.Class)。 上文提到的clean:clean、resources:resources,以及compiler:compile对应了一些Maven插件及插件目标,比如clean:clean是clean插件的clean目标,compiler:compile是compiler插件的compile目标,后文会详细讲述Maven插件及其编写方法。 至此,Maven在没有任何额外的配置的情况下就执行了项目的清理和编译任务,接下来,我们编写一些单元测试代码并让Maven执行自动化测试。 1. [INFO] Scanning for projects... 2. [INFO] ------------------------------------------------------------------------ 3. [INFO] Building Maven Hello World Project 4. [INFO] task-segment: [clean, test] 5. [INFO] ------------------------------------------------------------------------ 6. [INFO] [clean:clean {execution: default-clean}] 7. [INFO] Deleting directory D:\git-juven\mvnbook\code\hello-world\target 8. [INFO] [resources:resources {execution: default-resources}] 9. … 10. Downloading: http://repo1.maven.org/maven2/junit/junit/4.7/junit-4.7.pom 11. 1K downloaded (junit-4.7.pom) 12. [INFO] [compiler:compile {execution: default-compile}] 13. [INFO] Compiling 1 source file to D: \code\hello-world\target\classes 14. [INFO] [resources:testResources {execution: default-testResources}] 15. … 16. Downloading: http://repo1.maven.org/maven2/junit/junit/4.7/junit-4.7.jar 17. 226K downloaded (junit-4.7.jar) 18. [INFO] [compiler:testCompile {execution: default-testCompile}] 19. [INFO] Compiling 1 source file to D:\ code\hello-world\target\test-classes 20. [INFO] ------------------------------------------------------------------------ 21. [ERROR] BUILD FAILURE 22. [INFO] ------------------------------------------------------------------------ 23. [INFO] Compilation failure 24. D:\code\hello-world\src\test\java\com\juvenxu\mvnbook\helloworld\HelloWorldTest.java:[8,5] -source 1.3 中不支持注释 25. (请使用 -source 5 或更高版本以启用注释) 26. @Test 27. [INFO] ------------------------------------------------------------------------ 28. [INFO] For more information, run Maven with the -e switch 29. … 不幸的是构建失败了,不过我们先耐心分析一下这段输出(为了本书的简洁,一些不重要的信息我用省略号略去了)。命令行输入的是mvn clean test,而Maven实际执行的可不止这两个任务,还有clean:clean、resources:resources、compiler:compile、resources:testResources以及compiler:testCompile。暂时我们需要了解的是,在Maven执行测试(test)之前,它会先自动执行项目主资源处理,主代码编译,测试资源处理,测试代码编译等工作,这是Maven生命周期的一个特性,本书后续章节会详细解释Maven的生命周期。 从输出中我们还看到:Maven从中央仓库下载了junit-4.7.pom和junit-4.7.jar这两个文件到本地仓库(~/.m2/repository)中,供所有Maven项目使用。 构建在执行compiler:testCompile任务的时候失败了,Maven输出提示我们需要使用-source 5或更高版本以启动注释,也就是前面提到的JUnit 4的@Test注解。这是Maven初学者常常会遇到的一个问题。由于历史原因,Maven的核心插件之一compiler插件默认只支持编译Java 1.3,因此我们需要配置该插件使其支持Java 5。
总结
|
|