Search in sources :

Example 1 with JavaOptimizationMode

use of com.google.devtools.build.lib.rules.java.JavaConfiguration.JavaOptimizationMode in project bazel by bazelbuild.

the class ProguardHelper method getProguardOutputs.

public static ProguardOutput getProguardOutputs(Artifact outputJar, @Nullable Artifact proguardSeeds, @Nullable Artifact proguardUsage, RuleContext ruleContext, JavaSemantics semantics, @Nullable Artifact proguardOutputMap) throws InterruptedException {
    JavaOptimizationMode optMode = getJavaOptimizationMode(ruleContext);
    boolean mappingRequested = genProguardMapping(ruleContext.attributes());
    Artifact proguardOutputProtoMap = null;
    Artifact proguardConstantStringMap = null;
    if (mappingRequested || optMode.alwaysGenerateOutputMapping()) {
        // TODO(bazel-team): if rex is enabled, the proguard map will change and then will no
        // longer correspond to the proto map
        proguardOutputProtoMap = semantics.getProtoMapping(ruleContext);
    }
    if (genObfuscatedConstantStringMap(ruleContext.attributes())) {
        proguardConstantStringMap = semantics.getObfuscatedConstantStringMap(ruleContext);
    }
    Artifact proguardConfigOutput = ruleContext.getImplicitOutputArtifact(JavaSemantics.JAVA_BINARY_PROGUARD_CONFIG);
    return new ProguardOutput(outputJar, proguardOutputMap, proguardOutputProtoMap, proguardSeeds, proguardUsage, proguardConstantStringMap, proguardConfigOutput);
}
Also used : JavaOptimizationMode(com.google.devtools.build.lib.rules.java.JavaConfiguration.JavaOptimizationMode) Artifact(com.google.devtools.build.lib.actions.Artifact)

Example 2 with JavaOptimizationMode

use of com.google.devtools.build.lib.rules.java.JavaConfiguration.JavaOptimizationMode in project bazel by bazelbuild.

the class ProguardHelper method applyProguardIfRequested.

/**
   * Creates an action to run Proguard to <i>output</i> the given {@code deployJar} artifact if
   * --java_optimization_mode calls for it from an assumed input artifact {@link
   * JavaSemantics#JAVA_BINARY_MERGED_JAR}. Returns the artifacts that Proguard will generate or
   * {@code null} if Proguard isn't used.
   *
   * <p>If this method returns artifacts then {@link
   * com.google.devtools.build.lib.rules.java.DeployArchiveBuilder} needs to write the assumed input
   * artifact (instead of the conventional deploy.jar, which now Proguard writes). Do not use this
   * method for binary rules that themselves declare {@link #PROGUARD_SPECS} attributes, which as of
   * includes 1/2016 {@code android_binary} and {@code android_test}.
   */
@Nullable
public ProguardOutput applyProguardIfRequested(RuleContext ruleContext, Artifact deployJar, ImmutableList<Artifact> bootclasspath, String mainClassName, JavaSemantics semantics) throws InterruptedException {
    JavaOptimizationMode optMode = getJavaOptimizationMode(ruleContext);
    if (optMode == JavaOptimizationMode.NOOP || optMode == JavaOptimizationMode.LEGACY) {
        // For simplicity do nothing in LEGACY mode
        return null;
    }
    Preconditions.checkArgument(!bootclasspath.isEmpty(), "Bootclasspath should not be empty");
    FilesToRunProvider proguard = findProguard(ruleContext);
    if (proguard == null) {
        ruleContext.ruleError("--proguard_top required for --java_optimization_mode=" + optMode);
        return null;
    }
    ImmutableList<Artifact> proguardSpecs = collectProguardSpecs(ruleContext, bootclasspath, mainClassName);
    Artifact singleJar = ruleContext.getImplicitOutputArtifact(JavaSemantics.JAVA_BINARY_MERGED_JAR);
    // 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 (genProguardMapping(ruleContext.attributes()) || optMode.alwaysGenerateOutputMapping()) {
        proguardOutputMap = ruleContext.getImplicitOutputArtifact(JavaSemantics.JAVA_BINARY_PROGUARD_MAP);
    }
    return createProguardAction(ruleContext, proguard, singleJar, proguardSpecs, /* proguardSeeds */
    (Artifact) null, /* proguardUsage */
    (Artifact) null, /* proguardMapping */
    (Artifact) null, bootclasspath, deployJar, semantics, /* optimizationPases */
    3, proguardOutputMap, /* useSingleJarForProguardLibraryJars */
    false);
}
Also used : JavaOptimizationMode(com.google.devtools.build.lib.rules.java.JavaConfiguration.JavaOptimizationMode) FilesToRunProvider(com.google.devtools.build.lib.analysis.FilesToRunProvider) Artifact(com.google.devtools.build.lib.actions.Artifact) Nullable(javax.annotation.Nullable)

