blob: 351f66ddf50028cd7f1f8451ff42bb463a0580b3 [file] [log] [blame]
// 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));
}
}