com.android.build.gradle.internal.LibraryTaskManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-core Show documentation
Show all versions of gradle-core Show documentation
Core library to build Android Gradle plugin.
/*
* Copyright (C) 2015 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.internal;
import static com.android.SdkConstants.FD_JNI;
import static com.android.SdkConstants.FD_RENDERSCRIPT;
import static com.android.SdkConstants.FN_ANNOTATIONS_ZIP;
import static com.android.SdkConstants.FN_CLASSES_JAR;
import static com.android.SdkConstants.LIBS_FOLDER;
import static com.android.builder.dependency.LibraryBundle.FN_PROGUARD_TXT;
import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.build.gradle.AndroidConfig;
import com.android.build.gradle.internal.core.GradleVariantConfiguration;
import com.android.build.gradle.internal.dsl.CoreBuildType;
import com.android.build.gradle.internal.pipeline.TransformManager;
import com.android.build.gradle.internal.pipeline.TransformTask;
import com.android.build.gradle.internal.scope.AndroidTask;
import com.android.build.gradle.internal.scope.ConventionMappingHelper;
import com.android.build.gradle.internal.scope.GlobalScope;
import com.android.build.gradle.internal.scope.VariantScope;
import com.android.build.gradle.internal.tasks.LibraryJarTransform;
import com.android.build.gradle.internal.tasks.LibraryJniLibsTransform;
import com.android.build.gradle.internal.tasks.MergeFileTask;
import com.android.build.gradle.internal.variant.BaseVariantData;
import com.android.build.gradle.internal.variant.BaseVariantOutputData;
import com.android.build.gradle.internal.variant.LibVariantOutputData;
import com.android.build.gradle.internal.variant.LibraryVariantData;
import com.android.build.gradle.internal.variant.VariantHelper;
import com.android.build.gradle.tasks.ExtractAnnotations;
import com.android.build.gradle.tasks.MergeResources;
import com.android.build.api.transform.QualifiedContent.Scope;
import com.android.build.api.transform.Transform;
import com.android.builder.core.AndroidBuilder;
import com.android.builder.core.BuilderConstants;
import com.android.builder.dependency.LibraryBundle;
import com.android.builder.dependency.LibraryDependency;
import com.android.builder.dependency.ManifestDependency;
import com.android.builder.model.AndroidLibrary;
import com.android.builder.model.MavenCoordinates;
import com.android.builder.model.SyncIssue;
import com.android.builder.profile.ExecutionType;
import com.android.builder.profile.Recorder;
import com.android.builder.profile.ThreadRecorder;
import com.android.utils.FileUtils;
import com.android.utils.StringHelper;
import com.google.common.collect.Sets;
import org.gradle.api.Action;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.plugins.BasePlugin;
import org.gradle.api.tasks.Copy;
import org.gradle.api.tasks.Sync;
import org.gradle.api.tasks.bundling.Zip;
import org.gradle.api.tasks.compile.JavaCompile;
import org.gradle.tooling.BuildException;
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry;
import android.databinding.tool.DataBindingBuilder;
import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
/**
* TaskManager for creating tasks in an Android library project.
*/
public class LibraryTaskManager extends TaskManager {
private static final String ANNOTATIONS = "annotations";
private Task assembleDefault;
public LibraryTaskManager (
Project project,
AndroidBuilder androidBuilder,
DataBindingBuilder dataBindingBuilder,
AndroidConfig extension,
SdkHandler sdkHandler,
DependencyManager dependencyManager,
ToolingModelBuilderRegistry toolingRegistry) {
super(project, androidBuilder, dataBindingBuilder, extension, sdkHandler,dependencyManager, toolingRegistry);
}
@Override
public void createTasksForVariantData(
@NonNull final TaskFactory tasks,
@NonNull final BaseVariantData extends BaseVariantOutputData> variantData) {
final LibraryVariantData libVariantData = (LibraryVariantData) variantData;
final GradleVariantConfiguration variantConfig = variantData.getVariantConfiguration();
final CoreBuildType buildType = variantConfig.getBuildType();
final VariantScope variantScope = variantData.getScope();
GlobalScope globalScope = variantScope.getGlobalScope();
final File intermediatesDir = globalScope.getIntermediatesDir();
final Collection variantDirectorySegments = variantConfig.getDirectorySegments();
final File variantBundleDir = FileUtils.join(
intermediatesDir,
StringHelper.toStrings(DIR_BUNDLES, variantDirectorySegments));
createAnchorTasks(tasks, variantScope);
// Create all current streams (dependencies mostly at this point)
createDependencyStreams(variantScope);
createCheckManifestTask(tasks, variantScope);
// Add a task to create the res values
ThreadRecorder.get().record(ExecutionType.LIB_TASK_MANAGER_CREATE_GENERATE_RES_VALUES_TASK,
new Recorder.Block() {
@Override
public Void call() throws Exception {
createGenerateResValuesTask(tasks, variantScope);
return null;
}
});
// Add a task to process the manifest(s)
ThreadRecorder.get().record(ExecutionType.LIB_TASK_MANAGER_CREATE_MERGE_MANIFEST_TASK,
new Recorder.Block() {
@Override
public Void call() throws Exception {
createMergeLibManifestsTask(tasks, variantScope);
return null;
}
});
// Add a task to compile renderscript files.
ThreadRecorder.get().record(ExecutionType.LIB_TASK_MANAGER_CREATE_CREATE_RENDERSCRIPT_TASK,
new Recorder.Block() {
@Override
public Void call() throws Exception {
createRenderscriptTask(tasks, variantScope);
return null;
}
});
AndroidTask packageRes = ThreadRecorder.get().record(
ExecutionType.LIB_TASK_MANAGER_CREATE_MERGE_RESOURCES_TASK,
new Recorder.Block>() {
@Override
public AndroidTask call() throws Exception {
// Create a merge task to only merge the resources from this library and not
// the dependencies. This is what gets packaged in the aar.
AndroidTask mergeResourceTask =
basicCreateMergeResourcesTask(
tasks,
variantScope,
"package",
FileUtils.join(variantBundleDir, "res"),
false /*includeDependencies*/,
false /*process9Patch*/);
if (variantData.getVariantDependency().hasNonOptionalLibraries()) {
// Add a task to merge the resource folders, including the libraries, in order to
// generate the R.txt file with all the symbols, including the ones from
// the dependencies.
createMergeResourcesTask(tasks, variantScope);
}
mergeResourceTask.configure(tasks,
new Action() {
@Override
public void execute(Task task) {
MergeResources mergeResourcesTask = (MergeResources) task;
mergeResourcesTask.setPublicFile(FileUtils.join(
variantBundleDir,
SdkConstants.FN_PUBLIC_TXT
));
}
});
return mergeResourceTask;
}
});
// Add a task to merge the assets folders
ThreadRecorder.get().record(ExecutionType.LIB_TASK_MANAGER_CREATE_MERGE_ASSETS_TASK,
new Recorder.Block() {
@Override
public Void call() {
createMergeAssetsTask(tasks, variantScope);
return null;
}
});
// Add a task to create the BuildConfig class
ThreadRecorder.get().record(ExecutionType.LIB_TASK_MANAGER_CREATE_BUILD_CONFIG_TASK,
new Recorder.Block() {
@Override
public Void call() throws Exception {
createBuildConfigTask(tasks, variantScope);
return null;
}
});
ThreadRecorder.get().record(ExecutionType.LIB_TASK_MANAGER_CREATE_PROCESS_RES_TASK,
new Recorder.Block() {
@Override
public Void call() throws Exception {
// Add a task to generate resource source files, directing the location
// of the r.txt file to be directly in the bundle.
createProcessResTask(tasks, variantScope, variantBundleDir,
false /*generateResourcePackage*/);
// process java resources
createProcessJavaResTasks(tasks, variantScope);
return null;
}
});
ThreadRecorder.get().record(ExecutionType.LIB_TASK_MANAGER_CREATE_AIDL_TASK,
new Recorder.Block() {
@Override
public Void call() throws Exception {
createAidlTask(tasks, variantScope);
return null;
}
});
// Add a compile task
ThreadRecorder.get().record(ExecutionType.LIB_TASK_MANAGER_CREATE_COMPILE_TASK,
new Recorder.Block() {
@Override
public Void call() throws Exception {
AndroidTask javacTask = createJavacTask(tasks, variantScope);
TaskManager.setJavaCompilerTask(javacTask, tasks, variantScope);
return null;
}
});
// Add data binding tasks if enabled
if (extension.getDataBinding().isEnabled()) {
createDataBindingTasks(tasks, variantScope);
}
// Add dependencies on NDK tasks if NDK plugin is applied.
if (isNdkTaskNeeded) {
// Add NDK tasks
ThreadRecorder.get().record(ExecutionType.LIB_TASK_MANAGER_CREATE_NDK_TASK,
new Recorder.Block() {
@Override
public Void call() throws Exception {
createNdkTasks(variantScope);
return null;
}
});
}
variantScope.setNdkBuildable(getNdkBuildable(variantData));
// merge jni libs.
createMergeJniLibFoldersTasks(tasks, variantScope);
Sync packageRenderscript = ThreadRecorder.get().record(
ExecutionType.LIB_TASK_MANAGER_CREATE_PACKAGING_TASK,
new Recorder.Block() {
@Override
public Sync call() throws Exception {
// package the renderscript header files files into the bundle folder
Sync packageRenderscript = project.getTasks().create(
variantScope.getTaskName("package", "Renderscript"), Sync.class);
// package from 3 sources. the order is important to make sure the override works well.
packageRenderscript.from(variantConfig.getRenderscriptSourceList())
.include("**/*.rsh");
packageRenderscript.into(new File(variantBundleDir, FD_RENDERSCRIPT));
return packageRenderscript;
}
});
// merge consumer proguard files from different build types and flavors
MergeFileTask mergeProGuardFileTask = ThreadRecorder.get().record(
ExecutionType.LIB_TASK_MANAGER_CREATE_MERGE_PROGUARD_FILE_TASK,
new Recorder.Block() {
@Override
public MergeFileTask call() throws Exception {
MergeFileTask mergeProGuardFileTask = project.getTasks().create(
variantScope.getTaskName("merge", "ProguardFiles"),
MergeFileTask.class);
mergeProGuardFileTask.setVariantName(variantConfig.getFullName());
mergeProGuardFileTask.setInputFiles(
project.files(variantConfig.getConsumerProguardFiles())
.getFiles());
mergeProGuardFileTask.setOutputFile(
new File(variantBundleDir, FN_PROGUARD_TXT));
return mergeProGuardFileTask;
}
});
// copy lint.jar into the bundle folder
Copy lintCopy = project.getTasks().create(
variantScope.getTaskName("copy", "Lint"), Copy.class);
lintCopy.dependsOn(LINT_COMPILE);
lintCopy.from(new File(
globalScope.getIntermediatesDir(),
"lint/lint.jar"));
lintCopy.into(variantBundleDir);
final Zip bundle = project.getTasks().create(variantScope.getTaskName("bundle"), Zip.class);
if (variantData.getVariantDependency().isAnnotationsPresent()) {
libVariantData.generateAnnotationsTask =
createExtractAnnotations(project, variantData);
}
if (libVariantData.generateAnnotationsTask != null) {
bundle.dependsOn(libVariantData.generateAnnotationsTask);
}
final boolean instrumented = variantConfig.getBuildType().isTestCoverageEnabled();
ThreadRecorder.get().record(
ExecutionType.LIB_TASK_MANAGER_CREATE_POST_COMPILATION_TASK,
new Recorder.Block() {
@Override
public Void call() throws Exception {
TransformManager transformManager = variantScope.getTransformManager();
// ----- Code Coverage first -----
if (instrumented) {
createJacocoTransform(tasks, variantScope);
}
// ----- External Transforms -----
// apply all the external transforms.
List customTransforms = extension.getTransforms();
List> customTransformsDependencies = extension.getTransformsDependencies();
for (int i = 0, count = customTransforms.size() ; i < count ; i++) {
Transform transform = customTransforms.get(i);
// Check the transform only applies to supported scopes for libraries:
// We cannot transform scopes that are not packaged in the library
// itself.
Sets.SetView difference = Sets.difference(transform.getScopes(),
TransformManager.SCOPE_FULL_LIBRARY);
if (!difference.isEmpty()) {
String scopes = difference.toString();
androidBuilder.getErrorReporter().handleSyncError(
"",
SyncIssue.TYPE_GENERIC,
String.format("Transforms with scopes '%s' cannot be applied to library projects.",
scopes));
}
AndroidTask task = transformManager
.addTransform(tasks, variantScope, transform);
List