Example 3 with JavaOptimizationMode

use of com.google.devtools.build.lib.rules.java.JavaConfiguration.JavaOptimizationMode in project bazel by bazelbuild.

the class AndroidBinary method createEmptyProguardAction.

private static ProguardOutput createEmptyProguardAction(RuleContext ruleContext, JavaSemantics semantics, Artifact proguardOutputJar, Artifact deployJarArtifact, Artifact proguardOutputMap) throws InterruptedException {
    NestedSetBuilder<Artifact> failures = NestedSetBuilder.<Artifact>stableOrder();
    ProguardOutput outputs = ProguardHelper.getProguardOutputs(proguardOutputJar, /* proguardSeeds */
    (Artifact) null, /* proguardUsage */
    (Artifact) null, ruleContext, semantics, proguardOutputMap);
    outputs.addAllToSet(failures);
    JavaOptimizationMode optMode = getJavaOptimizationMode(ruleContext);
    ruleContext.registerAction(new FailAction(ruleContext.getActionOwner(), failures.build(), String.format("Can't run Proguard %s", optMode == JavaOptimizationMode.LEGACY ? "without proguard_specs" : "in optimization mode " + optMode)));
    return new ProguardOutput(deployJarArtifact, null, null, null, null, null, null);
}
Also used : JavaOptimizationMode(com.google.devtools.build.lib.rules.java.JavaConfiguration.JavaOptimizationMode) ProguardOutput(com.google.devtools.build.lib.rules.java.ProguardHelper.ProguardOutput) FailAction(com.google.devtools.build.lib.actions.FailAction) Artifact(com.google.devtools.build.lib.actions.Artifact)

Example 4 with JavaOptimizationMode

use of com.google.devtools.build.lib.rules.java.JavaConfiguration.JavaOptimizationMode in project bazel by bazelbuild.

the class ProguardHelper method createProguardAction.

/**
   * Creates an action to run Proguard over the given {@code programJar} with various other given
   * inputs to produce {@code proguardOutputJar}.  If requested explicitly, or implicitly with
   * --java_optimization_mode, the action also produces a mapping file (which shows what methods and
   * classes in the output Jar correspond to which methods and classes in the input).  The "pair"
   * returned by this method indicates whether a mapping is being produced.
   *
   * <p>See the Proguard manual for the meaning of the various artifacts in play.
   *
   * @param proguard Proguard executable to use
   * @param proguardSpecs Proguard specification files to pass to Proguard
   * @param proguardMapping optional mapping file for Proguard to apply
   * @param libraryJars any other Jar files that the {@code programJar} will run against
   * @param mappingRequested whether to ask Proguard to output a mapping file (a mapping will be
   *        produced anyway if --java_optimization_mode includes obfuscation)
   * @param optimizationPasses if not null specifies to break proguard up into multiple passes with
   *        the given number of optimization passes.
   * @param proguardOutputMap mapping generated by Proguard if requested. could be null.
   * @param useSingleJarForProguardLibraryJars whether to combine all library jars into a single jar
   *        file before processing with Proguard
   */
