| /* |
| * 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.FN_ANNOTATIONS_ZIP; |
| import static com.android.SdkConstants.LIBS_FOLDER; |
| import static com.google.common.base.Preconditions.checkNotNull; |
| import static com.google.common.base.Preconditions.checkState; |
| |
| 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.scope.AndroidTask; |
| import com.android.build.gradle.internal.scope.ConventionMappingHelper; |
| import com.android.build.gradle.internal.scope.VariantScope; |
| 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.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.profile.ExecutionType; |
| import com.android.builder.profile.Recorder; |
| import com.android.builder.profile.ThreadRecorder; |
| |
| 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.Jar; |
| 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 java.io.File; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| 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, |
| AndroidConfig extension, |
| SdkHandler sdkHandler, |
| DependencyManager dependencyManager, |
| ToolingModelBuilderRegistry toolingRegistry) { |
| super(project, androidBuilder, 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(); |
| CoreBuildType buildType = variantConfig.getBuildType(); |
| |
| final VariantScope variantScope = variantData.getScope(); |
| |
| final String dirName = variantConfig.getDirName(); |
| |
| createAnchorTasks(tasks, 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<Void>() { |
| @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<Void>() { |
| @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<Void>() { |
| @Override |
| public Void call() throws Exception { |
| createRenderscriptTask(tasks, variantScope); |
| return null; |
| } |
| }); |
| |
| AndroidTask<MergeResources> packageRes = ThreadRecorder.get().record( |
| ExecutionType.LIB_TASK_MANAGER_CREATE_MERGE_RESOURCES_TASK, |
| new Recorder.Block<AndroidTask<MergeResources>>() { |
| @Override |
| public AndroidTask<MergeResources> 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<MergeResources> mergeResourceTask = |
| basicCreateMergeResourcesTask( |
| tasks, |
| variantScope, |
| "package", |
| new File( |
| variantScope.getGlobalScope().getIntermediatesDir(), |
| DIR_BUNDLES + "/" + variantScope |
| .getVariantConfiguration().getDirName() + |
| "/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<Task>() { |
| @Override |
| public void execute(Task task) { |
| MergeResources mergeResourcesTask = (MergeResources) task; |
| mergeResourcesTask.setPublicFile(new File( |
| variantScope.getGlobalScope().getIntermediatesDir(), |
| DIR_BUNDLES + "/" + dirName + "/" + |
| 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<Void>() { |
| @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<Void>() { |
| @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<Void>() { |
| @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, |
| new File(variantScope.getGlobalScope().getIntermediatesDir(), |
| DIR_BUNDLES + "/" + dirName), |
| false /*generateResourcePackage*/); |
| |
| // process java resources |
| createProcessJavaResTasks(tasks, variantScope); |
| return null; |
| } |
| }); |
| |
| ThreadRecorder.get().record(ExecutionType.LIB_TASK_MANAGER_CREATE_AIDL_TASK, |
| new Recorder.Block<Void>() { |
| @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<Void>() { |
| @Override |
| public Void call() throws Exception { |
| AndroidTask<JavaCompile> javacTask = createJavacTask(tasks, variantScope); |
| TaskManager.setJavaCompilerTask(javacTask, tasks, variantScope); |
| return null; |
| } |
| }); |
| |
| // package the prebuilt native libs into the bundle folder |
| final Sync packageJniLibs = project.getTasks().create( |
| variantScope.getTaskName("package", "JniLibs"), |
| Sync.class); |
| |
| // 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<Void>() { |
| @Override |
| public Void call() throws Exception { |
| createNdkTasks(variantScope); |
| packageJniLibs.dependsOn(variantData.ndkCompileTask); |
| packageJniLibs.from(variantData.ndkCompileTask.getSoFolder()) |
| .include("**/*.so"); |
| return null; |
| } |
| }); |
| } else { |
| if (variantData.compileTask != null) { |
| variantData.compileTask.dependsOn(getNdkBuildable(variantData)); |
| } else { |
| variantScope.getCompileTask().dependsOn(tasks, getNdkBuildable(variantData)); |
| } |
| } |
| |
| Sync packageRenderscript = ThreadRecorder.get().record( |
| ExecutionType.LIB_TASK_MANAGER_CREATE_PACKAGING_TASK, |
| new Recorder.Block<Sync>() { |
| @Override |
| public Sync call() throws Exception { |
| // package from 2 sources. |
| packageJniLibs.from(variantConfig.getJniLibsList()) |
| .include("**/*.so"); |
| packageJniLibs.into(new File( |
| variantScope.getGlobalScope().getIntermediatesDir(), |
| DIR_BUNDLES + "/" + dirName + "/jni")); |
| |
| // 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( |
| variantScope.getGlobalScope().getIntermediatesDir(), |
| DIR_BUNDLES + "/" + dirName + "/" + SdkConstants.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<MergeFileTask>() { |
| @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( |
| variantScope.getGlobalScope().getIntermediatesDir(), |
| DIR_BUNDLES + "/" + dirName + "/" + LibraryBundle.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( |
| variantScope.getGlobalScope().getIntermediatesDir(), |
| "lint/lint.jar")); |
| lintCopy.into(new File( |
| variantScope.getGlobalScope().getIntermediatesDir(), |
| DIR_BUNDLES + "/" + dirName)); |
| |
| 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(); |
| |
| // data holding dependencies and input for the dex. This gets updated as new |
| // post-compilation steps are inserted between the compilation and dx. |
| final PostCompilationData pcDataTemp = new PostCompilationData(); |
| |
| final PostCompilationData pcData = ThreadRecorder.get().record( |
| ExecutionType.LIB_TASK_MANAGER_CREATE_POST_COMPILATION_TASK, |
| new Recorder.Block<PostCompilationData>() { |
| @Override |
| public PostCompilationData call() throws Exception { |
| pcDataTemp.setClassGeneratingTasks(Collections.singletonList( |
| variantScope.getJavacTask().getName())); |
| pcDataTemp.setLibraryGeneratingTasks(Collections.singletonList( |
| variantData.getVariantDependency().getPackageConfiguration() |
| .getBuildDependencies())); |
| pcDataTemp.setInputFilesCallable(new Callable<List<File>>() { |
| @Override |
| public List<File> call() throws Exception { |
| return new ArrayList<File>( |
| variantData.javacTask.getOutputs().getFiles().getFiles()); |
| } |
| |
| }); |
| pcDataTemp.setInputDir(variantScope.getJavaOutputDir()); |
| pcDataTemp.setInputLibraries(Collections.<File>emptyList()); |
| |
| // if needed, instrument the code |
| if (instrumented) { |
| return createJacocoTask(tasks, variantScope, pcDataTemp); |
| } |
| return pcDataTemp; |
| } |
| }); |
| checkState(pcData != null); |
| |
| if (buildType.isMinifyEnabled()) { |
| // run proguard on output of compile task |
| ThreadRecorder.get().record( |
| ExecutionType.LIB_TASK_MANAGER_CREATE_PROGUARD_TASK, |
| new Recorder.Block<Void>() { |
| @Override |
| public Void call() throws Exception { |
| File outFile = maybeCreateProguardTasks(tasks, variantScope, |
| pcData); |
| checkNotNull(outFile); |
| pcData.setInputFiles(Collections.singletonList(outFile)); |
| pcData.setInputDirCallable(null); |
| pcData.setInputLibraries(Collections.<File>emptyList()); |
| return null; |
| } |
| }); |
| } else { |
| // package the local jar in libs/ |
| ThreadRecorder.get().record( |
| ExecutionType.LIB_TASK_MANAGER_CREATE_PACKAGE_LOCAL_JAR, |
| new Recorder.Block<Void>() { |
| @Override |
| public Void call() throws Exception { |
| Sync packageLocalJar = project.getTasks().create( |
| variantScope.getTaskName("package", "LocalJar"), Sync.class); |
| packageLocalJar.from( |
| DependencyManager |
| .getPackagedLocalJarFileList( |
| variantData.getVariantDependency()) |
| .toArray()); |
| packageLocalJar.into(new File( |
| variantScope.getGlobalScope().getIntermediatesDir(), |
| DIR_BUNDLES + "/" + dirName + "/" + LIBS_FOLDER)); |
| |
| // add the input libraries. This is only going to be the agent jar if applicable |
| // due to how inputLibraries is initialized. |
| // TODO: clean this. |
| packageLocalJar.from(pcData.getInputLibrariesCallable()); |
| TaskManager.optionalDependsOn( |
| packageLocalJar, |
| pcData.getLibraryGeneratingTasks()); |
| pcData.setLibraryGeneratingTasks( |
| Collections.singletonList(packageLocalJar)); |
| |
| // jar the classes. |
| Jar jar = project.getTasks().create( |
| variantScope.getTaskName("package", "Jar"), Jar.class); |
| jar.dependsOn(variantScope.getMergeJavaResourcesTask().getName()); |
| |
| // add the class files (whether they are instrumented or not. |
| jar.from(pcData.getInputDirCallable()); |
| TaskManager.optionalDependsOn(jar, pcData.getClassGeneratingTasks()); |
| pcData.setClassGeneratingTasks(Collections.singletonList(jar)); |
| |
| jar.from(variantScope.getJavaResourcesDestinationDir()); |
| |
| jar.setDestinationDir(new File( |
| variantScope.getGlobalScope().getIntermediatesDir(), |
| DIR_BUNDLES + "/" + dirName)); |
| jar.setArchiveName("classes.jar"); |
| |
| String packageName = variantConfig.getPackageFromManifest(); |
| if (packageName == null) { |
| throw new BuildException("Failed to read manifest", null); |
| } |
| |
| packageName = packageName.replace(".", "/"); |
| |
| jar.exclude(packageName + "/R.class"); |
| jar.exclude(packageName + "/R$*.class"); |
| if (!getExtension().getPackageBuildConfig()) { |
| jar.exclude(packageName + "/Manifest.class"); |
| jar.exclude(packageName + "/Manifest$*.class"); |
| jar.exclude(packageName + "/BuildConfig.class"); |
| } |
| |
| if (libVariantData.generateAnnotationsTask != null) { |
| // In case extract annotations strips out private typedef annotation classes |
| jar.dependsOn(libVariantData.generateAnnotationsTask); |
| } |
| return null; |
| } |
| }); |
| } |
| |
| bundle.dependsOn(packageRes.getName(), packageRenderscript, lintCopy, packageJniLibs, |
| mergeProGuardFileTask); |
| TaskManager.optionalDependsOn(bundle, pcData.getClassGeneratingTasks()); |
| TaskManager.optionalDependsOn(bundle, pcData.getLibraryGeneratingTasks()); |
| |
| bundle.setDescription("Assembles a bundle containing the library in " + |
| variantConfig.getFullName() + "."); |
| bundle.setDestinationDir(new File(variantScope.getGlobalScope().getOutputsDir(), "aar")); |
| bundle.setArchiveName(project.getName() + "-" + variantConfig.getBaseName() + "." |
| + BuilderConstants.EXT_LIB_ARCHIVE); |
| bundle.setExtension(BuilderConstants.EXT_LIB_ARCHIVE); |
| bundle.from(new File( |
| variantScope.getGlobalScope().getIntermediatesDir(), |
| DIR_BUNDLES + "/" + dirName)); |
| bundle.from(new File( |
| variantScope.getGlobalScope().getIntermediatesDir(), |
| ANNOTATIONS + "/" + dirName)); |
| |
| // get the single output for now, though that may always be the case for a library. |
| LibVariantOutputData variantOutputData = libVariantData.getOutputs().get(0); |
| variantOutputData.packageLibTask = bundle; |
| |
| variantData.assembleVariantTask.dependsOn(bundle); |
| variantOutputData.assembleTask = variantData.assembleVariantTask; |
| |
| if (getExtension().getDefaultPublishConfig().equals(variantConfig.getFullName())) { |
| VariantHelper.setupDefaultConfig(project, |
| variantData.getVariantDependency().getPackageConfiguration()); |
| |
| // add the artifact that will be published |
| project.getArtifacts().add("default", bundle); |
| |
| getAssembleDefault().dependsOn(variantData.assembleVariantTask); |
| } |
| |
| // also publish the artifact with its full config name |
| if (getExtension().getPublishNonDefault()) { |
| project.getArtifacts().add( |
| variantData.getVariantDependency().getPublishConfiguration().getName(), bundle); |
| bundle.setClassifier( |
| variantData.getVariantDependency().getPublishConfiguration().getName()); |
| } |
| |
| // configure the variant to be testable. |
| variantConfig.setOutput(new LibraryBundle( |
| bundle.getArchivePath(), |
| new File(variantScope.getGlobalScope().getIntermediatesDir(), |
| DIR_BUNDLES + "/" + dirName), |
| variantData.getName(), |
| project.getPath()) { |
| @Override |
| @Nullable |
| public String getProjectVariant() { |
| return variantData.getName(); |
| } |
| |
| @NonNull |
| @Override |
| public List<LibraryDependency> getDependencies() { |
| return variantConfig.getDirectLibraries(); |
| } |
| |
| @NonNull |
| @Override |
| public List<? extends AndroidLibrary> getLibraryDependencies() { |
| return variantConfig.getDirectLibraries(); |
| } |
| |
| @NonNull |
| @Override |
| public List<? extends ManifestDependency> getManifestDependencies() { |
| return variantConfig.getDirectLibraries(); |
| } |
| |
| @Override |
| @Nullable |
| public MavenCoordinates getRequestedCoordinates() { |
| return null; |
| } |
| |
| @Override |
| @Nullable |
| public MavenCoordinates getResolvedCoordinates() { |
| return null; |
| } |
| |
| @Override |
| @NonNull |
| protected File getJarsRootFolder() { |
| return getFolder(); |
| } |
| |
| @Override |
| public boolean isOptional() { |
| return false; |
| } |
| |
| }); |
| |
| ThreadRecorder.get().record(ExecutionType.LIB_TASK_MANAGER_CREATE_LINT_TASK, |
| new Recorder.Block<Void>() { |
| @Override |
| public Void call() throws Exception { |
| createLintTasks(tasks, variantScope); |
| return null; |
| } |
| }); |
| } |
| |
| public ExtractAnnotations createExtractAnnotations( |
| final Project project, |
| final BaseVariantData variantData) { |
| final GradleVariantConfiguration config = variantData.getVariantConfiguration(); |
| |
| final ExtractAnnotations task = project.getTasks().create( |
| variantData.getScope().getTaskName("extract", "Annotations"), |
| ExtractAnnotations.class); |
| task.setDescription( |
| "Extracts Android annotations for the " + variantData.getVariantConfiguration() |
| .getFullName() |
| + " variant into the archive file"); |
| task.setGroup(BasePlugin.BUILD_GROUP); |
| task.variant = variantData; |
| task.setDestinationDir(new File( |
| variantData.getScope().getGlobalScope().getIntermediatesDir(), |
| ANNOTATIONS + "/" + config.getDirName())); |
| task.output = new File(task.getDestinationDir(), FN_ANNOTATIONS_ZIP); |
| task.classDir = new File(variantData.getScope().getGlobalScope().getIntermediatesDir(), |
| "classes/" + variantData.getVariantConfiguration().getDirName()); |
| task.setSource(variantData.getJavaSources()); |
| task.encoding = getExtension().getCompileOptions().getEncoding(); |
| task.setSourceCompatibility( |
| getExtension().getCompileOptions().getSourceCompatibility().toString()); |
| ConventionMappingHelper.map(task, "classpath", new Callable<ConfigurableFileCollection>() { |
| @Override |
| public ConfigurableFileCollection call() throws Exception { |
| return project.files(androidBuilder.getCompileClasspath(config)); |
| } |
| }); |
| task.dependsOn(variantData.getScope().getJavacTask().getName()); |
| |
| // Setup the boot classpath just before the task actually runs since this will |
| // force the sdk to be parsed. (Same as in compileTask) |
| task.doFirst(new Action<Task>() { |
| @Override |
| public void execute(Task task) { |
| if (task instanceof ExtractAnnotations) { |
| ExtractAnnotations extractAnnotations = (ExtractAnnotations) task; |
| extractAnnotations.bootClasspath = androidBuilder.getBootClasspathAsStrings(); |
| } |
| } |
| }); |
| |
| return task; |
| } |
| |
| private Task getAssembleDefault() { |
| if (assembleDefault == null) { |
| assembleDefault = project.getTasks().findByName("assembleDefault"); |
| } |
| return assembleDefault; |
| } |
| } |