// Copyright 2014 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.java; import static com.google.common.base.Preconditions.checkArgument; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap.Builder; import com.google.devtools.build.lib.analysis.config.BuildConfiguration.Fragment; import com.google.devtools.build.lib.analysis.config.BuildConfiguration.StrictDepsMode; import com.google.devtools.build.lib.analysis.config.BuildOptions; import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.cmdline.LabelSyntaxException; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.events.Event; import com.google.devtools.build.lib.events.EventHandler; import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; import com.google.devtools.common.options.TriState; import java.util.List; /** * A java compiler configuration containing the flags required for compilation. */ @Immutable @SkylarkModule(name = "java", doc = "A java compiler configuration") public final class JavaConfiguration extends Fragment { /** * Values for the --experimental_java_classpath option */ public static enum JavaClasspathMode { /** Use full transitive classpaths, the default behavior. */ OFF, /** JavaBuilder computes the reduced classpath before invoking javac. */ JAVABUILDER, /** Blaze computes the reduced classpath before invoking JavaBuilder. */ BLAZE } /** * Values for the --java_optimization_mode option, which controls how Proguard is run over binary * and test targets. Note that for the moment this has no effect when building library targets. */ public static enum JavaOptimizationMode { /** Proguard is used iff top-level target has {@code proguard_specs} attribute. */ LEGACY, /** * No link-time optimizations are applied, regardless of the top-level target's attributes. In * practice this mode skips Proguard completely, rather than invoking Proguard as a no-op. */ NOOP("-dontshrink", "-dontoptimize", "-dontobfuscate"), /** * Symbols have different names except where configured not to rename. This mode is primarily * intended to aid in identifying missing configuration directives that prevent symbols accessed * reflectively etc. from being renamed or removed. */ RENAME("-dontshrink", "-dontoptimize"), /** * "Quickly" produce small binary typically without changing code structure. In practice this * mode removes unreachable code and uses short symbol names except where configured not to * rename or remove. This mode should build faster than {@link #OPTIMIZE_MINIFY} and may hence * be preferable during development. */ FAST_MINIFY("-dontoptimize"), /** * Produce fully optimized binary with short symbol names and unreachable code removed. Unlike * {@link #FAST_MINIFY}, this mode may apply code transformations, in addition to removing and * renaming code as the configuration allows, to produce a more compact binary. This mode * should be preferable for producing and testing release binaries. */ OPTIMIZE_MINIFY; private String proguardDirectives; private JavaOptimizationMode(String... donts) { StringBuilder proguardDirectives = new StringBuilder(); for (String dont : donts) { checkArgument(dont.startsWith("-dont"), "invalid Proguard directive: %s", dont); proguardDirectives.append(dont).append('\n'); } this.proguardDirectives = proguardDirectives.toString(); } /** * Returns additional Proguard directives necessary for this mode (can be empty). */ public String getImplicitProguardDirectives() { return proguardDirectives; } /** * Returns true if all affected targets should produce mappings from original to renamed symbol * names, regardless of the proguard_generate_mapping attribute. This should be the case for * all modes that force symbols to be renamed. By contrast, the {@link #NOOP} mode will never * produce a mapping file since no symbols are ever renamed. */ public boolean alwaysGenerateOutputMapping() { switch (this) { case LEGACY: case NOOP: return false; case RENAME: case FAST_MINIFY: case OPTIMIZE_MINIFY: return true; default: throw new AssertionError("Unexpected mode: " + this); } } } private final ImmutableList commandLineJavacFlags; private final Label javaLauncherLabel; private final Label javaBuilderTop; private final ImmutableList defaultJavaBuilderJvmOpts; private final Label javaLangtoolsJar; private final boolean useIjars; private final boolean generateJavaDeps; private final JavaClasspathMode experimentalJavaClasspath; private final ImmutableList javaWarns; private final ImmutableList defaultJvmFlags; private final ImmutableList checkedConstraints; private final StrictDepsMode strictJavaDeps; private final Label javacBootclasspath; private final Label javacExtdir; private final ImmutableList javacOpts; private final ImmutableList