public static ProguardOutput createProguardAction(RuleContext ruleContext, FilesToRunProvider proguard, Artifact programJar, ImmutableList<Artifact> proguardSpecs, @Nullable Artifact proguardSeeds, @Nullable Artifact proguardUsage, @Nullable Artifact proguardMapping, Iterable<Artifact> libraryJars, Artifact proguardOutputJar, JavaSemantics semantics, @Nullable Integer optimizationPasses, @Nullable Artifact proguardOutputMap, boolean useSingleJarForProguardLibraryJars) throws InterruptedException {
    JavaOptimizationMode optMode = getJavaOptimizationMode(ruleContext);
    Preconditions.checkArgument(optMode != JavaOptimizationMode.NOOP);
    Preconditions.checkArgument(optMode != JavaOptimizationMode.LEGACY || !proguardSpecs.isEmpty());
    ProguardOutput output = getProguardOutputs(proguardOutputJar, proguardSeeds, proguardUsage, ruleContext, semantics, proguardOutputMap);
    if (useSingleJarForProguardLibraryJars && Iterables.size(libraryJars) > 1) {
        JavaTargetAttributes attributes = new JavaTargetAttributes.Builder(semantics).build();
        Artifact combinedLibraryJar = getProguardTempArtifact(ruleContext, optMode.name().toLowerCase(), "combined_library_jars.jar");
        new DeployArchiveBuilder(semantics, ruleContext).setOutputJar(combinedLibraryJar).setAttributes(attributes).addRuntimeJars(libraryJars).build();
        libraryJars = ImmutableList.of(combinedLibraryJar);
    }
    if (optimizationPasses == null) {
        // Run proguard as a single step.
        Builder builder = makeBuilder(proguard, programJar, proguardSpecs, proguardMapping, libraryJars, output.getOutputJar(), output.getMapping(), output.getProtoMapping(), output.getSeeds(), output.getUsage(), output.getConstantStringObfuscatedMapping(), output.getConfig()).setProgressMessage("Trimming binary with Proguard").addOutput(proguardOutputJar);
        ruleContext.registerAction(builder.build(ruleContext));
    } else {
        // Optimization passes have been specified, so run proguard in multiple phases.
        Artifact lastStageOutput = getProguardTempArtifact(ruleContext, optMode.name().toLowerCase(), "proguard_preoptimization.jar");
        ruleContext.registerAction(makeBuilder(proguard, programJar, proguardSpecs, proguardMapping, libraryJars, output.getOutputJar(), /* proguardOutputMap */
        null, /* proguardOutputProtoMap */
        null, // ProGuard only prints seeds during INITIAL and NORMAL runtypes.
        output.getSeeds(), /* proguardUsage */
        null, /* constantStringObfuscatedMapping */
        null, /* proguardConfigOutput */
        null).setProgressMessage("Trimming binary with Proguard: Verification/Shrinking Pass").addArgument("-runtype INITIAL").addArgument("-nextstageoutput").addOutputArgument(lastStageOutput).build(ruleContext));
        for (int i = 0; i < optimizationPasses; i++) {
            Artifact optimizationOutput = getProguardTempArtifact(ruleContext, optMode.name().toLowerCase(), "proguard_optimization_" + (i + 1) + ".jar");
            ruleContext.registerAction(makeBuilder(proguard, programJar, proguardSpecs, proguardMapping, libraryJars, output.getOutputJar(), /* proguardOutputMap */
            null, /* proguardOutputProtoMap */
            null, /* proguardSeeds */
            null, /* proguardUsage */
            null, /* constantStringObfuscatedMapping */
            null, /* proguardConfigOutput */
            null).setProgressMessage("Trimming binary with Proguard: Optimization Pass " + (i + 1)).addArgument("-runtype OPTIMIZATION").addArgument("-laststageoutput").addInputArgument(lastStageOutput).addArgument("-nextstageoutput").addOutputArgument(optimizationOutput).build(ruleContext));
            lastStageOutput = optimizationOutput;
        }
        Builder builder = makeBuilder(proguard, programJar, proguardSpecs, proguardMapping, libraryJars, output.getOutputJar(), output.getMapping(), output.getProtoMapping(), // runtype FINAL does not produce seeds.
        null, /* proguardSeeds */
        output.getUsage(), output.getConstantStringObfuscatedMapping(), output.getConfig()).setProgressMessage("Trimming binary with Proguard: Obfuscation and Final Output Pass").addArgument("-runtype FINAL").addArgument("-laststageoutput").addInputArgument(lastStageOutput).addOutput(proguardOutputJar);
        ruleContext.registerAction(builder.build(ruleContext));
    }
    return output;
}
Also used : JavaOptimizationMode(com.google.devtools.build.lib.rules.java.JavaConfiguration.JavaOptimizationMode) NestedSetBuilder(com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder) Builder(com.google.devtools.build.lib.analysis.actions.SpawnAction.Builder) Artifact(com.google.devtools.build.lib.actions.Artifact)

