| // Copyright 2015 The Bazel Authors. All rights reserved. |
| // |
| // 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.google.devtools.build.lib.rules.android; |
| |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.Iterables; |
| import com.google.devtools.build.lib.actions.Action; |
| import com.google.devtools.build.lib.actions.Artifact; |
| import com.google.devtools.build.lib.actions.CommandLine; |
| import com.google.devtools.build.lib.actions.ParamFileInfo; |
| import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType; |
| import com.google.devtools.build.lib.analysis.RuleContext; |
| import com.google.devtools.build.lib.analysis.actions.ActionConstructionContext; |
| import com.google.devtools.build.lib.analysis.actions.SpawnAction; |
| import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode; |
| import com.google.devtools.build.lib.util.OS; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| /** Builder for creating aar generator action. */ |
| public class AarGeneratorBuilder { |
| |
| private AndroidResources primaryResources; |
| private AndroidAssets primaryAssets; |
| |
| private Artifact manifest; |
| private Artifact rTxt; |
| private Artifact classes; |
| private ImmutableList<Artifact> proguardSpecs = ImmutableList.of(); |
| |
| private Artifact aarOut; |
| private boolean throwOnResourceConflict; |
| |
| private final RuleContext ruleContext; |
| private final SpawnAction.Builder builder; |
| |
| /** |
| * Creates an {@link AarGeneratorBuilder}. |
| * |
| * @param ruleContext The {@link RuleContext} that is used to register the {@link Action}. |
| */ |
| public AarGeneratorBuilder(RuleContext ruleContext) { |
| this.ruleContext = ruleContext; |
| this.builder = new SpawnAction.Builder(); |
| } |
| |
| public AarGeneratorBuilder withPrimaryResources(AndroidResources primaryResources) { |
| this.primaryResources = primaryResources; |
| return this; |
| } |
| |
| public AarGeneratorBuilder withPrimaryAssets(AndroidAssets primaryAssets) { |
| this.primaryAssets = primaryAssets; |
| return this; |
| } |
| |
| public AarGeneratorBuilder withManifest(Artifact manifest) { |
| this.manifest = manifest; |
| return this; |
| } |
| |
| public AarGeneratorBuilder withRtxt(Artifact rTxt) { |
| this.rTxt = rTxt; |
| return this; |
| } |
| |
| public AarGeneratorBuilder withClasses(Artifact classes) { |
| this.classes = classes; |
| return this; |
| } |
| |
| public AarGeneratorBuilder setAAROut(Artifact aarOut) { |
| this.aarOut = aarOut; |
| return this; |
| } |
| |
| public AarGeneratorBuilder setProguardSpecs(ImmutableList<Artifact> proguardSpecs) { |
| this.proguardSpecs = proguardSpecs; |
| return this; |
| } |
| |
| public AarGeneratorBuilder setThrowOnResourceConflict(boolean throwOnResourceConflict) { |
| this.throwOnResourceConflict = throwOnResourceConflict; |
| return this; |
| } |
| |
| public void build(ActionConstructionContext context) { |
| List<Artifact> outs = new ArrayList<>(); |
| List<Artifact> ins = new ArrayList<>(); |
| List<String> args = new ArrayList<>(); |
| |
| // Set the busybox tool |
| args.add("--tool"); |
| args.add("GENERATE_AAR"); |
| // Deliminate between the tool and the tool arguments. |
| args.add("--"); |
| |
| args.add("--mainData"); |
| |
| Iterables.addAll(ins, primaryResources.getResources()); |
| Iterables.addAll(ins, primaryAssets.getAssets()); |
| ins.add(manifest); |
| |
| // no R.txt, because it will be generated from this action. |
| args.add( |
| String.format( |
| "%s:%s:%s", |
| AndroidDataConverter.rootsToString(primaryResources.getResourceRoots()), |
| AndroidDataConverter.rootsToString(primaryAssets.getAssetRoots()), |
| manifest.getExecPathString())); |
| |
| if (manifest != null) { |
| args.add("--manifest"); |
| args.add(manifest.getExecPathString()); |
| ins.add(manifest); |
| } |
| |
| if (rTxt != null) { |
| args.add("--rtxt"); |
| args.add(rTxt.getExecPathString()); |
| ins.add(rTxt); |
| } |
| |
| if (classes != null) { |
| args.add("--classes"); |
| args.add(classes.getExecPathString()); |
| ins.add(classes); |
| } |
| |
| for (Artifact proguardSpec : proguardSpecs) { |
| args.add("--proguardSpec"); |
| args.add(proguardSpec.getExecPathString()); |
| ins.add(proguardSpec); |
| } |
| |
| args.add("--aarOutput"); |
| args.add(aarOut.getExecPathString()); |
| outs.add(aarOut); |
| |
| if (throwOnResourceConflict) { |
| args.add("--throwOnResourceConflict"); |
| } |
| |
| ParamFileInfo.Builder paramFileInfo = ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED); |
| // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special |
| // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting |
| // semantics are very complicated (more so than in Bash), so let's just always use a parameter |
| // file. |
| // TODO(laszlocsomor), TODO(corysmith): restructure the Android BusyBux's flags by deprecating |
| // list-type and list-of-list-type flags that use such problematic separators in favor of |
| // multi-value flags (to remove one level of listing) and by changing all list separators to a |
| // platform-safe character (= comma). |
| paramFileInfo.setUseAlways(OS.getCurrent() == OS.WINDOWS); |
| |
| ruleContext.registerAction( |
| this.builder |
| .useDefaultShellEnvironment() |
| .addInputs(ImmutableList.<Artifact>copyOf(ins)) |
| .addOutputs(ImmutableList.<Artifact>copyOf(outs)) |
| .addCommandLine(CommandLine.of(args), paramFileInfo.build()) |
| .setExecutable( |
| ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST)) |
| .setProgressMessage("Building AAR package for %s", ruleContext.getLabel()) |
| .setMnemonic("AARGenerator") |
| .build(context)); |
| } |
| } |