use of com.google.devtools.build.lib.analysis.actions.CommandLine in project bazel by bazelbuild.
the class CustomCommandLineTest method testJoinExpandedTreeArtifactExecPath.
@Test
public void testJoinExpandedTreeArtifactExecPath() {
Artifact treeArtifact = createTreeArtifact("myTreeArtifact");
CommandLine commandLine = CustomCommandLine.builder().add("hello").addJoinExpandedTreeArtifactExecPath(":", treeArtifact).build();
assertThat(commandLine.arguments()).containsExactly("hello", "JoinExpandedTreeArtifactExecPathsArg{ delimiter: :, treeArtifact: myTreeArtifact}");
final Iterable<TreeFileArtifact> treeFileArtifacts = ImmutableList.of(createTreeFileArtifact(treeArtifact, "children/child1"), createTreeFileArtifact(treeArtifact, "children/child2"));
ArtifactExpander artifactExpander = new ArtifactExpander() {
@Override
public void expand(Artifact artifact, Collection<? super Artifact> output) {
for (TreeFileArtifact treeFileArtifact : treeFileArtifacts) {
if (treeFileArtifact.getParent().equals(artifact)) {
output.add(treeFileArtifact);
}
}
}
};
assertThat(commandLine.arguments(artifactExpander)).containsExactly("hello", "myTreeArtifact/children/child1:myTreeArtifact/children/child2");
}
use of com.google.devtools.build.lib.analysis.actions.CommandLine in project bazel by bazelbuild.
the class LegacyCompilationSupport method registerLinkAction.
private void registerLinkAction(ObjcProvider objcProvider, ExtraLinkArgs extraLinkArgs, Iterable<Artifact> extraLinkInputs, Optional<Artifact> dsymBundleZip, Iterable<Artifact> prunedJ2ObjcArchives, Optional<Artifact> linkmap, Optional<Artifact> bitcodeSymbolMap) {
Artifact binaryToLink = getBinaryToLink();
ImmutableList<Artifact> objcLibraries = objcProvider.getObjcLibraries();
ImmutableList<Artifact> ccLibraries = objcProvider.getCcLibraries();
ImmutableList<Artifact> bazelBuiltLibraries = Iterables.isEmpty(prunedJ2ObjcArchives) ? objcLibraries : substituteJ2ObjcPrunedLibraries(objcProvider);
CommandLine commandLine = linkCommandLine(extraLinkArgs, objcProvider, binaryToLink, dsymBundleZip, ccLibraries, bazelBuiltLibraries, linkmap, bitcodeSymbolMap);
ruleContext.registerAction(ObjcRuleClasses.spawnAppleEnvActionBuilder(appleConfiguration, appleConfiguration.getSingleArchPlatform()).setMnemonic("ObjcLink").setShellCommand(ImmutableList.of("/bin/bash", "-c")).setCommandLine(new SingleArgCommandLine(commandLine)).addOutput(binaryToLink).addOutputs(dsymBundleZip.asSet()).addOutputs(linkmap.asSet()).addOutputs(bitcodeSymbolMap.asSet()).addInputs(bazelBuiltLibraries).addTransitiveInputs(objcProvider.get(IMPORTED_LIBRARY)).addTransitiveInputs(objcProvider.get(STATIC_FRAMEWORK_FILE)).addTransitiveInputs(objcProvider.get(DYNAMIC_FRAMEWORK_FILE)).addTransitiveInputs(objcProvider.get(LINK_INPUTS)).addInputs(ccLibraries).addInputs(extraLinkInputs).addInputs(prunedJ2ObjcArchives).addInput(intermediateArtifacts.linkerObjList()).addInput(xcrunwrapper(ruleContext).getExecutable()).build(ruleContext));
if (objcConfiguration.shouldStripBinary()) {
registerBinaryStripAction(binaryToLink, getStrippingType(commandLine));
}
}
use of com.google.devtools.build.lib.analysis.actions.CommandLine in project bazel by bazelbuild.
the class DeployArchiveBuilder method build.
/** Builds the action as configured. */
public void build() throws InterruptedException {
ImmutableList<Artifact> classpathResources = attributes.getClassPathResources();
Set<String> classPathResourceNames = new HashSet<>();
for (Artifact artifact : classpathResources) {
String name = artifact.getExecPath().getBaseName();
if (!classPathResourceNames.add(name)) {
ruleContext.attributeError("classpath_resources", "entries must have different file names (duplicate: " + name + ")");
return;
}
}
IterablesChain<Artifact> runtimeJars = runtimeJarsBuilder.build();
// TODO(kmb): Consider not using getArchiveInputs, specifically because we don't want/need to
// transform anything but the runtimeClasspath and b/c we currently do it twice here and below
IterablesChain.Builder<Artifact> inputs = IterablesChain.builder();
inputs.add(getArchiveInputs(attributes, derivedJars));
inputs.add(ImmutableList.copyOf(Iterables.transform(runtimeJars, derivedJars)));
if (runfilesMiddleman != null) {
inputs.addElement(runfilesMiddleman);
}
ImmutableList<Artifact> buildInfoArtifacts = ruleContext.getBuildInfo(JavaBuildInfoFactory.KEY);
inputs.add(buildInfoArtifacts);
Iterable<Artifact> runtimeClasspath = Iterables.transform(Iterables.concat(runtimeJars, attributes.getRuntimeClassPathForArchive()), derivedJars);
if (launcher != null) {
inputs.addElement(launcher);
}
CommandLine commandLine = semantics.buildSingleJarCommandLine(ruleContext.getConfiguration(), outputJar, javaStartClass, deployManifestLines, buildInfoArtifacts, classpathResources, runtimeClasspath, includeBuildData, compression, launcher);
List<String> jvmArgs = ImmutableList.of(SINGLEJAR_MAX_MEMORY);
ResourceSet resourceSet = ResourceSet.createWithRamCpuIo(/*memoryMb = */
200.0, /*cpuUsage = */
.2, /*ioUsage=*/
.2);
// If singlejar's name ends with .jar, it is Java application, otherwise it is native.
// TODO(asmundak): once https://github.com/bazelbuild/bazel/issues/2241 is fixed (that is,
// the native singlejar is used on windows) remove support for the Java implementation
Artifact singlejar = getSingleJar(ruleContext);
if (singlejar.getFilename().endsWith(".jar")) {
ruleContext.registerAction(new SpawnAction.Builder().addInputs(inputs.build()).addTransitiveInputs(JavaHelper.getHostJavabaseInputs(ruleContext)).addOutput(outputJar).setResources(resourceSet).setJarExecutable(ruleContext.getHostConfiguration().getFragment(Jvm.class).getJavaExecutable(), singlejar, jvmArgs).setCommandLine(commandLine).alwaysUseParameterFile(ParameterFileType.SHELL_QUOTED).setProgressMessage("Building deploy jar " + outputJar.prettyPrint()).setMnemonic("JavaDeployJar").setExecutionInfo(ImmutableMap.of("supports-workers", "1")).build(ruleContext));
} else {
ruleContext.registerAction(new SpawnAction.Builder().addInputs(inputs.build()).addOutput(outputJar).setResources(resourceSet).setExecutable(singlejar).setCommandLine(commandLine).alwaysUseParameterFile(ParameterFileType.SHELL_QUOTED).setProgressMessage("Building deploy jar " + outputJar.prettyPrint()).setMnemonic("JavaDeployJar").build(ruleContext));
}
}
use of com.google.devtools.build.lib.analysis.actions.CommandLine in project bazel by bazelbuild.
the class AndroidBinary method dex.
/** Creates one or more classes.dex files that correspond to {@code proguardedJar}. */
private static DexingOutput dex(RuleContext ruleContext, AndroidSemantics androidSemantics, Artifact binaryJar, Artifact proguardedJar, boolean isBinaryJarFiltered, AndroidCommon common, @Nullable Artifact mainDexProguardSpec, JavaTargetAttributes attributes, Function<Artifact, Artifact> derivedJarFunction) throws InterruptedException, RuleErrorException {
List<String> dexopts = ruleContext.getTokenizedStringListAttr("dexopts");
MultidexMode multidexMode = getMultidexMode(ruleContext);
if (!supportsMultidexMode(ruleContext, multidexMode)) {
ruleContext.throwWithRuleError("Multidex mode \"" + multidexMode.getAttributeValue() + "\" not supported by this version of the Android SDK");
}
int dexShards = ruleContext.attributes().get("dex_shards", Type.INTEGER);
if (dexShards > 1) {
if (multidexMode == MultidexMode.OFF) {
ruleContext.throwWithRuleError(".dex sharding is only available in multidex mode");
}
if (multidexMode == MultidexMode.MANUAL_MAIN_DEX) {
ruleContext.throwWithRuleError(".dex sharding is not available in manual multidex mode");
}
}
Artifact mainDexList = ruleContext.getPrerequisiteArtifact("main_dex_list", Mode.TARGET);
if ((mainDexList != null && multidexMode != MultidexMode.MANUAL_MAIN_DEX) || (mainDexList == null && multidexMode == MultidexMode.MANUAL_MAIN_DEX)) {
ruleContext.throwWithRuleError("Both \"main_dex_list\" and \"multidex='manual_main_dex'\" must be specified.");
}
// Always OFF if finalJarIsDerived
ImmutableSet<AndroidBinaryType> incrementalDexing = getEffectiveIncrementalDexing(ruleContext, dexopts, !Objects.equals(binaryJar, proguardedJar));
Artifact inclusionFilterJar = isBinaryJarFiltered && Objects.equals(binaryJar, proguardedJar) ? binaryJar : null;
if (multidexMode == MultidexMode.OFF) {
// Single dex mode: generate classes.dex directly from the input jar.
if (incrementalDexing.contains(AndroidBinaryType.MONODEX)) {
Artifact classesDex = getDxArtifact(ruleContext, "classes.dex.zip");
Artifact jarToDex = getDxArtifact(ruleContext, "classes.jar");
createShuffleJarAction(ruleContext, true, (Artifact) null, ImmutableList.of(jarToDex), common, inclusionFilterJar, dexopts, androidSemantics, attributes, derivedJarFunction, (Artifact) null);
createDexMergerAction(ruleContext, "off", jarToDex, classesDex, (Artifact) null, dexopts);
return new DexingOutput(classesDex, binaryJar, ImmutableList.of(classesDex));
} else {
// By *not* writing a zip we get dx to drop resources on the floor.
Artifact classesDex = getDxArtifact(ruleContext, "classes.dex");
AndroidCommon.createDexAction(ruleContext, proguardedJar, classesDex, dexopts, /* multidex */
false, (Artifact) null);
return new DexingOutput(classesDex, binaryJar, ImmutableList.of(classesDex));
}
} else {
if (multidexMode == MultidexMode.LEGACY) {
// For legacy multidex, we need to generate a list for the dexer's --main-dex-list flag.
mainDexList = createMainDexListAction(ruleContext, androidSemantics, proguardedJar, mainDexProguardSpec);
}
Artifact classesDex = getDxArtifact(ruleContext, "classes.dex.zip");
if (dexShards > 1) {
List<Artifact> shards = new ArrayList<>(dexShards);
for (int i = 1; i <= dexShards; i++) {
shards.add(getDxArtifact(ruleContext, "shard" + i + ".jar"));
}
Artifact javaResourceJar = createShuffleJarAction(ruleContext, incrementalDexing.contains(AndroidBinaryType.MULTIDEX_SHARDED), /*proguardedJar*/
!Objects.equals(binaryJar, proguardedJar) ? proguardedJar : null, shards, common, inclusionFilterJar, dexopts, androidSemantics, attributes, derivedJarFunction, mainDexList);
List<Artifact> shardDexes = new ArrayList<>(dexShards);
for (int i = 1; i <= dexShards; i++) {
Artifact shard = shards.get(i - 1);
Artifact shardDex = getDxArtifact(ruleContext, "shard" + i + ".dex.zip");
shardDexes.add(shardDex);
if (incrementalDexing.contains(AndroidBinaryType.MULTIDEX_SHARDED)) {
// If there's a main dex list then the first shard contains exactly those files.
// To work with devices that lack native multi-dex support we need to make sure that
// the main dex list becomes one dex file if at all possible.
// Note shard here (mostly) contains of .class.dex files from shuffled dex archives,
// instead of being a conventional Jar file with .class files.
String multidexStrategy = mainDexList != null && i == 1 ? "minimal" : "best_effort";
createDexMergerAction(ruleContext, multidexStrategy, shard, shardDex, (Artifact) null, dexopts);
} else {
AndroidCommon.createDexAction(ruleContext, shard, shardDex, dexopts, /* multidex */
true, (Artifact) null);
}
}
CommandLine mergeCommandLine = CustomCommandLine.builder().addBeforeEachExecPath("--input_zip", shardDexes).addExecPath("--output_zip", classesDex).build();
ruleContext.registerAction(new SpawnAction.Builder().setMnemonic("MergeDexZips").setProgressMessage("Merging dex shards for " + ruleContext.getLabel()).setExecutable(ruleContext.getExecutablePrerequisite("$merge_dexzips", Mode.HOST)).addInputs(shardDexes).addOutput(classesDex).setCommandLine(mergeCommandLine).build(ruleContext));
if (incrementalDexing.contains(AndroidBinaryType.MULTIDEX_SHARDED)) {
// Using the deploy jar for java resources gives better "bazel mobile-install" performance
// with incremental dexing b/c bazel can create the "incremental" and "split resource"
// APKs earlier (b/c these APKs don't depend on code being dexed here). This is also done
// for other multidex modes.
javaResourceJar = binaryJar;
}
return new DexingOutput(classesDex, javaResourceJar, shardDexes);
} else {
if (incrementalDexing.contains(AndroidBinaryType.MULTIDEX_UNSHARDED)) {
Artifact jarToDex = AndroidBinary.getDxArtifact(ruleContext, "classes.jar");
createShuffleJarAction(ruleContext, true, (Artifact) null, ImmutableList.of(jarToDex), common, inclusionFilterJar, dexopts, androidSemantics, attributes, derivedJarFunction, (Artifact) null);
createDexMergerAction(ruleContext, "minimal", jarToDex, classesDex, mainDexList, dexopts);
} else {
// Because the dexer also places resources into this zip, we also need to create a cleanup
// action that removes all non-.dex files before staging for apk building.
// Create an artifact for the intermediate zip output that includes non-.dex files.
Artifact classesDexIntermediate = AndroidBinary.getDxArtifact(ruleContext, "intermediate_classes.dex.zip");
// Have the dexer generate the intermediate file and the "cleaner" action consume this to
// generate the final archive with only .dex files.
AndroidCommon.createDexAction(ruleContext, proguardedJar, classesDexIntermediate, dexopts, /* multidex */
true, mainDexList);
createCleanDexZipAction(ruleContext, classesDexIntermediate, classesDex);
}
return new DexingOutput(classesDex, binaryJar, ImmutableList.of(classesDex));
}
}
}
Aggregations