随着信息化的快速发展,IT项目变得越来越复杂,通常都是由多个子系统共同协作完成。对于这种多系统、多项目的情况,很多构建工具都已经提供了不错的支持,像maven、ant。Gradle除了借鉴了ant或者maven的继承的方式定义子项目,也提供了一种更为方便的集中配置的方式,大大减少了构建带来的复杂度。除此之外,Gradle还提供了清晰的Project树模型来映射多项目的组织结构。下面,让我们了解一下如何使用Gradle构建多项目。

1. 多项目定义及结构

在Gradle中,使用文件settings.gradle定义当前项目的子项目,格式如下所示:

include 'sub-project1', 'sub-project2', 'sub-project3',

它表示在当前的项目下建立三个子项目,分别为'sub-project1', 'sub-project2', 'sub-project3'。默认情况下,每个子项目的名称对应着当前操作系统目录下的一个子目录。

当Gradle运行时,会根据settings.gradle的配置情况,构建一个单根节点的项目树。其中的每个子节点代表一个项目(Project),每个项目都有一个唯一的路径表示它在当前树中的位置,路径的定义方式类似:

Root:<Level1-子节点>:<Level2-子节点>:<Level3-子节点>

也可以简写成“:<Level1-子节点>:<Level2-子节点>:<Level3-子节点>”。借助这种路径的定义方式,我们可以在build.gradle去访问不同的子项目。另外,对于单项目,实际上是一种特殊的、只存在根节点,没有子节点的项目树。

例如,我们有个产品A,包括以下几个组件core,web,mobile。分别代表"核心逻辑"、"网站"、“手机客户端”。 因为每个组件是独立的部分,这个时候最好我们能定义多个子项目,让每个子项目分别管理自己的构建。于是我们可以这样定义A/settings.gradle

include 'core', 'web', 'mobile'

按照之前描述的,core组件对应A/core目录,web组件对应A/web目录,mobile组件对应A/mobile目录。接下来,我们就可以在每个组件内部,定义build.gradle负责管理当前组件的构建。

Gradle提供了一个内建的task 'gradle projects',可以 帮助我们查看当前项目所包含的子项目,下面让我们看看gradle projects的输出结果:

$ gradle projects

:projects

------------------------------------------------------------

Root project

------------------------------------------------------------

Root project 'A'

+--- Project ':core'

+--- Project ':mobile'

\--- Project ':web

结果一目了然,首先是Root级别的项目A,然后是A下面的子项目'core', 'mobile', 'mobile'

最终的文件以及目录结构如下所示:

A

   --settings.gradle

   --build.gradle

   --core

     --build.gradle

   --web

      --build.gradle

   --mobile

      --build.gradle

如果你不喜欢这种默认的结构,也可以按照如下方式定义子项目的名称和物理目录结构:

