随着Android Studio的普及,越来越多的Android开发者也要开始了解和学习Gradle这款强大的代码构建工具了。我们在学习和了解一项新事物的时候,最快速的方法往往是与已知的事物进行比较,对于熟悉Makefile编译机制的Linux程序员而言,认识和掌握Gradle最好的方法莫过于比较它们之间的区别了,本文不准备详细介绍Gradle的方方面面,而是希望通过与Makefile的对比帮助Gradle初学者更快速地理解Gradle的基础和原理。

Makefile是一种管理和编译 Linux C/C++ 项目的工具,而Gradle也是一种代码构建工具,只不过是针对Java语言的,它同样可以通过一些配置文件和脚本来完成代码的依赖、第三方库的引入、编译的自动化配置等功能。

首先说说Makefile,它是由一个个"规则"组成,每个"规则"都是由"目标"、"依赖"、"命令"构成, 一个最简单的Makefile如下所示:

1
2
3
4
5
6
7
8
9
.PHONY: clean
 
all: hello
 
hello: hello.c
    gcc -o hello hello.c
 
clean:
    rm hello

这里有三个"目标",分别是: "all","hello","clean"

当执行"make"命令时,编译器会默认查找目标"all" ,如果没有"all"则会查找Makefile文件的第一个目标。本示例中有"all"目标,它依赖"hello"目标,因此编译器会转而先构建"hello"目标,构建前, 编译器会先检测"hello"目标是否需要更新(通过判断"hello"文件与它所依赖的源文件"hello.c"的修改时间),如果需要,则执行后面的命令,而需要编译的源文件则是通过手动或者相关函数的方式添加到编译命令的参数中去的。

这就是makefile最核心的构建思想,通过一个个"目标"、"依赖"、"命令"来完成整个项目的关联和编译。那么,我们也根据这一思想来看看Gradle是怎么实现的。

1. Gradle是怎么识别源文件的 ?

Gradle是采取了一种"约定优于配置"的思想来完成这一点的,它通过"Plugin"来约定项目的目标和源文件的布局,例如: Java Plugin 定义的源文件布局如图所示:

由该图可以很清楚地看到,Java Plugin 直接约定好了源文件的目录结构,在Gradle中,一般把这些源码目录的配置叫做"SourceSet",同理,Android提供的Android Plugin同样也定义了自己的源文件布局,还加入了如 jni, AndroidManifest.xml 等目录和文件。对于Gradle项目而言,需要在每个代码模块的"build.gradle"文件中定义使用哪一种Plugin, 例如:

1
2
3
4
5
6
7
8
//普通的Java项目
apply plugin: 'java'
 
//Android Application
apply plugin: 'com.android.application'
 
//Android Library
apply plugin: 'com.android.library'

2. Gradle是如何识别编译目标的 ?

在Gradle中,与Makefile的"目标"相对应的概念是"任务",即"task",Gradle的构建过程,就是执行一条一条"task"任务的过程, 同样,一个"task"也是可以依赖另一个"task"的,这样,通过这种依赖关系,就可以将整个项目中各个"task"链接到一起了。

与Makefile中手写目标的方式不同,Gradle将所有的"task"的定义全部交给Plugin来完成,由于每一种工程类型(Java项目、Android项目等),其构建过程都是大同小异的,因此为每一种类型的项目定义好了一种通用的Plugin,以后同类型的项目就可以直接使用该Plugin了,非常的灵活和方便。

当我们在项目中执行"gradle build"命令时,可以看到该项目使用的Plugin具体定义了哪些"task",例如一个典型的Java Plugin定义的"task"如下所示:

1
2
3
4
5
6
7
8
9
10
11
:compileJava
:processResources
:classes
:jar
:assemble
:compileTestJava
:processTestResources
:testClasses
:test
:check
:build

