Search in sources :

Example 1 with CommandLine

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");
}
Also used : TreeFileArtifact(com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact) CommandLine(com.google.devtools.build.lib.analysis.actions.CommandLine) CustomCommandLine(com.google.devtools.build.lib.analysis.actions.CustomCommandLine) ArtifactExpander(com.google.devtools.build.lib.actions.Artifact.ArtifactExpander) Collection(java.util.Collection) SpecialArtifact(com.google.devtools.build.lib.actions.Artifact.SpecialArtifact) TreeFileArtifact(com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact) Test(org.junit.Test)

Example 2 with CommandLine

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));
    }
}
Also used : CustomCommandLine(com.google.devtools.build.lib.analysis.actions.CustomCommandLine) CommandLine(com.google.devtools.build.lib.analysis.actions.CommandLine) Artifact(com.google.devtools.build.lib.actions.Artifact) TreeFileArtifact(com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact)

Example 3 with 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));
    }
}
Also used : IterablesChain(com.google.devtools.build.lib.collect.IterablesChain) ResourceSet(com.google.devtools.build.lib.actions.ResourceSet) Artifact(com.google.devtools.build.lib.actions.Artifact) CommandLine(com.google.devtools.build.lib.analysis.actions.CommandLine) CustomCommandLine(com.google.devtools.build.lib.analysis.actions.CustomCommandLine) HashSet(java.util.HashSet)

Example 4 with CommandLine

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));
        }
    }
}
Also used : CustomCommandLine(com.google.devtools.build.lib.analysis.actions.CustomCommandLine) CommandLine(com.google.devtools.build.lib.analysis.actions.CommandLine) MultidexMode(com.google.devtools.build.lib.rules.android.AndroidRuleClasses.MultidexMode) MultimapBuilder(com.google.common.collect.MultimapBuilder) Builder(com.google.devtools.build.lib.analysis.actions.SpawnAction.Builder) NestedSetBuilder(com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder) RuleConfiguredTargetBuilder(com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder) DeployArchiveBuilder(com.google.devtools.build.lib.rules.java.DeployArchiveBuilder) AndroidBinaryType(com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidBinaryType) ArrayList(java.util.ArrayList) Artifact(com.google.devtools.build.lib.actions.Artifact)

Aggregations

CommandLine (com.google.devtools.build.lib.analysis.actions.CommandLine)4 CustomCommandLine (com.google.devtools.build.lib.analysis.actions.CustomCommandLine)4 Artifact (com.google.devtools.build.lib.actions.Artifact)3 TreeFileArtifact (com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact)2 MultimapBuilder (com.google.common.collect.MultimapBuilder)1 ArtifactExpander (com.google.devtools.build.lib.actions.Artifact.ArtifactExpander)1 SpecialArtifact (com.google.devtools.build.lib.actions.Artifact.SpecialArtifact)1 ResourceSet (com.google.devtools.build.lib.actions.ResourceSet)1 RuleConfiguredTargetBuilder (com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder)1 Builder (com.google.devtools.build.lib.analysis.actions.SpawnAction.Builder)1 IterablesChain (com.google.devtools.build.lib.collect.IterablesChain)1 NestedSetBuilder (com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder)1 AndroidBinaryType (com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidBinaryType)1 MultidexMode (com.google.devtools.build.lib.rules.android.AndroidRuleClasses.MultidexMode)1 DeployArchiveBuilder (com.google.devtools.build.lib.rules.java.DeployArchiveBuilder)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 HashSet (java.util.HashSet)1 Test (org.junit.Test)1