From b1e9884f6ad7cca5205d113d8a6f21d61fdea986 Mon Sep 17 00:00:00 2001 From: ilist Date: Tue, 15 Dec 2020 03:27:45 -0800 Subject: [PATCH] Set Java toolchain source and target version from target Java runtime. This functionality will enable Bazel to automatically produce target code for detected version of local JDK. PiperOrigin-RevId: 347577778 --- .../build/lib/rules/java/JavaRuntime.java | 2 ++ .../build/lib/rules/java/JavaRuntimeInfo.java | 10 ++++++++++ .../build/lib/rules/java/JavaRuntimeRule.java | 4 ++++ .../build/lib/rules/java/JavaToolchain.java | 10 +++++++++- .../lib/rules/java/JavaToolchainRule.java | 18 ++++++++++++++++++ .../lib/rules/java/JavaRuntimeInfoTest.java | 2 ++ 6 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntime.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntime.java index 05445435fe68cf..982278179298a7 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntime.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntime.java @@ -33,6 +33,7 @@ import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; +import com.google.devtools.build.lib.packages.Type; import com.google.devtools.build.lib.util.OsUtils; import com.google.devtools.build.lib.vfs.PathFragment; @@ -102,6 +103,7 @@ public ConfiguredTarget create(RuleContext ruleContext) JavaRuntimeInfo javaRuntime = JavaRuntimeInfo.create( + ruleContext.attributes().get("version", Type.STRING), filesToBuild, middleman, javaHome, diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeInfo.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeInfo.java index d57e291f1f31ea..ec8535bc1be8e2 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeInfo.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeInfo.java @@ -38,6 +38,7 @@ public final class JavaRuntimeInfo extends ToolchainInfo implements JavaRuntimeInfoApi { public static JavaRuntimeInfo create( + String version, NestedSet javaBaseInputs, NestedSet javaBaseInputsMiddleman, PathFragment javaHome, @@ -45,6 +46,7 @@ public static JavaRuntimeInfo create( PathFragment javaHomeRunfilesPath, PathFragment javaBinaryRunfilesPath) { return new JavaRuntimeInfo( + version, javaBaseInputs, javaBaseInputsMiddleman, javaHome, @@ -81,6 +83,7 @@ private static JavaRuntimeInfo from(RuleContext ruleContext, String attributeNam return (JavaRuntimeInfo) prerequisite.get(ToolchainInfo.PROVIDER); } + private final String version; private final NestedSet javaBaseInputs; private final NestedSet javaBaseInputsMiddleman; private final PathFragment javaHome; @@ -91,6 +94,7 @@ private static JavaRuntimeInfo from(RuleContext ruleContext, String attributeNam @AutoCodec.Instantiator @VisibleForSerialization JavaRuntimeInfo( + String version, NestedSet javaBaseInputs, NestedSet javaBaseInputsMiddleman, PathFragment javaHome, @@ -98,6 +102,7 @@ private static JavaRuntimeInfo from(RuleContext ruleContext, String attributeNam PathFragment javaHomeRunfilesPath, PathFragment javaBinaryRunfilesPath) { super(ImmutableMap.of(), Location.BUILTIN); + this.version = version; this.javaBaseInputs = javaBaseInputs; this.javaBaseInputsMiddleman = javaBaseInputsMiddleman; this.javaHome = javaHome; @@ -106,6 +111,11 @@ private static JavaRuntimeInfo from(RuleContext ruleContext, String attributeNam this.javaBinaryRunfilesPath = javaBinaryRunfilesPath; } + /** Release version of the Java runtiem. */ + public String version() { + return version; + } + /** All input artifacts in the javabase. */ public NestedSet javaBaseInputs() { return javaBaseInputs; diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeRule.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeRule.java index 52971e8471b587..2ef05006ccc2b1 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeRule.java @@ -52,6 +52,10 @@ public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) path. In that case, the srcs and java attributes must be empty. */ .add(attr("java_home", STRING)) + /* + The release version of JDK, this is for example 8 for JDK 1.8.0, and 11 for JDK 11. + */ + .add(attr("version", STRING)) .add(attr("output_licenses", LICENSE)) .build(); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchain.java index d262f1c191fb9c..81a31a59143d3d 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchain.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchain.java @@ -149,10 +149,18 @@ public ConfiguredTarget create(RuleContext ruleContext) private ImmutableList getJavacOpts(RuleContext ruleContext) { ImmutableList.Builder javacopts = ImmutableList.builder(); String source = ruleContext.attributes().get("source_version", Type.STRING); + String target = ruleContext.attributes().get("target_version", Type.STRING); + if (!ruleContext.attributes().isAttributeValueExplicitlySpecified("source_version") + && !ruleContext.attributes().isAttributeValueExplicitlySpecified("target_version")) { + JavaRuntimeInfo targetJavaRuntime = + (JavaRuntimeInfo) + ruleContext.getPrerequisite("$target_java_runtime", JavaRuntimeInfo.PROVIDER); + source = targetJavaRuntime.version(); + target = source; + } if (!isNullOrEmpty(source)) { javacopts.add("-source").add(source); } - String target = ruleContext.attributes().get("target_version", Type.STRING); if (!isNullOrEmpty(target)) { javacopts.add("-target").add(target); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainRule.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainRule.java index a2311331dbf6c5..2a14fa583ec52a 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaToolchainRule.java @@ -30,6 +30,8 @@ import com.google.devtools.build.lib.analysis.config.ExecutionTransitionFactory; import com.google.devtools.build.lib.analysis.config.transitions.NoTransition; import com.google.devtools.build.lib.analysis.platform.ToolchainInfo; +import com.google.devtools.build.lib.packages.Attribute; +import com.google.devtools.build.lib.packages.AttributeMap; import com.google.devtools.build.lib.packages.RuleClass; import com.google.devtools.build.lib.util.FileTypeSet; import java.util.List; @@ -295,6 +297,22 @@ The Java target version (e.g., '6' or '7'). It specifies for which Java runtime .mandatoryProviders(ToolchainInfo.PROVIDER.id()) .allowedFileTypes(FileTypeSet.ANY_FILE) .useOutputLicenses()) + .add( + attr("$target_java_runtime", LABEL) + .value( + new Attribute.ComputedDefault("source_version", "target_version") { + @Override + public Object getDefault(AttributeMap rule) { + if (!rule.isAttributeValueExplicitlySpecified("source_version") + && !rule.isAttributeValueExplicitlySpecified("target_version")) { + return JavaSemantics.jvmAttribute(env); + } + return null; + } + }) + .mandatoryProviders(ToolchainInfo.PROVIDER.id()) + .allowedFileTypes(FileTypeSet.ANY_FILE) + .useOutputLicenses()) /* Label of the Android Lint runner, if any. */ diff --git a/src/test/java/com/google/devtools/build/lib/rules/java/JavaRuntimeInfoTest.java b/src/test/java/com/google/devtools/build/lib/rules/java/JavaRuntimeInfoTest.java index eecd0669c8a89e..1adfc21afd1722 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/java/JavaRuntimeInfoTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/java/JavaRuntimeInfoTest.java @@ -29,6 +29,7 @@ public class JavaRuntimeInfoTest { public void equalityIsObjectIdentity() { JavaRuntimeInfo a = JavaRuntimeInfo.create( + /* version = */ "", NestedSetBuilder.emptySet(Order.STABLE_ORDER), NestedSetBuilder.emptySet(Order.STABLE_ORDER), PathFragment.create(""), @@ -37,6 +38,7 @@ public void equalityIsObjectIdentity() { PathFragment.create("")); JavaRuntimeInfo b = JavaRuntimeInfo.create( + /* version = */ "", NestedSetBuilder.emptySet(Order.STABLE_ORDER), NestedSetBuilder.emptySet(Order.STABLE_ORDER), PathFragment.create(""),