include(':core)

project(':core').projectDir = new File(settingsDir, 'core-xxx') 



include(':web)

project(':web').projectDir = new File(settingsDir, 'web-xxx') 



include(':mobile)

project(':mobile').projectDir = new File(settingsDir, 'mobile-xxx') 

在这个例子中,子项目core实际上对应的物理目录为A/core-xxx,web实际上对应的是A/web-xxx,mobile也类似。

虽然我们更改了子项目的物理目录结构,不过由于我们在build.gradle中使用的是类似 “ :<SubProject>”的方式访问对应的子项目,所以目录结构的改变,对我们Gradle的构建脚本并不会产生影响。

接下来,考虑一个更复杂的情况,随着产品的发展,mobile这个组件慢慢的划分成了Android和IOS两个部分,这时我们只需要在目录A/mobile下定义新的settings.gradle,并加入如下部分:

include 'android', 'ios'

现在,mobile组件下将存在两个新的子项目 "android"和"ios"

于是,这时候'gradle projects'的目录结构就变成

A

   --settings.gradle

   --core

      --build.gradle

   --web

      --build.gradle

   --mobile

      --settings.gradle

      --ios

        --build.gradle

      --android

        --build.gradle

2. 多项目的集中配置

对于大多数构建工具,对于子项目的配置,都是基于继承的方式。Gradle除了提供继承的方式来设置子项目,还提供了另外一种集中的配置方式,方便我们统一管理子项目的信息。下面看一个例子,打开A/build.gradle,输入如下部分:

allprojects {

    task hello << {task -> println "I'm $task.project.name" }

}

subprojects {

    hello << {println "- I am the sub project of A"}

}

project(':core').hello << {

      println "- I'm the core component and provide service for other parts."

}

对于上面所示的代码,已经很表意了:

allprojects{xxx}  这段代码表示,对于所有的project,Gradle都将定义一个名称是hello的Task { println "I'm $task.project.name"} 。

subprojects{xxxx}的这段代码表示,对于所有的子project,将在名称为hello的Task上追加Action {println "- I am the sub project of A"}

注意:关于Task和Action的关系,请看我之前写的本系列的第一部分。

project(':core')的这段代码表示,对于名称为core的project,将在名称为hello的Task上追加Action { println "- I'm the core component and provide service for other parts." }

3. 多项目的Task执行

之前我们已经了解了多项目的结构以及如何通过路径去访问子项目。现在让我们看看如何使用Gradle来执行多项目。

在Gradle中,当在当前项目上执行gradle <Task>时,gradle会遍历当前项目以及其所有的子项目,依次执行所有的同名Task,注意:子项目的遍历顺序并不是按照setting.gradle中的定义顺序,而是按照子项目的首字母排列顺序。

基于刚才的例子,如果我们在根目录下,执行gradle hello,那么所有子项目的“hello” Task都会被执行。如果我们在mobile目录下执行gradle hello,那么mobile、android以及IOS的“hello” Task都会被执行。关于该例子的运行结果,这里就不贴出来了。大家如果有兴趣的话可以试试。

4. 总结

这篇文章主要描述了使用Gradle管理多项目的知识。相比Ant或者Maven,Gradle提供了更灵活的配置方式。更重要的是,Gradle还提供了很多内建的Task帮助我们查看或者管理项目。这次就先聊到这里,下次我们来看看Gradle的生命周期。

从零开始学习Gradle之三---多项目构建的更多相关文章

  1. VUE2 第六天学习--- vue单文件项目构建

    阅读目录 VUE2 第六天学习--- vue单文件项目构建 回到顶部 VUE2 第六天学习--- vue单文件项目构建 VUE单文件组件在Vue项目中,然后使用 new Vue({el: '#cont ...

  2. (转)Maven学习总结(二)——Maven项目构建过程练习

    孤傲苍狼 只为成功找方法,不为失败找借口! Maven学习总结(二)——Maven项目构建过程练习 上一篇只是简单介绍了一下maven入门的一些相关知识,这一篇主要是体验一下Maven高度自动化构建项 ...

  3. Maven学习---使用maven进行项目构建

    1. 使用maven进行项目构建 MyEclipse 自带maven 插件 Eclipse 需要单独安装maven插件 1.1. Maven 在企业中怎么用的 ? Maven : 项目构建工具 ,进行 ...

  4. Maven学习总结(二)——Maven项目构建过程练习

    上一篇只是简单介绍了一下maven入门的一些相关知识,这一篇主要是体验一下Maven高度自动化构建项目的过程 一.创建Maven项目 1.1.建立Hello项目 1.首先建立Hello项目,同时建立M ...

  5. Maven学习总结(二)——Maven项目构建过程练习_转载

    上一篇只是简单介绍了一下maven入门的一些相关知识,这一篇主要是体验一下Maven高度自动化构建项目的过程 一.创建Maven项目 1.1.建立Hello项目 1.首先建立Hello项目,同时建立M ...

  6. 转】Maven学习总结(二)——Maven项目构建过程练习

    原博文出自于:http://www.cnblogs.com/xdp-gacl/p/4051690.html 感谢! 上一篇只是简单介绍了一下maven入门的一些相关知识,这一篇主要是体验一下Maven ...

  7. Maven学习总结(2)——Maven项目构建过程练习

    Maven学习总结(二)--Maven项目构建过程练习 上一篇只是简单介绍了一下maven入门的一些相关知识,这一篇主要是体验一下Maven高度自动化构建项目的过程 一.创建Maven项目 1.1.建 ...

  8. 取代 Maven?这款项目构建工具性能提升 300%

    在 GitHub 上闲逛的时候,发现了一个新的项目:maven-mvnd,持续霸占 GitHub trending 榜单好几天了. maven-mvnd,可以读作 Maven Daemon,译作 Ma ...

  9. 第一次使用Android Studio时你应该知道的一切配置(三):gradle项目构建

    ​[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...

随机推荐

  1. WEBAPI 最近更新项目时 服务器总是提示:An error has occurred.

    解决办法: 在webconfig中设置 <system.web><customErrors mode="Off"/></system.web> ...

  2. C#委托的定义 以及使用方式详解,更简单的理解委托。

    委托的声明及定义: 委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得 ...

  3. SQL SERVER中Datetime时间的范围与.net的DateTime对象的区别

    对于编写.net程序中我们一般写默认的时间,我们会自动创建一个new DateTime()对象.但与SQL SERVER连用我们就会出现一个时间范围的问题. 今天我就记录一下该时间问题. 我们创建的n ...

  4. 在Windows server 2019 Core 版本上安装SQL2016

    安装系统后,通过网络等方式先把安装ISO的文件copy过来,虚拟机则用挂一个虚拟光驱即可,然后cd进入目录,执行以下命名即可安装核心服务了: Setup.exe /qs /ACTION=Install ...

  5. (备忘)Java数据类型中String、Integer、int相互间的转换

    1.Integer转换成int的方法 Integer i; int k = i.intValue();即Integer.intValue(); 2.int转换成Integer int i; Integ ...

  6. asyncio:python3未来并发编程主流、充满野心的模块

    介绍 asyncio是Python在3.5中正式引入的标准库,这是Python未来的并发编程的主流,非常重要的一个模块.有一个web框架叫sanic,就是基于asyncio,语法和flask类似,使用 ...

  7. C语言求π的方法

    #include <stdio.h> #include <math.h> int main() { int r; double PI,s; scanf("%d&quo ...

  8. 在Python中,如何用一行代码去判定整数二进制中的连续 1

    利用字节位操作如何判断一个整数的二进制是否含有至少两个连续的1 的方法有多种,大家第一反应应该想到的是以下的第一种方法. 方法一:从头到尾遍历一遍每一位即可找出是否有连续的1存在 这个方法是最普遍的. ...

  9. mysql服务脚本

    #!/bin/bash #*************************** #* copyleft huihui 2015-08-11 #**************************** ...

  10. goquery 解析不了noscript

    今天在用goquery的时候 解析noscript标签的时候.发现一直获取不到里面的元素. google得到.需要去除noscript标签. s.Find("noscript"). ...