Example 5 with JavaOptimizationMode

use of com.google.devtools.build.lib.rules.java.JavaConfiguration.JavaOptimizationMode in project bazel by bazelbuild.

the class ProguardHelper method collectTransitiveProguardSpecs.

/**
   * Retrieves the full set of proguard specs that should be applied to this binary, including the
   * specs passed in, if Proguard should run on the given rule.  {@link #createProguardAction}
   * relies on this method returning an empty list if the given rule doesn't declare specs in
   * --java_optimization_mode=legacy.
   *
   * <p>If Proguard shouldn't be applied, or the legacy link mode is used and there are no
   * proguard_specs on this rule, an empty list will be returned, regardless of any given specs or
   * specs from dependencies.
   * {@link com.google.devtools.build.lib.rules.android.AndroidBinary#createAndroidBinary} relies on
   * that behavior.
   */
public static ImmutableList<Artifact> collectTransitiveProguardSpecs(RuleContext ruleContext, Iterable<Artifact> specsToInclude) {
    JavaOptimizationMode optMode = getJavaOptimizationMode(ruleContext);
    if (optMode == JavaOptimizationMode.NOOP) {
        return ImmutableList.of();
    }
    ImmutableList<Artifact> proguardSpecs = ruleContext.attributes().has(PROGUARD_SPECS, BuildType.LABEL_LIST) ? ruleContext.getPrerequisiteArtifacts(PROGUARD_SPECS, Mode.TARGET).list() : ImmutableList.<Artifact>of();
    if (optMode == JavaOptimizationMode.LEGACY && proguardSpecs.isEmpty()) {
        return ImmutableList.of();
    }
    // TODO(bazel-team): In modes except LEGACY verify that proguard specs don't include -dont...
    // flags since those flags would override the desired optMode
    ImmutableSortedSet.Builder<Artifact> builder = ImmutableSortedSet.orderedBy(Artifact.EXEC_PATH_COMPARATOR).addAll(proguardSpecs).addAll(specsToInclude).addAll(ruleContext.getPrerequisiteArtifacts(":extra_proguard_specs", Mode.TARGET).list());
    for (ProguardSpecProvider dep : ruleContext.getPrerequisites("deps", Mode.TARGET, ProguardSpecProvider.class)) {
        builder.addAll(dep.getTransitiveProguardSpecs());
    }
    // Generate and include implicit Proguard spec for requested mode.
    if (!optMode.getImplicitProguardDirectives().isEmpty()) {
        Artifact implicitDirectives = getProguardConfigArtifact(ruleContext, optMode.name().toLowerCase());
        ruleContext.registerAction(FileWriteAction.create(ruleContext, implicitDirectives, optMode.getImplicitProguardDirectives(), /*makeExecutable=*/
        false));
        builder.add(implicitDirectives);
    }
    return builder.build().asList();
}
Also used : JavaOptimizationMode(com.google.devtools.build.lib.rules.java.JavaConfiguration.JavaOptimizationMode) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) Artifact(com.google.devtools.build.lib.actions.Artifact)

Aggregations

Artifact (com.google.devtools.build.lib.actions.Artifact)5 JavaOptimizationMode (com.google.devtools.build.lib.rules.java.JavaConfiguration.JavaOptimizationMode)5 ImmutableSortedSet (com.google.common.collect.ImmutableSortedSet)1 FailAction (com.google.devtools.build.lib.actions.FailAction)1 FilesToRunProvider (com.google.devtools.build.lib.analysis.FilesToRunProvider)1 Builder (com.google.devtools.build.lib.analysis.actions.SpawnAction.Builder)1 NestedSetBuilder (com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder)1 ProguardOutput (com.google.devtools.build.lib.rules.java.ProguardHelper.ProguardOutput)1 Nullable (javax.annotation.Nullable)1