blob: 0c6aa481bbac12257427dad5eea916d3d6fda12d [file] [log] [blame]
Yigit Boyar3986e042016-02-08 18:31:38 -08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16import android.support.build.ApiModule
17import java.nio.file.Path;
18import java.nio.file.Paths;
19
20/**
21 * To add platform specific code to a library:
22 * 1) add the related source set into the studioCompat map (defined below)
23 * 2) In your build gradle file, call:
24 * * createApiSourceSets(project, gradle.ext.studioCompat.modules.<PROJECT>.apiTargets)
25 * * setApiModuleDependencies(project, dependencies, gradle.ext.studioCompat.modules.<PROJECT>.dependencies)
26 */
27
28def studioCompat = [
Yigit Boyar6fe8ece2016-05-26 17:01:47 +000029 enableApiModules : hasProperty('android.injected.invoked.from.ide'),
Yigit Boyar3986e042016-02-08 18:31:38 -080030 modules : [
Chris Banes2c63c7b2016-05-04 13:54:06 +010031 compat : [
Yigit Boyar3986e042016-02-08 18:31:38 -080032 apiTargets : [
Kirill Grouchnikov81fc7d72016-05-11 10:01:23 -070033 new ApiModule("gingerbread",9),
Yigit Boyar3986e042016-02-08 18:31:38 -080034 new ApiModule("honeycomb",11),
35 new ApiModule("honeycomb_mr1",12),
36 new ApiModule("honeycomb_mr2",13),
37 new ApiModule("ics",14),
38 new ApiModule("ics-mr1",15),
39 new ApiModule("jellybean", 16),
40 new ApiModule("jellybean-mr1",17),
41 new ApiModule("jellybean-mr2",18),
42 new ApiModule("kitkat",19),
Kirill Grouchnikov32d19172016-05-10 16:08:11 -070043 new ApiModule("api20",20),
Yigit Boyar3986e042016-02-08 18:31:38 -080044 new ApiModule("api21",21),
45 new ApiModule("api22",22),
46 new ApiModule("api23",23),
47 new ApiModule("api24", ApiModule.CURRENT)
48 ],
49 dependencies : [":support-annotations"],
Chris Banes2c63c7b2016-05-04 13:54:06 +010050 folder : "compat",
51 moduleName : "support-compat"
52 ],
Kirill Grouchnikovd3c53472016-05-10 08:02:18 -070053 mediacompat : [
54 apiTargets : [
Kirill Grouchnikovd3c53472016-05-10 08:02:18 -070055 new ApiModule("ics",14),
56 new ApiModule("jellybean-mr2",18),
57 new ApiModule("kitkat",19),
58 new ApiModule("api21",21),
59 new ApiModule("api22",22),
60 new ApiModule("api23",23),
61 new ApiModule("api24", ApiModule.CURRENT)
62 ],
Kirill Grouchnikovff22d812016-05-11 15:24:25 -070063 dependencies : [":support-compat"],
Kirill Grouchnikovd3c53472016-05-10 08:02:18 -070064 folder : "media-compat",
65 moduleName : "support-media-compat"
66 ],
Kirill Grouchnikovff22d812016-05-11 15:24:25 -070067 coreutils : [
68 apiTargets : [
69 new ApiModule("gingerbread",9),
70 new ApiModule("honeycomb",11),
71 new ApiModule("jellybean", 16),
72 new ApiModule("kitkat",19),
73 new ApiModule("api20",20),
74 new ApiModule("api21",21),
75 new ApiModule("api23",23),
76 new ApiModule("api24", ApiModule.CURRENT)
77 ],
78 dependencies : [":support-compat"],
79 folder : "v4",
80 moduleName : "support-core-utils"
81 ],
82 coreui : [
83 apiTargets : [
84 new ApiModule("honeycomb",11),
85 new ApiModule("ics",14),
86 new ApiModule("jellybean-mr2",18),
87 new ApiModule("api21",21)
88 ],
89 dependencies : [":support-compat"],
90 folder : "core-ui",
91 moduleName : "support-core-ui"
92 ],
93 fragment : [
94 apiTargets : [
95 new ApiModule("gingerbread",9),
96 new ApiModule("honeycomb",11),
97 new ApiModule("jellybean", 16),
98 new ApiModule("api21",21)
99 ],
Kirill Grouchnikovc0160502016-05-16 18:27:36 -0700100 dependencies : [":support-media-compat", ":support-core-ui", ":support-core-utils"],
Kirill Grouchnikovff22d812016-05-11 15:24:25 -0700101 folder : "fragment",
102 moduleName : "support-fragment"
Yigit Boyar3986e042016-02-08 18:31:38 -0800103 ],
104 v13 : [
105 apiTargets : [
106 new ApiModule("ics", 14),
107 new ApiModule("ics-mr1", 15),
108 new ApiModule("api23", 23),
109 new ApiModule("api24", ApiModule.CURRENT)
110 ],
111 dependencies : [":support-v4"],
112 folder : "v13",
113 moduleName : "support-v13"
Yigit Boyar01b95042016-04-28 14:34:48 -0700114 ],
115 mediaRouter : [
116 apiTargets : [
Yigit Boyar6fe8ece2016-05-26 17:01:47 +0000117 new ApiModule("jellybean", 16),
118 new ApiModule("jellybean-mr1", 17),
119 new ApiModule("jellybean-mr2", 18),
Yigit Boyar01b95042016-04-28 14:34:48 -0700120 new ApiModule("api24", ApiModule.CURRENT)
121 ],
Yigit Boyar01b95042016-04-28 14:34:48 -0700122 folder : "v7/mediarouter",
123 moduleName : "support-mediarouter-v7"
Yigit Boyar3986e042016-02-08 18:31:38 -0800124 ]
125 ]
126]
127
128/**
129 * Adds a link to the previous ApiModule for each module. This information is later used when
130 * setting dependencies.
131 */
132def setupDependencies(projectConfig) {
133 projectConfig.apiTargets.eachWithIndex { entry, index ->
134 entry.parentModuleName = projectConfig.moduleName
135 entry.prev = index == 0 ? null : projectConfig.apiTargets[index - 1]
136 }
137}
Yigit Boyar6fe8ece2016-05-26 17:01:47 +0000138gradle.ext.currentSdk = studioCompat.enableApiModules ? ApiModule.CURRENT : 'current'
Yigit Boyar3986e042016-02-08 18:31:38 -0800139
140// the hashmap from apiModuleProjectFolder -> ApiModule
141gradle.ext.folderToApiModuleMapping = new HashMap()
142
143/**
144 * For each APIModule in the given projectConfig, creates a gradle module. These modules use the
145 * common `apiModule.gradle` build file.
146 */
147def createModules(projectConfig) {
148 Path buildFile = Paths.get(file("apiModule.gradle").toURI())
149 projectConfig.apiTargets.each { ApiModule module ->
150 logger.info "creating ${module.moduleName}"
151 module.setParentModuleDependencies(projectConfig.dependencies)
152 include "${module.moduleName}"
153 def folder = new File(rootDir, "${projectConfig.folder}/${module.folderName}")
154 project("${module.moduleName}").projectDir = folder
155 project("${module.moduleName}").buildFileName = Paths.get(folder.toURI()).relativize(buildFile)
156 gradle.ext.folderToApiModuleMapping[folder.canonicalPath] = module
157 }
158}
159
160/**
161 * returns the APIModule for the given project.
162 */
163ApiModule getApiModule(Project project) {
164 return gradle.ext.folderToApiModuleMapping[project.projectDir.canonicalPath]
165}
166
167studioCompat.modules.each { k, v ->
168 setupDependencies(v)
169}
170// create these fake modules only if Studio opens the project.
Yigit Boyar6fe8ece2016-05-26 17:01:47 +0000171if (studioCompat.enableApiModules) {
Yigit Boyar3986e042016-02-08 18:31:38 -0800172 // validate we have the 99 folder, otherwise it wont work
173 def currentSdkPrebuilt = file("${rootProject.projectDir}/../../prebuilts/sdk/" +
174 "${ApiModule.CURRENT}/")
175 if (!currentSdkPrebuilt.exists()) {
176 throw new GradleScriptException(
177 "You need a symlink in prebuilts/sdk/${ApiModule.CURRENT} that points to"
178 + " prebuilts/sdk/current."
179 + "Without it, studio cannot understand current SDK.\n"
180 + "> ln -s ../../prebuilts/sdk/current "
181 + "../../prebuilts/sdk/${ApiModule.CURRENT}\n"
182 , new Exception())
183 }
184 Properties localProps = new Properties()
185 def localPropsStream = new FileInputStream(file("${rootProject.projectDir}/local.properties"))
186 try {
187 localProps.load(localPropsStream)
188 def sdkDir = localProps.get("sdk.dir")
189 if (sdkDir != null && sdkDir != "") {
190 throw new GradleScriptException("You should not have sdk.dir in local.properties because"
191 + " it overrides android.dir and prevents studio from seeing current sdk. "
192 + " Studio may add it by mistake, just remove it and it will work fine.",
193 new Exception())
194 }
195 } finally {
196 localPropsStream.close()
197 }
198 studioCompat.modules.each { k, v ->
199 createModules(v)
200 }
201}
202gradle.ext.studioCompat = studioCompat
Chris Banes2c63c7b2016-05-04 13:54:06 +0100203gradle.ext.getApiModule = this.&getApiModule