当然,虽然同是Android类型的工程,但不同的项目毕竟还是有配置上的差异,因此,Gradle的Plugin中也可以定义和导出一些特定的"元素"用于传递用户自定义的配置信息,例如: Google提供的 "com.android.application" Plugin 就定义了一个"android"元素,开发者可以在build.gradle中配置该元素的细节,比如定义一些: "项目的ID"、"sdk的版本"、"是否混淆"等等,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
android {
 
    compileSdkVersion 21
    buildToolsVersion "21.1.1"
 
    defaultConfig {
        applicationId "com.jhuster.test"
        minSdkVersion 15
        targetSdkVersion 21
        versionCode 1
        versionName "1.0.0"
     }
}

3. Gradle命令怎么用 ?

gradle命令与make命令类似,都是用来执行编译/清理任务的,make命令默认查找当前目录下的Makefile文件,并且开始构建命令参数中所指定的"目标",例如:

1
2
$make all
$make clean

同样,gradle命令也是类似的用法,例如:

1
2
3
4
$gradle build        //构建和打包整个项目
$gradle clean        //清除之前的构建
$gradle test         //执行测试
$gradle compileJava  //编译java

4. Gradle是如何引入第三方库的 ?

对于Makefile而言,通常需要将第三方库的源码下载下来,编译为库后,放入到工程目录下,然后修改Makefile文件,在gcc/g++的编译链接参数中引用该第三方库的,例如:

1
2
hello: hello.c
    gcc -o hello hello.c -L/libs/foo.a

而Gradle则是通过build.grade文件中的dependencies来配置的,例如:

1
2
3
4
dependencies {
    compile files('libs/foo.jar')  //以jar的方式引用
    compile project(':foo')         //以library工程源码的方式引用
}

另外,Gradle还支持类似Ubuntu软件源仓库的方式来引用第三方库,开发者可以将自己的第三方库上传到一些支持Gradle的中心仓库中,这样,其他人就可以通过配置build.gradle直接完成对第三方库的引用了,代码构建的时候Gradle会自动完成第三方库的下载和链接。比较常用的两个个中心仓库: jcenter,mavenCentral。

例如: 我们引用jcenter仓库的okhttp库,则build.gradle配置如下:

1
2
3
4
5
6
7
8
9
allprojects {
    repositories {
        jcenter()
    }
}
 
dependencies {
    compile 'com.squareup.okhttp:okhttp:2.4.0'
}

5. 小结

Gradle真的很强大很灵活,它将最核心的构建规都则交给了Plugin来完成,这样,轻松实现了构建过程的通用性,开发者只需要关注业务逻辑,以及少许的配置即可完成自动化编译和部署的过程,相比于Linux手写makefile要方便很多。好了,关于Gradle和Makefile的简单对比就介绍到这里了,希望对Gradle的初学者有所帮助,有任何疑问或者建议欢迎留言或者来信lujun.hust@gmail.com交流,或者关注我的新浪微博 @卢_俊 获取最新的文章和资讯。

