use of com.google.devtools.build.lib.analysis.actions.SpawnAction.Builder in project bazel by bazelbuild.
the class AndroidBinary method createAndroidBinary.
public static RuleConfiguredTargetBuilder createAndroidBinary(RuleContext ruleContext, NestedSetBuilder<Artifact> filesBuilder, Artifact binaryJar, Function<Artifact, Artifact> derivedJarFunction, boolean isBinaryJarFiltered, JavaCommon javaCommon, AndroidCommon androidCommon, JavaSemantics javaSemantics, AndroidSemantics androidSemantics, NativeLibs nativeLibs, ApplicationManifest applicationManifest, ResourceApk resourceApk, ResourceApk incrementalResourceApk, ResourceApk instantRunResourceApk, ResourceApk splitResourceApk, boolean shrinkResources, JavaTargetAttributes resourceClasses, ImmutableList<Artifact> apksUnderTest, ImmutableList<Artifact> additionalMergedManifests, Artifact proguardMapping) throws InterruptedException, RuleErrorException {
ImmutableList<Artifact> proguardSpecs = ProguardHelper.collectTransitiveProguardSpecs(ruleContext, ImmutableList.of(resourceApk.getResourceProguardConfig()));
boolean rexEnabled = ruleContext.getFragment(AndroidConfiguration.class).useRexToCompressDexFiles() || (ruleContext.attributes().get("rewrite_dexes_with_rex", Type.BOOLEAN));
// TODO(bazel-team): Verify that proguard spec files don't contain -printmapping directions
// which this -printmapping command line flag will override.
Artifact proguardOutputMap = null;
if (ProguardHelper.genProguardMapping(ruleContext.attributes()) || ProguardHelper.getJavaOptimizationMode(ruleContext).alwaysGenerateOutputMapping() || shrinkResources) {
if (rexEnabled) {
proguardOutputMap = ProguardHelper.getProguardTempArtifact(ruleContext, ProguardHelper.getJavaOptimizationMode(ruleContext).name().toLowerCase(), "proguard_output_for_rex.map");
} else {
proguardOutputMap = ruleContext.getImplicitOutputArtifact(JavaSemantics.JAVA_BINARY_PROGUARD_MAP);
}
}
ProguardOutput proguardOutput = applyProguard(ruleContext, androidCommon, javaSemantics, binaryJar, proguardSpecs, proguardMapping, proguardOutputMap);
if (shrinkResources) {
resourceApk = shrinkResources(ruleContext, resourceApk, proguardSpecs, proguardOutput, filesBuilder);
}
Artifact jarToDex = proguardOutput.getOutputJar();
DexingOutput dexingOutput = shouldDexWithJack(ruleContext) ? dexWithJack(ruleContext, androidCommon, proguardSpecs) : dex(ruleContext, androidSemantics, binaryJar, jarToDex, isBinaryJarFiltered, androidCommon, resourceApk.getMainDexProguardConfig(), resourceClasses, derivedJarFunction);
NestedSet<Artifact> nativeLibsZips = AndroidCommon.collectTransitiveNativeLibsZips(ruleContext).build();
Artifact finalDexes;
Artifact finalProguardMap;
if (rexEnabled) {
finalDexes = getDxArtifact(ruleContext, "rexed_dexes.zip");
Builder rexActionBuilder = new SpawnAction.Builder();
rexActionBuilder.setExecutable(ruleContext.getExecutablePrerequisite("$rex_wrapper", Mode.HOST)).setMnemonic("Rex").setProgressMessage("Rexing dex files").addArgument("--dex_input").addInputArgument(dexingOutput.classesDexZip).addArgument("--dex_output").addOutputArgument(finalDexes);
if (proguardOutput.getMapping() != null) {
finalProguardMap = ruleContext.getImplicitOutputArtifact(JavaSemantics.JAVA_BINARY_PROGUARD_MAP);
Artifact finalRexPackageMap = getDxArtifact(ruleContext, "rex_output_package.map");
rexActionBuilder.addArgument("--proguard_input_map").addInputArgument(proguardOutput.getMapping()).addArgument("--proguard_output_map").addOutputArgument(finalProguardMap).addArgument("--rex_output_package_map").addOutputArgument(finalRexPackageMap);
if (ruleContext.attributes().isAttributeValueExplicitlySpecified("rex_package_map")) {
Artifact rexPackageMap = ruleContext.getPrerequisiteArtifact("rex_package_map", Mode.TARGET);
rexActionBuilder.addArgument("--rex_input_package_map").addInputArgument(rexPackageMap);
}
} else {
finalProguardMap = proguardOutput.getMapping();
}
// determine whether or not to pass the flag to Rex
if (ruleContext.attributes().isAttributeValueExplicitlySpecified("main_dex_list")) {
rexActionBuilder.addArgument("--keep-main-dex");
}
ruleContext.registerAction(rexActionBuilder.build(ruleContext));
} else {
finalDexes = dexingOutput.classesDexZip;
finalProguardMap = proguardOutput.getMapping();
}
if (!proguardSpecs.isEmpty()) {
proguardOutput.addAllToSet(filesBuilder, finalProguardMap);
}
ApkSigningMethod signingMethod = ruleContext.getFragment(AndroidConfiguration.class).getApkSigningMethod();
Artifact unsignedApk = ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_BINARY_UNSIGNED_APK);
Artifact zipAlignedApk = ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_BINARY_APK);
ApkActionsBuilder.create("apk", signingMethod).setClassesDex(finalDexes).setResourceApk(resourceApk.getArtifact()).setJavaResourceZip(dexingOutput.javaResourceJar).setNativeLibsZips(nativeLibsZips).setNativeLibs(nativeLibs).setUnsignedApk(unsignedApk).setSignedApk(zipAlignedApk).setZipalignApk(true).registerActions(ruleContext, androidSemantics);
// Don't add blacklistedApk, so it's only built if explicitly requested.
filesBuilder.add(binaryJar);
filesBuilder.add(unsignedApk);
filesBuilder.add(zipAlignedApk);
NestedSet<Artifact> filesToBuild = filesBuilder.build();
Iterable<Artifact> dataDeps = ImmutableList.of();
if (ruleContext.attributes().has("data", BuildType.LABEL_LIST) && ruleContext.getAttributeMode("data") == Mode.DATA) {
dataDeps = ruleContext.getPrerequisiteArtifacts("data", Mode.DATA).list();
}
Artifact deployInfo = ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.DEPLOY_INFO);
AndroidDeployInfoAction.createDeployInfoAction(ruleContext, deployInfo, resourceApk.getManifest(), additionalMergedManifests, Iterables.concat(ImmutableList.of(zipAlignedApk), apksUnderTest), dataDeps);
NestedSet<Artifact> coverageMetadata = (androidCommon.getInstrumentedJar() != null) ? NestedSetBuilder.create(Order.STABLE_ORDER, androidCommon.getInstrumentedJar()) : NestedSetBuilder.<Artifact>emptySet(Order.STABLE_ORDER);
RuleConfiguredTargetBuilder builder = new RuleConfiguredTargetBuilder(ruleContext);
Artifact incrementalApk = ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_BINARY_INCREMENTAL_APK);
Artifact fullDeployMarker = ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.FULL_DEPLOY_MARKER);
Artifact incrementalDeployMarker = ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.INCREMENTAL_DEPLOY_MARKER);
Artifact splitDeployMarker = ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.SPLIT_DEPLOY_MARKER);
Artifact incrementalDexManifest = ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.DEX_MANIFEST);
ruleContext.registerAction(new SpawnAction.Builder().setMnemonic("AndroidDexManifest").setProgressMessage("Generating incremental installation manifest for " + ruleContext.getLabel()).setExecutable(ruleContext.getExecutablePrerequisite("$build_incremental_dexmanifest", Mode.HOST)).addOutputArgument(incrementalDexManifest).addInputArguments(dexingOutput.shardDexZips).useParameterFile(ParameterFileType.UNQUOTED).build(ruleContext));
Artifact stubData = ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.MOBILE_INSTALL_STUB_APPLICATION_DATA);
Artifact stubDex = getStubDex(ruleContext, javaSemantics, false);
ruleContext.assertNoErrors();
ApkActionsBuilder incrementalActionsBuilder = ApkActionsBuilder.create("incremental apk", signingMethod).setClassesDex(stubDex).setResourceApk(incrementalResourceApk.getArtifact()).setJavaResourceZip(dexingOutput.javaResourceJar).setNativeLibsZips(nativeLibsZips).setJavaResourceFile(stubData).setSignedApk(incrementalApk);
if (!ruleContext.getFragment(AndroidConfiguration.class).useIncrementalNativeLibs()) {
incrementalActionsBuilder.setNativeLibs(nativeLibs);
}
incrementalActionsBuilder.registerActions(ruleContext, androidSemantics);
Artifact argsArtifact = ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.MOBILE_INSTALL_ARGS);
ruleContext.registerAction(new WriteAdbArgsAction(ruleContext.getActionOwner(), argsArtifact));
createInstallAction(ruleContext, false, fullDeployMarker, argsArtifact, incrementalDexManifest, incrementalResourceApk.getArtifact(), incrementalApk, nativeLibs, stubData);
createInstallAction(ruleContext, true, incrementalDeployMarker, argsArtifact, incrementalDexManifest, incrementalResourceApk.getArtifact(), incrementalApk, nativeLibs, stubData);
Artifact incrementalDeployInfo = ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.DEPLOY_INFO_INCREMENTAL);
AndroidDeployInfoAction.createDeployInfoAction(ruleContext, incrementalDeployInfo, resourceApk.getManifest(), additionalMergedManifests, ImmutableList.<Artifact>of(), dataDeps);
NestedSet<Artifact> fullInstallOutputGroup = NestedSetBuilder.<Artifact>stableOrder().add(fullDeployMarker).add(incrementalDeployInfo).build();
NestedSet<Artifact> incrementalInstallOutputGroup = NestedSetBuilder.<Artifact>stableOrder().add(incrementalDeployMarker).add(incrementalDeployInfo).build();
NestedSetBuilder<Artifact> splitApkSetBuilder = NestedSetBuilder.compileOrder();
// Put the Android resource APK first so that this split gets installed first.
//
// This avoids some logcat spam during installation, because otherwise the Android package
// manager would complain about references to missing resources in the manifest during the
// installation of each split (said references would eventually get installed, but it cannot
// know that in advance)
Artifact resourceSplitApk = getDxArtifact(ruleContext, "android_resources.apk");
ApkActionsBuilder.create("split Android resource apk", signingMethod).setResourceApk(splitResourceApk.getArtifact()).setSignedApk(resourceSplitApk).registerActions(ruleContext, androidSemantics);
splitApkSetBuilder.add(resourceSplitApk);
for (int i = 0; i < dexingOutput.shardDexZips.size(); i++) {
String splitName = "dex" + (i + 1);
Artifact splitApkResources = createSplitApkResources(ruleContext, applicationManifest, splitName, true);
Artifact splitApk = getDxArtifact(ruleContext, splitName + ".apk");
ApkActionsBuilder.create("split dex apk " + (i + 1), signingMethod).setClassesDex(dexingOutput.shardDexZips.get(i)).setResourceApk(splitApkResources).setSignedApk(splitApk).registerActions(ruleContext, androidSemantics);
splitApkSetBuilder.add(splitApk);
}
Artifact nativeSplitApkResources = createSplitApkResources(ruleContext, applicationManifest, "native", false);
Artifact nativeSplitApk = getDxArtifact(ruleContext, "native.apk");
ApkActionsBuilder.create("split native apk", signingMethod).setResourceApk(nativeSplitApkResources).setNativeLibs(nativeLibs).setSignedApk(nativeSplitApk).registerActions(ruleContext, androidSemantics);
splitApkSetBuilder.add(nativeSplitApk);
Artifact javaSplitApkResources = createSplitApkResources(ruleContext, applicationManifest, "java_resources", false);
Artifact javaSplitApk = getDxArtifact(ruleContext, "java_resources.apk");
ApkActionsBuilder.create("split Java resource apk", signingMethod).setResourceApk(javaSplitApkResources).setJavaResourceZip(dexingOutput.javaResourceJar).setSignedApk(javaSplitApk).registerActions(ruleContext, androidSemantics);
splitApkSetBuilder.add(javaSplitApk);
Artifact splitMainApkResources = getDxArtifact(ruleContext, "split_main.ap_");
ruleContext.registerAction(new SpawnAction.Builder().setMnemonic("AndroidStripResources").setProgressMessage("Stripping resources from split main apk").setExecutable(ruleContext.getExecutablePrerequisite("$strip_resources", Mode.HOST)).addArgument("--input_resource_apk").addInputArgument(resourceApk.getArtifact()).addArgument("--output_resource_apk").addOutputArgument(splitMainApkResources).build(ruleContext));
NestedSet<Artifact> splitApks = splitApkSetBuilder.build();
Artifact splitMainApk = getDxArtifact(ruleContext, "split_main.apk");
Artifact splitStubDex = getStubDex(ruleContext, javaSemantics, true);
ruleContext.assertNoErrors();
ApkActionsBuilder.create("split main apk", signingMethod).setClassesDex(splitStubDex).setResourceApk(splitMainApkResources).setNativeLibsZips(nativeLibsZips).setSignedApk(splitMainApk).registerActions(ruleContext, androidSemantics);
splitApkSetBuilder.add(splitMainApk);
NestedSet<Artifact> allSplitApks = splitApkSetBuilder.build();
createSplitInstallAction(ruleContext, splitDeployMarker, argsArtifact, splitMainApk, splitApks, stubData);
Artifact splitDeployInfo = ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.DEPLOY_INFO_SPLIT);
AndroidDeployInfoAction.createDeployInfoAction(ruleContext, splitDeployInfo, resourceApk.getManifest(), additionalMergedManifests, ImmutableList.<Artifact>of(), dataDeps);
NestedSet<Artifact> splitInstallOutputGroup = NestedSetBuilder.<Artifact>stableOrder().addTransitive(allSplitApks).add(splitDeployMarker).add(splitDeployInfo).build();
Artifact debugKeystore = androidSemantics.getApkDebugSigningKey(ruleContext);
Artifact apkManifest = ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.APK_MANIFEST);
createApkManifestAction(ruleContext, apkManifest, // text proto
false, androidCommon, resourceClasses, instantRunResourceApk, nativeLibs, debugKeystore);
Artifact apkManifestText = ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.APK_MANIFEST_TEXT);
createApkManifestAction(ruleContext, apkManifestText, // text proto
true, androidCommon, resourceClasses, instantRunResourceApk, nativeLibs, debugKeystore);
androidCommon.addTransitiveInfoProviders(builder, androidSemantics, null, /* aar */
resourceApk, zipAlignedApk, apksUnderTest);
androidSemantics.addTransitiveInfoProviders(builder, ruleContext, javaCommon, androidCommon, jarToDex);
if (proguardOutput.getMapping() != null) {
builder.add(ProguardMappingProvider.class, ProguardMappingProvider.create(finalProguardMap));
}
return builder.setFilesToBuild(filesToBuild).add(RunfilesProvider.class, RunfilesProvider.simple(new Runfiles.Builder(ruleContext.getWorkspaceName(), ruleContext.getConfiguration().legacyExternalRunfiles()).addRunfiles(ruleContext, RunfilesProvider.DEFAULT_RUNFILES).addTransitiveArtifacts(filesToBuild).build())).add(JavaSourceInfoProvider.class, JavaSourceInfoProvider.fromJavaTargetAttributes(resourceClasses, javaSemantics)).add(ApkProvider.class, ApkProvider.create(NestedSetBuilder.create(Order.STABLE_ORDER, zipAlignedApk), coverageMetadata, NestedSetBuilder.create(Order.STABLE_ORDER, applicationManifest.getManifest()))).add(AndroidPreDexJarProvider.class, AndroidPreDexJarProvider.create(jarToDex)).addOutputGroup("mobile_install_full" + INTERNAL_SUFFIX, fullInstallOutputGroup).addOutputGroup("mobile_install_incremental" + INTERNAL_SUFFIX, incrementalInstallOutputGroup).addOutputGroup("mobile_install_split" + INTERNAL_SUFFIX, splitInstallOutputGroup).addOutputGroup("apk_manifest", apkManifest).addOutputGroup("apk_manifest_text", apkManifestText).addOutputGroup("android_deploy_info", deployInfo);
}
use of com.google.devtools.build.lib.analysis.actions.SpawnAction.Builder in project bazel by bazelbuild.
the class AndroidBinary method createSplitInstallAction.
private static void createSplitInstallAction(RuleContext ruleContext, Artifact marker, Artifact argsArtifact, Artifact splitMainApk, NestedSet<Artifact> splitApks, Artifact stubDataFile) {
FilesToRunProvider adb = AndroidSdkProvider.fromRuleContext(ruleContext).getAdb();
SpawnAction.Builder builder = new SpawnAction.Builder().setExecutable(ruleContext.getExecutablePrerequisite("$incremental_install", Mode.HOST)).addTool(adb).executeUnconditionally().setMnemonic("AndroidInstall").setProgressMessage("Installing " + ruleContext.getLabel() + " using split apks").setExecutionInfo(ImmutableMap.of("local", "")).addArgument("--output_marker").addOutputArgument(marker).addArgument("--stub_datafile").addInputArgument(stubDataFile).addArgument("--adb").addArgument(adb.getExecutable().getExecPathString()).addTool(adb).addArgument("--flagfile").addInputArgument(argsArtifact).addArgument("--split_main_apk").addInputArgument(splitMainApk);
for (Artifact splitApk : splitApks) {
builder.addArgument("--split_apk").addInputArgument(splitApk);
}
ruleContext.registerAction(builder.build(ruleContext));
}
use of com.google.devtools.build.lib.analysis.actions.SpawnAction.Builder in project bazel by bazelbuild.
the class AndroidAaptActionHelper method createGenerateResourceSymbolsAction.
/**
* Creates an Action that will invoke aapt to generate symbols java sources from the
* resources and pack them into a srcjar.
* @param javaSourcesJar Artifact to be generated by executing the action
* created by this method.
* @param rTxt R.txt artifact to be generated by the aapt invocation.
* @param javaPackage The package for which resources will be generated
* @param inlineConstants whether or not constants in Java generated sources
* should be inlined by the compiler.
*/
public void createGenerateResourceSymbolsAction(Artifact javaSourcesJar, Artifact rTxt, String javaPackage, boolean inlineConstants) {
// java path from the provided package for the resources
PathFragment javaPath = new PathFragment(javaPackage.replace('.', '/'));
PathFragment javaResourcesRoot = javaSourcesJar.getRoot().getExecPath().getRelative(ruleContext.getUniqueDirectory("_java_resources"));
String javaResources = javaResourcesRoot.getRelative(javaPath).getPathString();
List<String> args = new ArrayList<>();
args.add(javaSourcesJar.getExecPathString());
args.add(javaResourcesRoot.getPathString());
args.add(javaResources);
args.addAll(createAaptCommand("javasrcs", javaSourcesJar, rTxt, inlineConstants, "-J", javaResources, "--custom-package", javaPackage, "--rename-manifest-package", javaPackage));
final Builder builder = new SpawnAction.Builder().addInputs(getInputs()).addTool(AndroidSdkProvider.fromRuleContext(ruleContext).getAapt()).setExecutable(ruleContext.getExecutablePrerequisite("$android_aapt_java_generator", Mode.HOST)).addOutput(javaSourcesJar).setCommandLine(CommandLine.of(args, false)).useParameterFile(ParameterFileType.UNQUOTED).setProgressMessage("Generating Java resources").setMnemonic("AndroidAapt");
if (rTxt != null) {
builder.addOutput(rTxt);
}
ruleContext.registerAction(builder.build(ruleContext));
}
use of com.google.devtools.build.lib.analysis.actions.SpawnAction.Builder in project bazel by bazelbuild.
the class AndroidBinary method createInstallAction.
private static void createInstallAction(RuleContext ruleContext, boolean incremental, Artifact marker, Artifact argsArtifact, Artifact dexmanifest, Artifact resourceApk, Artifact apk, NativeLibs nativeLibs, Artifact stubDataFile) {
FilesToRunProvider adb = AndroidSdkProvider.fromRuleContext(ruleContext).getAdb();
SpawnAction.Builder builder = new SpawnAction.Builder().setExecutable(ruleContext.getExecutablePrerequisite("$incremental_install", Mode.HOST)).executeUnconditionally().setMnemonic("AndroidInstall").setProgressMessage("Installing " + ruleContext.getLabel() + (incremental ? " incrementally" : "")).setExecutionInfo(ImmutableMap.of("local", "")).addArgument("--output_marker").addOutputArgument(marker).addArgument("--dexmanifest").addInputArgument(dexmanifest).addArgument("--resource_apk").addInputArgument(resourceApk).addArgument("--stub_datafile").addInputArgument(stubDataFile).addArgument("--adb").addArgument(adb.getExecutable().getExecPathString()).addTool(adb).addArgument("--flagfile").addInputArgument(argsArtifact);
if (!incremental) {
builder.addArgument("--apk").addInputArgument(apk);
}
if (ruleContext.getFragment(AndroidConfiguration.class).useIncrementalNativeLibs()) {
for (Map.Entry<String, Iterable<Artifact>> arch : nativeLibs.getMap().entrySet()) {
for (Artifact lib : arch.getValue()) {
builder.addArgument("--native_lib").addArgument(arch.getKey() + ":" + lib.getExecPathString()).addInput(lib);
}
}
}
ruleContext.registerAction(builder.build(ruleContext));
}
use of com.google.devtools.build.lib.analysis.actions.SpawnAction.Builder in project bazel by bazelbuild.
the class AndroidBinary method createMainDexListAction.
/**
* Creates an action that generates a list of classes to be passed to the dexer's
* --main-dex-list flag (which specifies the classes that need to be directly in classes.dex).
* Returns the file containing the list.
*/
static Artifact createMainDexListAction(RuleContext ruleContext, AndroidSemantics androidSemantics, Artifact jar, @Nullable Artifact mainDexProguardSpec) throws InterruptedException {
// Process the input jar through Proguard into an intermediate, streamlined jar.
Artifact strippedJar = AndroidBinary.getDxArtifact(ruleContext, "main_dex_intermediate.jar");
AndroidSdkProvider sdk = AndroidSdkProvider.fromRuleContext(ruleContext);
SpawnAction.Builder streamlinedBuilder = new SpawnAction.Builder().addOutput(strippedJar).setExecutable(sdk.getProguard()).setProgressMessage("Generating streamlined input jar for main dex classes list").setMnemonic("MainDexClassesIntermediate").addArgument("-forceprocessing").addArgument("-injars").addInputArgument(jar).addArgument("-libraryjars").addInputArgument(sdk.getShrinkedAndroidJar()).addArgument("-outjars").addArgument(strippedJar.getExecPathString()).addArgument("-dontwarn").addArgument("-dontnote").addArgument("-dontoptimize").addArgument("-dontobfuscate").addArgument("-dontpreverify");
List<Artifact> specs = new ArrayList<>();
specs.addAll(ruleContext.getPrerequisiteArtifacts("main_dex_proguard_specs", Mode.TARGET).list());
if (specs.isEmpty()) {
specs.add(sdk.getMainDexClasses());
}
if (mainDexProguardSpec != null) {
specs.add(mainDexProguardSpec);
}
for (Artifact spec : specs) {
streamlinedBuilder.addArgument("-include");
streamlinedBuilder.addInputArgument(spec);
}
androidSemantics.addMainDexListActionArguments(ruleContext, streamlinedBuilder);
ruleContext.registerAction(streamlinedBuilder.build(ruleContext));
// Create the main dex classes list.
Artifact mainDexList = AndroidBinary.getDxArtifact(ruleContext, "main_dex_list.txt");
Builder builder = new Builder().setMnemonic("MainDexClasses").setProgressMessage("Generating main dex classes list");
ruleContext.registerAction(builder.setExecutable(sdk.getMainDexListCreator()).addOutputArgument(mainDexList).addInputArgument(strippedJar).addInputArgument(jar).addArguments(ruleContext.getTokenizedStringListAttr("main_dex_list_opts")).build(ruleContext));
return mainDexList;
}
Aggregations