本文是边看Gradle英文文档边作的笔记:Chapter 11. Composite builds
建议看的时候动手实验一下,帮助理解java
简单地说,Gradle的复合构建就是一个构建包含了其它构建。
Gradle的复合构建跟多项目构建很类似,
惟一的区别是多项目构建引入的是单个project(引入的java依赖可使用),
而复合构建引入的是一个完整的构建(除了引入的java依赖,引入的task也可使用)。web
能够先看如下代码示例,有个直观的区分:微信
多项目构建:app
文件:my-app/build.gradle: dependencies { compile project(':util') compile project(':web') } //这里假设有一个my-app的构建,my-app构建依赖了util工程和web工程。
复合构建:ide
文件:my-app/build.gradle: dependencies { compile "org.sample:util:1.0" compile "org.sample:web:1.0" } //my-app构建没有直接依赖util和web。而是声明了对util和web的构建结果(class文件)的依赖
多项目构建和复合构建很是类似,所以比较难区分,我是从两种构建方式关注点上区分的。函数
复合构建适用的场景:微信支付
被复合构建(my-app)引用的构建(util、web),只会向复合构建提供构建的结果,而配置信息是不会被导入到复合构建中的。gradle
若是被复合构建(my-app)包含的构建(util、web)中有依赖能够知足复合构建的依赖,会优先采用(util、web)该依赖。ui
Gradle默认会自行决定是否采用引入构建的依赖,可是官方建议最好显式声明(11.4, “Declaring the dependencies substituted by an included build”)idea
复合构建(my-app)能够直接声明对包含的构建(util、web)的task的依赖,
可是被包含的构建(util、web)因为它们是独立的,
被包含的构建(util、web)不能依赖复合构建(my-app)中的task,
也不能依赖其它被包含的构建的task。
首先须要声明复合构建的依赖
下面的多个例子演示如何将2个独立开发的构建组合到一个复合构建里面。
在例子里面,my-utils是一个多项目构建,包含了2个java库的构建(number-utils和string-utils),
而my-app则是一个复合构建,my-app使用了这两个java库里面的函数。
须要注意的是,my-app不是直接依赖my-utils,而是声明对my-utils的两个java库的打包结果的依赖
声明my-app的依赖项:
my-app/build.gradle
apply plugin: 'java' apply plugin: 'application' apply plugin: 'idea' group "org.sample" version "1.0" mainClassName = "org.sample.myapp.Main" dependencies { compile "org.sample:number-utils:1.0"//<--依赖number-utils子项目的产出结果 compile "org.sample:string-utils:1.0"//<--依赖string-utils子项目的产出结果 } repositories { jcenter() }
方式1:经过gradle命令行的--include-build选项实现复合构建
目录结构是这样的:
/samples/compositeBuilds/basic |--my-app |--build.gradle |--src/main/java |--my-utils |--number-utils |--src/main/java |--string-utils |--src/main/java |--build.gradle |--setting.gradle
在my-app目录下运行命令行:gradle --include-build ../my-utils run
便可实现复合构建
这个命令行意思是:
经过gradle --include-build ../my-utils
命令告诉gradle先去执行my-utils的构建,my-utils如无心外会产出两个java库的构建,number-utils和string-utils目录下会出现build目录,build目录就是构建的产出结果。
而后,因为my-app/build.gradle中声明了对number-utils和string-utils产出结果的依赖(就是下面的那部分代码),因此my-app的构建也能成功执行。
dependencies { compile "org.sample:number-utils:1.0"//<--依赖number-utils子项目的产出结果 compile "org.sample:string-utils:1.0"//<--依赖string-utils子项目的产出结果 }
最后,对my-app执行run任务,即运行my-app的代码。
方式2:在setting.gradle文件中使用includeBuild语句声明复合构建
实现以下:
my-app/build.gradle的配置依旧不变
...... dependencies { compile "org.sample:number-utils:1.0"//<--依赖number-utils子项目的产出结果 compile "org.sample:string-utils:1.0"//<--依赖string-utils子项目的产出结果 } ......
my-app/setting.gradle
rootProject.name = 'my-app' includeBuild '../my-utils'
方式2-补充:不修改my-app/setting.gradle文件实现复合构建
方式2中经过在my-app/setting.gradle文件中添加includeBuild '../my-utils'
配置来引入my-utils构建。
若是有特定场景要求不能修改my-app项目的任何文件该怎么办呢?这时能够采起另外一种方式来实现,创建一个新的构建(即一个目录),在新构建中引入my-app和my-utils,注意,原来是在my-app中引入my-utils的。
实现以下:
目录结构是这样的:
/samples/compositeBuilds/basic |--composite |--build.gradle |--setting.gradle |--my-app |--build.gradle |--src/main/java |--my-utils |--number-utils |--src/main/java |--string-utils |--src/main/java |--build.gradle |--setting.gradle
composite/setting.gradle:
//在composite构建中引入my-app构建和my-utils构建 rootProject.name='adhoc' includeBuild '../my-app' includeBuild '../my-utils'
因为咱们新建了一个名为composite的构建来包含my-app构建和my-utils构建,可是composite构建到目前为止是没有run
任务的(原来的my-app构建中定义了mainClassName = "org.sample.myapp.Main"
因此能执行run
任务),那该怎么办呢?
答案就是咱们在composite构建中定义一个的run
任务,把该run
任务的执行委派给my-app构建的run
任务:
composite/build.gradle:
apply plugin: 'idea' defaultTasks 'run' task run { //composite构建中定义一个run任务,委派给my-app的run任务 dependsOn gradle.includedBuild('my-app').task(':run') }
注意:一个构建须要知足什么条件才能被复合构建引入?