204 lines
8.1 KiB
Groovy
204 lines
8.1 KiB
Groovy
/*
|
|
* Copyright (C) 2016 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
import android.support.build.ApiModule
|
|
import java.nio.file.Path;
|
|
import java.nio.file.Paths;
|
|
|
|
/**
|
|
* To add platform specific code to a library:
|
|
* 1) add the related source set into the studioCompat map (defined below)
|
|
* 2) In your build gradle file, call:
|
|
* * createApiSourceSets(project, gradle.ext.studioCompat.modules.<PROJECT>.apiTargets)
|
|
* * setApiModuleDependencies(project, dependencies, gradle.ext.studioCompat.modules.<PROJECT>.dependencies)
|
|
*/
|
|
|
|
def studioCompat = [
|
|
enableApiModules : hasProperty('android.injected.invoked.from.ide'),
|
|
modules : [
|
|
compat : [
|
|
apiTargets : [
|
|
new ApiModule("gingerbread",9),
|
|
new ApiModule("honeycomb",11),
|
|
new ApiModule("honeycomb_mr1",12),
|
|
new ApiModule("honeycomb_mr2",13),
|
|
new ApiModule("ics",14),
|
|
new ApiModule("ics-mr1",15),
|
|
new ApiModule("jellybean", 16),
|
|
new ApiModule("jellybean-mr1",17),
|
|
new ApiModule("jellybean-mr2",18),
|
|
new ApiModule("kitkat",19),
|
|
new ApiModule("api20",20),
|
|
new ApiModule("api21",21),
|
|
new ApiModule("api22",22),
|
|
new ApiModule("api23",23),
|
|
new ApiModule("api24", ApiModule.CURRENT)
|
|
],
|
|
dependencies : [":support-annotations"],
|
|
folder : "compat",
|
|
moduleName : "support-compat"
|
|
],
|
|
mediacompat : [
|
|
apiTargets : [
|
|
new ApiModule("ics",14),
|
|
new ApiModule("jellybean-mr2",18),
|
|
new ApiModule("kitkat",19),
|
|
new ApiModule("api21",21),
|
|
new ApiModule("api22",22),
|
|
new ApiModule("api23",23),
|
|
new ApiModule("api24", ApiModule.CURRENT)
|
|
],
|
|
dependencies : [":support-compat"],
|
|
folder : "media-compat",
|
|
moduleName : "support-media-compat"
|
|
],
|
|
coreutils : [
|
|
apiTargets : [
|
|
new ApiModule("gingerbread",9),
|
|
new ApiModule("honeycomb",11),
|
|
new ApiModule("jellybean", 16),
|
|
new ApiModule("kitkat",19),
|
|
new ApiModule("api20",20),
|
|
new ApiModule("api21",21),
|
|
new ApiModule("api23",23),
|
|
new ApiModule("api24", ApiModule.CURRENT)
|
|
],
|
|
dependencies : [":support-compat"],
|
|
folder : "core-utils",
|
|
moduleName : "support-core-utils"
|
|
],
|
|
coreui : [
|
|
apiTargets : [
|
|
new ApiModule("honeycomb",11),
|
|
new ApiModule("ics",14),
|
|
new ApiModule("jellybean-mr2",18),
|
|
new ApiModule("api21",21)
|
|
],
|
|
dependencies : [":support-compat"],
|
|
folder : "core-ui",
|
|
moduleName : "support-core-ui"
|
|
],
|
|
fragment : [
|
|
apiTargets : [
|
|
new ApiModule("gingerbread",9),
|
|
new ApiModule("honeycomb",11),
|
|
new ApiModule("jellybean", 16),
|
|
new ApiModule("api21",21)
|
|
],
|
|
dependencies : [":support-media-compat", ":support-core-ui", ":support-core-utils"],
|
|
folder : "fragment",
|
|
moduleName : "support-fragment"
|
|
],
|
|
v13 : [
|
|
apiTargets : [
|
|
new ApiModule("ics", 14),
|
|
new ApiModule("ics-mr1", 15),
|
|
new ApiModule("api23", 23),
|
|
new ApiModule("api24", 24),
|
|
new ApiModule("api25", ApiModule.CURRENT)
|
|
],
|
|
dependencies : [":support-v4"],
|
|
folder : "v13",
|
|
moduleName : "support-v13"
|
|
],
|
|
mediaRouter : [
|
|
apiTargets : [
|
|
new ApiModule("jellybean", 16),
|
|
new ApiModule("jellybean-mr1", 17),
|
|
new ApiModule("jellybean-mr2", 18),
|
|
new ApiModule("api24", ApiModule.CURRENT)
|
|
],
|
|
folder : "v7/mediarouter",
|
|
moduleName : "support-mediarouter-v7"
|
|
]
|
|
]
|
|
]
|
|
|
|
/**
|
|
* Adds a link to the previous ApiModule for each module. This information is later used when
|
|
* setting dependencies.
|
|
*/
|
|
def setupDependencies(projectConfig) {
|
|
projectConfig.apiTargets.eachWithIndex { entry, index ->
|
|
entry.parentModuleName = projectConfig.moduleName
|
|
entry.prev = index == 0 ? null : projectConfig.apiTargets[index - 1]
|
|
}
|
|
}
|
|
gradle.ext.currentSdk = studioCompat.enableApiModules ? ApiModule.CURRENT : 'current'
|
|
|
|
// the hashmap from apiModuleProjectFolder -> ApiModule
|
|
gradle.ext.folderToApiModuleMapping = new HashMap()
|
|
|
|
/**
|
|
* For each APIModule in the given projectConfig, creates a gradle module. These modules use the
|
|
* common `apiModule.gradle` build file.
|
|
*/
|
|
def createModules(projectConfig) {
|
|
Path buildFile = Paths.get(file("apiModule.gradle").toURI())
|
|
projectConfig.apiTargets.each { ApiModule module ->
|
|
logger.info "creating ${module.moduleName}"
|
|
module.setParentModuleDependencies(projectConfig.dependencies)
|
|
include "${module.moduleName}"
|
|
def folder = new File(rootDir, "${projectConfig.folder}/${module.folderName}")
|
|
project("${module.moduleName}").projectDir = folder
|
|
project("${module.moduleName}").buildFileName = Paths.get(folder.toURI()).relativize(buildFile)
|
|
gradle.ext.folderToApiModuleMapping[folder.canonicalPath] = module
|
|
}
|
|
}
|
|
|
|
/**
|
|
* returns the APIModule for the given project.
|
|
*/
|
|
ApiModule getApiModule(Project project) {
|
|
return gradle.ext.folderToApiModuleMapping[project.projectDir.canonicalPath]
|
|
}
|
|
|
|
studioCompat.modules.each { k, v ->
|
|
setupDependencies(v)
|
|
}
|
|
// create these fake modules only if Studio opens the project.
|
|
if (studioCompat.enableApiModules) {
|
|
// validate we have the 99 folder, otherwise it wont work
|
|
def currentSdkPrebuilt = file("${rootProject.projectDir}/../../prebuilts/sdk/" +
|
|
"${ApiModule.CURRENT}/")
|
|
if (!currentSdkPrebuilt.exists()) {
|
|
throw new GradleScriptException(
|
|
"You need a symlink in prebuilts/sdk/${ApiModule.CURRENT} that points to"
|
|
+ " prebuilts/sdk/current."
|
|
+ "Without it, studio cannot understand current SDK.\n"
|
|
+ "> ln -s ../../prebuilts/sdk/current "
|
|
+ "../../prebuilts/sdk/${ApiModule.CURRENT}\n"
|
|
, new Exception())
|
|
}
|
|
Properties localProps = new Properties()
|
|
def localPropsStream = new FileInputStream(file("${rootProject.projectDir}/local.properties"))
|
|
try {
|
|
localProps.load(localPropsStream)
|
|
def sdkDir = localProps.get("sdk.dir")
|
|
if (sdkDir != null && sdkDir != "") {
|
|
throw new GradleScriptException("You should not have sdk.dir in local.properties because"
|
|
+ " it overrides android.dir and prevents studio from seeing current sdk. "
|
|
+ " Studio may add it by mistake, just remove it and it will work fine.",
|
|
new Exception())
|
|
}
|
|
} finally {
|
|
localPropsStream.close()
|
|
}
|
|
studioCompat.modules.each { k, v ->
|
|
createModules(v)
|
|
}
|
|
}
|
|
gradle.ext.studioCompat = studioCompat
|
|
gradle.ext.getApiModule = this.&getApiModule
|