aboutsummaryrefslogtreecommitdiff
path: root/gradle/src
diff options
context:
space:
mode:
authorXavier Ducrohet <xav@android.com>2012-10-05 19:34:10 -0700
committerXavier Ducrohet <xav@android.com>2012-10-08 11:50:04 -0700
commit74f7f6ebd5851679185b6c257f1523b0a41293dd (patch)
tree8e56958fcbebef354577d675accfe0e9f5bcb119 /gradle/src
parentdc71ab2627ac4f4f8843dd0d5a1d84ac0f04662d (diff)
downloadbuild-74f7f6ebd5851679185b6c257f1523b0a41293dd.tar.gz
Per-lib prepare task.
each Android library dependency is assigned its own task to ensure the library is unzipped. This task is set to depend on the build dependencies of the configuration(s) that brought it in the dependency graph. The Prepare task for each variant is set to depend on all the prepareLibTask needed by the dependency graph. Change-Id: I17829eac949c12df706d2328441fc90f9c64701d
Diffstat (limited to 'gradle/src')
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy106
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/PrepareDependenciesTask.groovy24
-rw-r--r--gradle/src/main/groovy/com/android/build/gradle/PrepareLibraryTask.groovy37
3 files changed, 115 insertions, 52 deletions
diff --git a/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy
index 954d5dd..30d7a18 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy
@@ -31,6 +31,8 @@ import com.android.builder.SdkParser
import com.android.builder.SourceProvider
import com.android.builder.VariantConfiguration
import com.android.utils.ILogger
+import com.google.common.collect.ArrayListMultimap
+import com.google.common.collect.Multimap
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.NamedDomainObjectContainer
@@ -48,6 +50,7 @@ import org.gradle.api.plugins.JavaBasePlugin
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.Copy
import org.gradle.api.tasks.compile.JavaCompile
+import org.gradle.util.GUtil
/**
* Base class for all Android plugins
@@ -59,6 +62,7 @@ abstract class BasePlugin {
private final Map<Object, AndroidBuilder> builders = [:]
final List<ApplicationVariant> variants = []
+ final Map<AndroidDependencyImpl, PrepareLibraryTask> prepareTaskMap = [:]
protected Project project
protected File sdkDir
@@ -546,35 +550,81 @@ abstract class BasePlugin {
prepareDependenciesTask.plugin = this
prepareDependenciesTask.variant = variant
- // look at all the flavors/build types of the variant and get all the libraries
- // to make sure they are unarchived before the build runs.
+ // for all libraries required by the configurations of this variant, make this task
+ // depend on all the tasks preparing these libraries.
for (ConfigurationDependencies configDependencies : configDependenciesList) {
- prepareDependenciesTask.dependsOn configDependencies.configuration.buildDependencies
+
for (AndroidDependencyImpl lib : configDependencies.libraries) {
addDependencyToPrepareTask(prepareDependenciesTask, lib)
- prepareDependenciesTask.add(lib.bundle, lib.bundleFolder)
}
}
return prepareDependenciesTask
}
+ def addDependencyToPrepareTask(PrepareDependenciesTask prepareDependenciesTask,
+ AndroidDependencyImpl lib) {
+ def prepareLibTask = prepareTaskMap.get(lib)
+ if (prepareLibTask != null) {
+ prepareDependenciesTask.dependsOn prepareLibTask
+ }
+
+ for (AndroidDependencyImpl childLib : lib.dependencies) {
+ addDependencyToPrepareTask(prepareDependenciesTask, childLib)
+ }
+ }
+
def resolveDependencies(List<ConfigurationDependencies> configs) {
+ Map<ModuleVersionIdentifier, List<AndroidDependency>> modules = [:]
+ Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts = [:]
+ Multimap<AndroidDependency, ConfigurationDependencies> reverseMap = ArrayListMultimap.create()
+
// start with the default config and its test
- resolveDependencyForConfig(defaultConfigData)
- resolveDependencyForConfig(defaultConfigData.testConfigDependencies)
+ resolveDependencyForConfig(defaultConfigData, modules, artifacts, reverseMap)
+ resolveDependencyForConfig(defaultConfigData.testConfigDependencies, modules, artifacts,
+ reverseMap)
// and then loop on all the other configs
for (ConfigurationDependencies config : configs) {
- resolveDependencyForConfig(config)
+ resolveDependencyForConfig(config, modules, artifacts, reverseMap)
if (config.testConfigDependencies != null) {
- resolveDependencyForConfig(config.testConfigDependencies)
+ resolveDependencyForConfig(config.testConfigDependencies, modules, artifacts,
+ reverseMap)
+ }
+ }
+
+ modules.values().each { List list ->
+ if (!list.isEmpty()) {
+ // get the first item only
+ AndroidDependencyImpl androidDependency = (AndroidDependencyImpl) list.get(0)
+
+ String bundleName = GUtil.toCamelCase(androidDependency.name.replaceAll("\\:", " "))
+
+ def prepareLibraryTask = project.tasks.add("prepare${bundleName}Library",
+ PrepareLibraryTask)
+ prepareLibraryTask.description = "Prepare ${androidDependency.name}"
+ prepareLibraryTask.bundle = androidDependency.bundle
+ prepareLibraryTask.explodedDir = androidDependency.bundleFolder
+
+ // Use the reverse map to find all the configurations that included this android
+ // library so that we can make sure they are built.
+ List<ConfigurationDependencies> configDepList = reverseMap.get(androidDependency)
+ if (configDepList != null && !configDepList.isEmpty()) {
+ for (ConfigurationDependencies configDependencies: configDepList) {
+ prepareLibraryTask.dependsOn configDependencies.configuration.buildDependencies
+ }
+ }
+
+ prepareTaskMap.put(androidDependency, prepareLibraryTask)
}
}
}
def resolveDependencyForConfig(
- ConfigurationDependencies configDependencies) {
+ ConfigurationDependencies configDependencies,
+ Map<ModuleVersionIdentifier, List<AndroidDependency>> modules,
+ Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts,
+ Multimap<AndroidDependency, ConfigurationDependencies> reverseMap) {
def compileClasspath = configDependencies.configuration
@@ -586,11 +636,10 @@ abstract class BasePlugin {
// TODO - defer downloading until required -- This is hard to do as we need the info to build the variant config.
List<AndroidDependency> bundles = []
List<JarDependency> jars = []
- Map<ModuleVersionIdentifier, List<AndroidDependency>> modules = [:]
- Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts = [:]
collectArtifacts(compileClasspath, artifacts)
compileClasspath.resolvedConfiguration.resolutionResult.root.dependencies.each { ResolvedDependencyResult dep ->
- addDependency(dep.selected, checker, bundles, jars, modules, artifacts)
+ addDependency(dep.selected, checker, configDependencies, bundles, jars, modules,
+ artifacts, reverseMap)
}
configDependencies.libraries = bundles
@@ -601,15 +650,6 @@ abstract class BasePlugin {
configureBuild(configDependencies)
}
- def addDependencyToPrepareTask(PrepareDependenciesTask prepareDependenciesTask,
- AndroidDependencyImpl lib) {
- prepareDependenciesTask.add(lib.bundle, lib.bundleFolder)
-
- for (AndroidDependencyImpl childLib : lib.dependencies) {
- addDependencyToPrepareTask(prepareDependenciesTask, childLib)
- }
- }
-
def ensureConfigured(Configuration config) {
config.allDependencies.withType(ProjectDependency).each { dep ->
project.evaluationDependsOn(dep.dependencyProject.path)
@@ -632,10 +672,12 @@ abstract class BasePlugin {
def addDependency(ResolvedModuleVersionResult moduleVersion,
DependencyChecker checker,
+ ConfigurationDependencies configDependencies,
Collection<AndroidDependency> bundles,
Collection<JarDependency> jars,
Map<ModuleVersionIdentifier, List<AndroidDependency>> modules,
- Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts) {
+ Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts,
+ Multimap<AndroidDependency, ConfigurationDependencies> reverseMap) {
def id = moduleVersion.id
if (checker.excluded(id)) {
return
@@ -648,8 +690,8 @@ abstract class BasePlugin {
def nestedBundles = []
moduleVersion.dependencies.each { ResolvedDependencyResult dep ->
- addDependency(dep.selected, checker, nestedBundles,
- jars, modules, artifacts)
+ addDependency(dep.selected, checker, configDependencies, nestedBundles,
+ jars, modules, artifacts, reverseMap)
}
def moduleArtifacts = artifacts[id]
@@ -657,9 +699,11 @@ abstract class BasePlugin {
if (artifact.type == 'alb') {
def explodedDir = project.file(
"$project.buildDir/exploded-bundles/$artifact.file.name")
- bundlesForThisModule << new AndroidDependencyImpl(
+ AndroidDependencyImpl adep = new AndroidDependencyImpl(
id.group + ":" + id.name + ":" + id.version,
explodedDir, nestedBundles, artifact.file)
+ bundlesForThisModule << adep
+ reverseMap.put(adep, configDependencies)
} else {
// TODO - need the correct values for the boolean flags
jars << new JarDependency(artifact.file.absolutePath, true, true, true)
@@ -669,6 +713,10 @@ abstract class BasePlugin {
if (bundlesForThisModule.empty && !nestedBundles.empty) {
throw new GradleException("Module version $id depends on libraries but is not a library itself")
}
+ } else {
+ for (AndroidDependency adep : bundlesForThisModule) {
+ reverseMap.put(adep, configDependencies)
+ }
}
bundles.addAll(bundlesForThisModule)
@@ -679,10 +727,10 @@ abstract class BasePlugin {
addDependsOnTaskInOtherProjects(
project.getTasks().getByName(JavaBasePlugin.BUILD_NEEDED_TASK_NAME), true,
- JavaBasePlugin.BUILD_NEEDED_TASK_NAME, configuration);
+ JavaBasePlugin.BUILD_NEEDED_TASK_NAME, "compile");
addDependsOnTaskInOtherProjects(
project.getTasks().getByName(JavaBasePlugin.BUILD_DEPENDENTS_TASK_NAME), false,
- JavaBasePlugin.BUILD_DEPENDENTS_TASK_NAME, configuration);
+ JavaBasePlugin.BUILD_DEPENDENTS_TASK_NAME, "compile");
}
/**
@@ -699,8 +747,10 @@ abstract class BasePlugin {
*/
private void addDependsOnTaskInOtherProjects(final Task task, boolean useDependedOn,
String otherProjectTaskName,
- Configuration configuration) {
+ String configurationName) {
Project project = task.getProject();
+ final Configuration configuration = project.getConfigurations().getByName(
+ configurationName);
task.dependsOn(configuration.getTaskDependencyFromProjectDependency(
useDependedOn, otherProjectTaskName));
}
diff --git a/gradle/src/main/groovy/com/android/build/gradle/PrepareDependenciesTask.groovy b/gradle/src/main/groovy/com/android/build/gradle/PrepareDependenciesTask.groovy
index 121434a..9180c55 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/PrepareDependenciesTask.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/PrepareDependenciesTask.groovy
@@ -16,41 +16,17 @@
package com.android.build.gradle
import com.android.utils.Pair
-import org.gradle.api.tasks.InputFiles
-import org.gradle.api.tasks.OutputDirectories
import org.gradle.api.tasks.TaskAction
class PrepareDependenciesTask extends BaseTask {
- final Map<File, File> bundles = [:]
final Set<Pair<Integer, String>> androidDependencies = []
- void add(File bundle, File explodedDir) {
- bundles[bundle] = explodedDir
- }
-
void addDependency(Pair<Integer, String> api) {
androidDependencies.add(api)
}
- @InputFiles
- Iterable<File> getBundles() {
- return bundles.keySet()
- }
-
- @OutputDirectories
- Iterable<File> getExplodedBundles() {
- return bundles.values()
- }
-
@TaskAction
def prepare() {
- bundles.each { bundle, explodedDir ->
- project.copy {
- from project.zipTree(bundle)
- into explodedDir
- }
- }
-
// TODO check against variant's minSdkVersion
if (!androidDependencies.isEmpty()) {
def builder = getBuilder();
diff --git a/gradle/src/main/groovy/com/android/build/gradle/PrepareLibraryTask.groovy b/gradle/src/main/groovy/com/android/build/gradle/PrepareLibraryTask.groovy
new file mode 100644
index 0000000..276646e
--- /dev/null
+++ b/gradle/src/main/groovy/com/android/build/gradle/PrepareLibraryTask.groovy
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+package com.android.build.gradle
+
+import org.gradle.api.DefaultTask
+import org.gradle.api.tasks.InputFile
+import org.gradle.api.tasks.OutputDirectory
+import org.gradle.api.tasks.TaskAction
+
+class PrepareLibraryTask extends DefaultTask {
+ @InputFile
+ File bundle
+
+ @OutputDirectory
+ File explodedDir
+
+ @TaskAction
+ def prepare() {
+ project.copy {
+ from project.zipTree(bundle)
+ into explodedDir
+ }
+ }
+}