Gradle与Makefile构建工具的对比的更多相关文章

  1. 学习笔记——Maven实战(六)Gradle,构建工具的未来?

    Maven面临的挑战 软件行业新旧交替的速度之快往往令人咂舌,不用多少时间,你就会发现曾经大红大紫的技术已经成为了昨日黄花,当然,Maven也不会例外.虽然目前它基本上是Java构建的事实标准,但我们 ...

  2. Maven实战——Gradle,构建工具的未来?

    许晓斌-- 四月 05, 2011 Maven面临的挑战 软件行业新旧交替的速度之快往往令人咂舌,不用多少时间,你就会发现曾经大红大紫的技术已经成为了昨日黄花,当然,Maven也不会例外.虽然目前它基 ...

  3. [Gradle] Gradle 构建工具的未来

    转载地址:http://www.infoq.com/cn/news/2011/04/xxb-maven-6-gradle Maven面临的挑战 软件行业新旧交替的速度之快往往令人咂舌,不用多少时间,你 ...

  4. 大神所写的深度好文---Gradle 构建工具

    什么是构建工具? 我们大家都知道 Gradle 是一种构建工具,那么什么是构建工具呢? 网上一大堆的文字解释我觉得很难理解,这里我以咱们 Android 开发来举个例子吧. 我们以前开发都是用 Ecl ...

  5. 项目自动构建工具对比(Maven、Gradle、Ant)

    Java世界中主要有三大构建工具:Ant.Maven和Gradle.经过几年的发展,Ant几乎销声匿迹.Maven也日薄西山,而Gradle的发展则如日中天. Maven的主要功能主要分为5点,分别是 ...

  6. 一览新的 Android Gradle 构建工具:新的 DSL 结构 和 Gradle 2.5

    译者地址:[翻]一览新的 Android Gradle 构建工具:新的 DSL 结构 和 Gradle 2.5 原文:First Look at New Android Gradle Build To ...

  7. 更快的Maven构建工具mvnd和Gradle哪个更快?

    Maven 作为经典的项目构建工具相信很多人已经用很久了,但如果体验过 Gradle,那感觉只有两个字"真香". 前段时间测评了更快的 Maven 构建工具 mvnd,感觉性能挺高 ...

  8. Java构建工具:如何用Maven,Gradle和Ant+Ivy进行依赖管理

    原文来自:https://zeroturnaround.com/rebellabs/java-build-tools-how-dependency-management-works-with-mave ...

  9. Gulp vs Grunt 前端构建工具对比

    Gulp vs Grunt 前端工程的构建工具对比 1. Grunt -> Gulp 早些年提到构建工具,难免会让人联想到历史比较悠久的Make,Ant,以及后来为了更方便的构建结构类似的Jav ...

随机推荐

  1. LVS中文站点

    http://blog.csdn.net/turkeyzhou/article/details/16980161 http://zh.linuxvirtualserver.org/

  2. linux 创建 bootable iso 文件

    windows制作iso文件通过ultraiso可以实现. linux下用mkisofs这个命令就可以 最简单的用法 mkisofs -o target.iso source 要制作可以启动的iso文 ...

  3. python supervisor进程监控工具的使用

    supervisor —— a process control system 另外一个类似 supervisor的工具,因为supervisor 不兼容python3, !!! Circus Proc ...

  4. sqlite 数据库 相关知识

    一基本简单介绍 SQLite 是一个自持的(self-contained).无server的.零配置的.事务型的关系型数据库引擎.由于他非常小,所以也能够作为嵌入式数据库内建在你的应用程序中. SQL ...

  5. session失效,使用ajax请求数据被拦截,此时正常的处理逻辑是跳到登录界面,而不是界面没有变化(java推断是否是ajax请求)

    在登录过滤器中.推断请求是ajax请求还是超链接或者地址栏变化的请求 if (httpServletReq.getHeader("x-requested-with") != nul ...

  6. 【Eclipse提高开发速度-插件篇】安装VJET插件,JS等提示开发插件

    1.安装Apache Batik CSS 一般安装VJET插件会出现 Cannot complete the install because one or more required items co ...

  7. 【Unity 3D】学习笔记三十六:物理引擎——刚体

    物理引擎就是游戏中模拟真是的物理效果.如两个物体发生碰撞,物体自由落体等.在unity中使用的是NVIDIA的physX,它渲染的游戏画面很逼真. 刚体 刚体是一个很很中要的组件. 默认情况下,新创的 ...

  8. Android简单开发之 通用Adapter ViewHolder

    我们寻常使用Adapter的方式 public class BusbaseSearchApadter extends SimpleBaseApadter { private List<Busba ...

  9. jquery操作删除元素

    通过 jQuery,可以很容易地删除已有的 HTML 元素. 删除元素/内容 如需删除元素和内容,一般可使用以下两个 jQuery 方法: remove() - 删除被选元素(及其子元素) empty ...

  10. CSS3径向渐变实现优惠券波浪造型

    效果看下图: 左右的波浪边框用CSS搞定这个效果.利用CSS radial-gradient() 函数 CSS 语法: background: radial-gradient(shape size a ...