5f256a203381e3cd022a9896a605f6d4a8d520ad
[android/platform/tools/build.git] / gradle / src / main / groovy / com / android / build / gradle / LibraryPlugin.groovy
1 /*
2  * Copyright (C) 2012 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  */
16 package com.android.build.gradle
17
18 import com.android.build.gradle.internal.BuildTypeData
19 import com.android.build.gradle.internal.ProductFlavorData
20 import com.android.build.gradle.internal.ProductionAppVariant
21 import com.android.build.gradle.internal.TestAppVariant
22 import com.android.builder.AndroidDependency
23 import com.android.builder.BuildType
24 import com.android.builder.BundleDependency
25 import com.android.builder.VariantConfiguration
26 import org.gradle.api.Plugin
27 import org.gradle.api.Project
28 import org.gradle.api.internal.project.ProjectInternal
29 import org.gradle.api.plugins.MavenPlugin
30 import org.gradle.api.tasks.Copy
31 import org.gradle.api.tasks.bundling.Jar
32 import org.gradle.api.tasks.bundling.Zip
33
34 class LibraryPlugin extends BasePlugin implements Plugin<Project> {
35
36     private final static String DIR_BUNDLES = "bundles";
37
38     LibraryExtension extension
39     BuildTypeData debugBuildTypeData
40     BuildTypeData releaseBuildTypeData
41
42     @Override
43     void apply(Project project) {
44         super.apply(project)
45
46         extension = project.extensions.create('android', LibraryExtension,
47                 (ProjectInternal) project)
48         setDefaultConfig(extension.defaultConfig, extension.sourceSetsContainer)
49
50         // create the source sets for the build type.
51         // the ones for the main product flavors are handled by the base plugin.
52         def debugSourceSet = extension.sourceSetsContainer.create(BuildType.DEBUG)
53         def releaseSourceSet = extension.sourceSetsContainer.create(BuildType.RELEASE)
54
55         debugBuildTypeData = new BuildTypeData(extension.debug, debugSourceSet, project)
56         releaseBuildTypeData = new BuildTypeData(extension.release, releaseSourceSet, project)
57         project.tasks.assemble.dependsOn debugBuildTypeData.assembleTask
58         project.tasks.assemble.dependsOn releaseBuildTypeData.assembleTask
59
60         createConfigurations()
61
62         project.afterEvaluate {
63             createAndroidTasks()
64         }
65     }
66
67     void createConfigurations() {
68         def debugConfig = project.configurations.add(BuildType.DEBUG)
69         def releaseConfig = project.configurations.add(BuildType.RELEASE)
70         debugConfig.extendsFrom(project.configurations["package"])
71         releaseConfig.extendsFrom(project.configurations["package"])
72         project.configurations["default"].extendsFrom(releaseConfig)
73
74         // Adjust the pom scope mappings
75         // TODO - this should be part of JavaBase plugin. Fix this in Gradle
76         project.plugins.withType(MavenPlugin) {
77             project.conf2ScopeMappings.addMapping(300, project.configurations.compile, "runtime")
78             project.conf2ScopeMappings.addMapping(300, project.configurations["package"], "runtime")
79             project.conf2ScopeMappings.addMapping(300, releaseConfig, "runtime")
80         }
81     }
82
83     void createAndroidTasks() {
84         ProductionAppVariant testedVariant = createLibraryTasks(debugBuildTypeData)
85         createLibraryTasks(releaseBuildTypeData)
86         createTestTasks(testedVariant)
87     }
88
89     ProductionAppVariant createLibraryTasks(BuildTypeData buildTypeData) {
90         ProductFlavorData defaultConfigData = getDefaultConfigData();
91
92         def variantConfig = new VariantConfiguration(
93                 defaultConfigData.productFlavor, defaultConfigData.sourceSet,
94                 buildTypeData.buildType, buildTypeData.sourceSet,
95                 VariantConfiguration.Type.LIBRARY)
96
97         ProductionAppVariant variant = new ProductionAppVariant(variantConfig)
98
99         def prepareDependenciesTask = createPrepareDependenciesTask(variant)
100
101         // Add a task to process the manifest(s)
102         ProcessManifestTask processManifestTask = createProcessManifestTask(variant, DIR_BUNDLES)
103         // TODO - move this
104         processManifestTask.dependsOn prepareDependenciesTask
105
106         // Add a task to create the BuildConfig class
107         def generateBuildConfigTask = createBuildConfigTask(variant, null)
108
109         // Add a task to generate resource source files
110         def processResources = createProcessResTask(variant, processManifestTask,
111                 null /*crunchTask*/)
112
113         // process java resources
114         createProcessJavaResTask(variant)
115
116         def compileAidl = createAidlTask(variant)
117         // TODO - move this
118         compileAidl.dependsOn prepareDependenciesTask
119
120         // Add a compile task
121         createCompileTask(variant, null/*testedVariant*/, processResources, generateBuildConfigTask,
122                 compileAidl)
123
124         // jar the classes.
125         Jar jar = project.tasks.add("package${buildTypeData.buildType.name.capitalize()}Jar", Jar);
126         jar.dependsOn variant.compileTask, variant.processJavaResources
127         jar.from(variant.compileTask.outputs);
128         jar.from(variant.processJavaResources.destinationDir)
129
130         jar.destinationDir = project.file("$project.buildDir/$DIR_BUNDLES/${variant.dirName}")
131         jar.archiveName = "classes.jar"
132         String packageName = variantConfig.getPackageFromManifest().replace('.', '/');
133         jar.exclude(packageName + "/R.class")
134         jar.exclude(packageName + "/R\$*.class")
135
136         // package the android resources into the bundle folder
137         Copy packageRes = project.tasks.add("package${variant.name}Res", Copy)
138         // packageRes from 3 sources. the order is important to make sure the override works well.
139         // TODO: fix the case of values -- need to merge the XML!
140         packageRes.from(defaultConfigData.sourceSet.resources.directory,
141                 buildTypeData.sourceSet.resources.directory)
142         packageRes.into(project.file("$project.buildDir/$DIR_BUNDLES/${variant.dirName}/res"))
143
144         // package the aidl files into the bundle folder
145         Copy packageAidl = project.tasks.add("package${variant.name}Aidl", Copy)
146         // packageAidl from 3 sources. the order is important to make sure the override works well.
147         packageAidl.from(defaultConfigData.sourceSet.aidl.directory,
148                 buildTypeData.sourceSet.aidl.directory)
149         packageAidl.into(project.file("$project.buildDir/$DIR_BUNDLES/${variant.dirName}/aidl"))
150
151         // package the R symbol test file into the bundle folder
152         Copy packageSymbol = project.tasks.add("package${variant.name}Symbols", Copy)
153         packageSymbol.dependsOn processResources
154         packageSymbol.from(processResources.textSymbolDir)
155         packageSymbol.into(project.file("$project.buildDir/$DIR_BUNDLES/${variant.dirName}"))
156
157         Zip bundle = project.tasks.add("bundle${variant.name}", Zip)
158         bundle.dependsOn jar, packageRes, packageAidl, packageSymbol
159         bundle.setDescription("Assembles a bundle containing the library in ${variant.name}.");
160         bundle.destinationDir = project.file("$project.buildDir/libs")
161         bundle.extension = "alb"
162         if (variant.baseName != BuildType.RELEASE) {
163             bundle.classifier = variant.baseName
164         }
165         bundle.from(project.file("$project.buildDir/$DIR_BUNDLES/${variant.dirName}"))
166
167         project.artifacts.add(buildTypeData.buildType.name, bundle)
168
169         buildTypeData.assembleTask.dependsOn bundle
170         variant.assembleTask = bundle
171
172         // configure the variant to be testable.
173         variantConfig.output = new BundleDependency(
174                 project.file("$project.buildDir/$DIR_BUNDLES/${variant.dirName}")) {
175
176             @Override
177             List<AndroidDependency> getDependencies() {
178                 return variantConfig.directLibraries
179             }
180         };
181
182         return variant
183     }
184
185     void createTestTasks(ProductionAppVariant testedVariant) {
186         ProductFlavorData defaultConfigData = getDefaultConfigData();
187
188         def testVariantConfig = new VariantConfiguration(
189                 defaultConfigData.productFlavor, defaultConfigData.testSourceSet,
190                 debugBuildTypeData.buildType, null,
191                 VariantConfiguration.Type.TEST, testedVariant.config)
192         // TODO: add actual dependencies
193         testVariantConfig.setAndroidDependencies(null)
194
195         def testVariant = new TestAppVariant(testVariantConfig,)
196         createTestTasks(testVariant, testedVariant)
197     }
198
199     @Override
200     String getTarget() {
201         return extension.target
202     }
203
204     protected String getManifestOutDir() {
205         return DIR_BUNDLES
206     }
207 }