aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Liam Miller-Cushon <cushon@google.com>2017-01-16 23:06:11 +0000
committerGravatar Vladimir Moskva <vladmos@google.com>2017-01-17 12:15:29 +0000
commita27a5aa83696200e22a459950081eb443e01e427 (patch)
tree19d1f57e42a46cbe5af5105ac547e4a1ab1c9e85
parent14d952232b0284fecc898a6d5cb1bf3467aff493 (diff)
Initial implementation of java_runtime and java_runtime_suite
These rules can be used to configure JDKs, as an alternative to the filegroups and filegroups-of-filegroups used currently. -- PiperOrigin-RevId: 144655277 MOS_MIGRATED_REVID=144655277
-rw-r--r--src/main/java/com/google/devtools/build/lib/BUILD5
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntime.java47
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeProvider.java34
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeRule.java71
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeSuite.java46
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeSuiteRule.java80
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JvmConfigurationLoader.java228
8 files changed, 436 insertions, 79 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index 9f9708107d..b174fd42f3 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -753,8 +753,12 @@ java_library(
"rules/java/JavaPlugin.java",
"rules/java/JavaPrimaryClassProvider.java",
"rules/java/JavaProvider.java",
+ "rules/java/JavaRuntime.java",
"rules/java/JavaRuntimeClasspathProvider.java",
"rules/java/JavaRuntimeJarProvider.java",
+ "rules/java/JavaRuntimeRule.java",
+ "rules/java/JavaRuntimeSuite.java",
+ "rules/java/JavaRuntimeSuiteRule.java",
"rules/java/JavaSkylarkCommon.java",
"rules/java/JavaSourceInfoProvider.java",
"rules/java/JavaToolchain.java",
@@ -842,6 +846,7 @@ java_library(
"rules/java/JavaPluginInfoProvider.java",
"rules/java/JavaRuleOutputJarsProvider.java",
"rules/java/JavaRunfilesProvider.java",
+ "rules/java/JavaRuntimeProvider.java",
"rules/java/JavaSemantics.java",
"rules/java/JavaSkylarkApiProvider.java",
"rules/java/JavaSourceJarsProvider.java",
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
index 362fd2709b..87dc0d5504 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
@@ -116,6 +116,8 @@ import com.google.devtools.build.lib.rules.genquery.GenQueryRule;
import com.google.devtools.build.lib.rules.java.JavaConfigurationLoader;
import com.google.devtools.build.lib.rules.java.JavaImportBaseRule;
import com.google.devtools.build.lib.rules.java.JavaOptions;
+import com.google.devtools.build.lib.rules.java.JavaRuntimeRule;
+import com.google.devtools.build.lib.rules.java.JavaRuntimeSuiteRule;
import com.google.devtools.build.lib.rules.java.JavaSkylarkCommon;
import com.google.devtools.build.lib.rules.java.JavaToolchainRule;
import com.google.devtools.build.lib.rules.java.JvmConfigurationLoader;
@@ -484,6 +486,8 @@ public class BazelRuleClassProvider {
builder.addRuleDefinition(new BazelJavaTestRule());
builder.addRuleDefinition(new BazelJavaPluginRule());
builder.addRuleDefinition(new JavaToolchainRule());
+ builder.addRuleDefinition(new JavaRuntimeRule());
+ builder.addRuleDefinition(new JavaRuntimeSuiteRule());
builder.addRuleDefinition(new ExtraActionRule());
builder.addRuleDefinition(new ActionListenerRule());
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
new file mode 100644
index 0000000000..e8ff3a8105
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntime.java
@@ -0,0 +1,47 @@
+// Copyright 2017 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 com.google.devtools.build.lib.actions.Actions;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.CompilationHelper;
+import com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.analysis.MiddlemanProvider;
+import com.google.devtools.build.lib.analysis.PrerequisiteArtifacts;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
+import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.analysis.RunfilesProvider;
+import com.google.devtools.build.lib.collect.nestedset.NestedSet;
+import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
+
+/** Implementation for the {@code java_runtime} rule. */
+public class JavaRuntime implements RuleConfiguredTargetFactory {
+ @Override
+ public ConfiguredTarget create(RuleContext ruleContext)
+ throws InterruptedException, RuleErrorException {
+ NestedSet<Artifact> filesToBuild =
+ PrerequisiteArtifacts.nestedSet(ruleContext, "srcs", Mode.TARGET);
+ NestedSet<Artifact> middleman =
+ CompilationHelper.getAggregatingMiddleman(
+ ruleContext, Actions.escapeLabel(ruleContext.getLabel()), filesToBuild);
+ return new RuleConfiguredTargetBuilder(ruleContext)
+ .addProvider(RunfilesProvider.class, RunfilesProvider.EMPTY)
+ .setFilesToBuild(filesToBuild)
+ .addProvider(JavaRuntimeProvider.class, JavaRuntimeProvider.create(filesToBuild))
+ .addProvider(MiddlemanProvider.class, new MiddlemanProvider(middleman))
+ .build();
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeProvider.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeProvider.java
new file mode 100644
index 0000000000..7ecd58c35e
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeProvider.java
@@ -0,0 +1,34 @@
+// Copyright 2017 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 com.google.auto.value.AutoValue;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
+import com.google.devtools.build.lib.collect.nestedset.NestedSet;
+import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+
+/** Information about the Java runtime used by the <code>java_*</code> rules. */
+@AutoValue
+@Immutable
+public abstract class JavaRuntimeProvider implements TransitiveInfoProvider {
+
+ public static JavaRuntimeProvider create(NestedSet<Artifact> javaBaseInputs) {
+ return new AutoValue_JavaRuntimeProvider(javaBaseInputs);
+ }
+
+ /** All input artifacts in the javabase. */
+ public abstract NestedSet<Artifact> 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
new file mode 100644
index 0000000000..ef526863f8
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeRule.java
@@ -0,0 +1,71 @@
+// Copyright 2017 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.devtools.build.lib.packages.Attribute.attr;
+import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
+import static com.google.devtools.build.lib.packages.BuildType.LICENSE;
+import static com.google.devtools.build.lib.syntax.Type.STRING;
+
+import com.google.devtools.build.lib.analysis.BaseRuleClasses;
+import com.google.devtools.build.lib.analysis.RuleDefinition;
+import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
+import com.google.devtools.build.lib.packages.RuleClass;
+import com.google.devtools.build.lib.packages.RuleClass.Builder;
+import com.google.devtools.build.lib.util.FileTypeSet;
+
+/** Rule definition for {@code java_runtime} */
+public final class JavaRuntimeRule implements RuleDefinition {
+ @Override
+ public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
+ return builder
+ /* <!-- #BLAZE_RULE(java_runtime).ATTRIBUTE(srcs) -->
+ All files in the runtime.
+ <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
+ .add(attr("srcs", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE).mandatory())
+ /* <!-- #BLAZE_RULE(java_runtime).ATTRIBUTE(java_home) -->
+ The relative path to the root of the runtime.
+ <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
+ .add(attr("java_home", STRING))
+ .add(attr("output_licenses", LICENSE))
+ .build();
+ }
+
+ @Override
+ public Metadata getMetadata() {
+ return RuleDefinition.Metadata.builder()
+ .name("java_runtime")
+ .ancestors(BaseRuleClasses.BaseRule.class)
+ .factoryClass(JavaRuntime.class)
+ .build();
+ }
+}
+/*<!-- #BLAZE_RULE (NAME = java_runtime, TYPE = OTHER, FAMILY = Java) -->
+
+<p>
+Specifies the configuration for a Java runtime.
+</p>
+
+<h4 id="java_runtime">Example:</h4>
+
+<pre class="code">
+java_runtime(
+ name = "jdk-9-ea+153",
+ srcs = glob(["jdk9-ea+153/**"]),
+ java_home = "jdk9-ea+153",
+)
+</pre>
+
+<!-- #END_BLAZE_RULE -->*/
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeSuite.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeSuite.java
new file mode 100644
index 0000000000..2a42e5e560
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeSuite.java
@@ -0,0 +1,46 @@
+// Copyright 2017 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 com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.analysis.FileProvider;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
+import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.analysis.RunfilesProvider;
+import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
+import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
+
+/** Implementation for the {@code java_runtime_suite} rule. */
+public class JavaRuntimeSuite implements RuleConfiguredTargetFactory {
+ @Override
+ public ConfiguredTarget create(RuleContext ruleContext)
+ throws InterruptedException, RuleErrorException {
+ TransitiveInfoCollection runtime =
+ ruleContext.getPrerequisiteMap("runtimes").get(ruleContext.getConfiguration().getCpu());
+ if (runtime == null) {
+ runtime = ruleContext.getPrerequisite("default", Mode.TARGET);
+ }
+ if (runtime == null) {
+ ruleContext.throwWithRuleError(
+ "could not resolve runtime for cpu " + ruleContext.getConfiguration().getCpu());
+ }
+ return new RuleConfiguredTargetBuilder(ruleContext)
+ .addProvider(JavaRuntimeProvider.class, runtime.getProvider(JavaRuntimeProvider.class))
+ .addProvider(RunfilesProvider.class, runtime.getProvider(RunfilesProvider.class))
+ .setFilesToBuild(runtime.getProvider(FileProvider.class).getFilesToBuild())
+ .build();
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeSuiteRule.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeSuiteRule.java
new file mode 100644
index 0000000000..63aa2683ed
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeSuiteRule.java
@@ -0,0 +1,80 @@
+// Copyright 2017 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.devtools.build.lib.packages.Attribute.attr;
+import static com.google.devtools.build.lib.packages.BuildType.LICENSE;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.analysis.BaseRuleClasses;
+import com.google.devtools.build.lib.analysis.RuleDefinition;
+import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
+import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
+import com.google.devtools.build.lib.packages.BuildType;
+import com.google.devtools.build.lib.packages.RuleClass;
+import com.google.devtools.build.lib.packages.RuleClass.Builder;
+import com.google.devtools.build.lib.util.FileTypeSet;
+
+/** Rule definition for {@code java_runtime_suite} */
+public final class JavaRuntimeSuiteRule implements RuleDefinition {
+ @Override
+ public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
+ return builder
+ /* <!-- #BLAZE_RULE(java_runtime_suite).ATTRIBUTE(runtimes) -->
+ A map from each supported architecture to the corresponding <code>java_runtime</code>.
+ <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
+ .add(attr("runtimes", BuildType.LABEL_DICT_UNARY))
+ /* <!-- #BLAZE_RULE(java_runtime_suite).ATTRIBUTE(default) -->
+ A map from each supported architecture to the corresponding <code>java_runtime</code>.
+ <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
+ .add(
+ attr("default", BuildType.LABEL)
+ .mandatoryNativeProviders(
+ ImmutableList.<Class<? extends TransitiveInfoProvider>>of(
+ JavaRuntimeProvider.class))
+ .allowedFileTypes(FileTypeSet.NO_FILE))
+ .add(attr("output_licenses", LICENSE))
+ .build();
+ }
+
+ @Override
+ public Metadata getMetadata() {
+ return RuleDefinition.Metadata.builder()
+ .name("java_runtime_suite")
+ .ancestors(BaseRuleClasses.BaseRule.class)
+ .factoryClass(JavaRuntimeSuite.class)
+ .build();
+ }
+}
+/*<!-- #BLAZE_RULE (NAME = java_runtime_suite, TYPE = OTHER, FAMILY = Java) -->
+
+<p>
+Specifies the configuration for the Java runtimes for each architecture.
+</p>
+
+<h4 id="java_runtime_suite">Example:</h4>
+
+<pre class="code">
+java_runtime_suite(
+ name = "jdk9",
+ runtimes = {
+ "k8": ":jdk9-k8",
+ "ppc": ":jdk9-ppc",
+ "arm": ":jdk9-arm",
+ },
+)
+</pre>
+
+<!-- #END_BLAZE_RULE -->*/
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JvmConfigurationLoader.java b/src/main/java/com/google/devtools/build/lib/rules/java/JvmConfigurationLoader.java
index 942d2abca3..a8fb7aaad4 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JvmConfigurationLoader.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JvmConfigurationLoader.java
@@ -29,23 +29,30 @@ import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
+import com.google.devtools.build.lib.packages.NoSuchThingException;
import com.google.devtools.build.lib.packages.RawAttributeMapper;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.List;
+import java.util.Map;
import javax.annotation.Nullable;
/**
* A provider to load jvm configurations from the package path.
*
- * <p>If the given {@code javaHome} is a label, i.e. starts with {@code "//"},
- * then the loader will look at the target it refers to. If the target is a
- * filegroup, then the loader will look in it's srcs for a filegroup that ends
- * with {@code -<cpu>}. It will use that filegroup to construct the actual
- * {@link Jvm} instance, using the filegroups {@code path} attribute to
- * construct the new {@code javaHome} path.
+ * <p>If the given {@code javaHome} is a label, i.e. starts with {@code "//"}, then the loader will
+ * look at the target it refers to.
+ *
+ * <ul>
+ * <li>If the target is a {@code java_runtime_suite}, the loader will select the runtime from the
+ * entry in {@code java_runtime_suite.runtimes} for {@code cpu}.
+ * <li>If the target is a filegroup, then the loader will look in it's srcs for a filegroup that
+ * ends with {@code -<cpu>}. It will use that filegroup to construct the actual {@link Jvm}
+ * instance, using the filegroups {@code path} attribute to construct the new {@code javaHome}
+ * path.
+ * </ul>
*
* <p>The loader also supports legacy mode, where the JVM can be defined with an abolute path.
*/
@@ -90,88 +97,151 @@ public final class JvmConfigurationLoader implements ConfigurationFragmentFactor
return null;
}
Target javaHomeTarget = lookup.getTarget(label);
- if ((javaHomeTarget instanceof Rule) &&
- "filegroup".equals(((Rule) javaHomeTarget).getRuleClass())) {
- RawAttributeMapper javaHomeAttributes = RawAttributeMapper.of((Rule) javaHomeTarget);
- if (javaHomeAttributes.isConfigurable("srcs", BuildType.LABEL_LIST)) {
- throw new InvalidConfigurationException("\"srcs\" in " + javaHome
- + " is configurable. JAVABASE targets don't support configurable attributes");
- }
- List<Label> labels = javaHomeAttributes.get("srcs", BuildType.LABEL_LIST);
- Label selectedJvmLabel = null;
- Label defaultJvmLabel = null;
- for (Label jvmLabel : labels) {
- if (jvmLabel.getName().endsWith("-" + cpu)) {
- selectedJvmLabel = jvmLabel;
- break;
- }
- // When we open sourced Bazel, we used the string "default" to look up the Jvm. This is
- // incorrect for cross-platform builds, but works for purely local builds. Since we now
- // need to support cross-platform builds, we need to look up by the CPU, rather than the
- // hard-coded string "default". However, for local builds the Jvm is setup with a
- // mechanism where we don't currently have access to the CPU value (this is different from
- // C++, where we infer the CPU from the local machine). As such, looking up only by CPU
- // breaks builds that currently work, unless we add alias rules for all possible CPU
- // values (but this is problematic if Bazel is ported to more platforms). For now, we're
- // working around this problem by falling back to -default if we can't find a Jvm ending
- // in -<cpu>. This is backwards compatible, but still allows cross-platform builds. In the
- // medium term, we should rewrite Jvm setup to use a Skylark remote repository, and also
- // remove the necessity of having a Jvm defined for all platforms even if there's no Java
- // code.
- if (jvmLabel.getName().endsWith("-default")) {
- defaultJvmLabel = jvmLabel;
- }
- }
- if (selectedJvmLabel == null) {
- selectedJvmLabel = defaultJvmLabel;
- }
- if (selectedJvmLabel != null) {
- selectedJvmLabel = RedirectChaser.followRedirects(
- lookup, selectedJvmLabel, "Architecture-specific JDK");
- if (selectedJvmLabel == null) {
- return null;
- }
-
- Target jvmTarget = lookup.getTarget(selectedJvmLabel);
- if (jvmTarget == null) {
- return null;
- }
-
- PathFragment javaHomePath;
- if (jvmTarget.getLabel().getPackageIdentifier().getRepository().isDefault()) {
- javaHomePath = selectedJvmLabel.getPackageFragment();
- } else {
- javaHomePath = jvmTarget.getLabel().getPackageIdentifier().getSourceRoot();
- }
-
- if ((jvmTarget instanceof Rule) &&
- "filegroup".equals(((Rule) jvmTarget).getRuleClass())) {
- RawAttributeMapper jvmTargetAttributes = RawAttributeMapper.of((Rule) jvmTarget);
- if (jvmTargetAttributes.isConfigurable("path", Type.STRING)) {
- throw new InvalidConfigurationException("\"path\" in " + jvmTarget
- + " is configurable. JVM targets don't support configurable attributes");
- }
- String path = jvmTargetAttributes.get("path", Type.STRING);
- if (path != null) {
- javaHomePath = javaHomePath.getRelative(path);
- }
- }
- return new Jvm(javaHomePath, selectedJvmLabel);
+ if (javaHomeTarget instanceof Rule) {
+ switch (((Rule) javaHomeTarget).getRuleClass()) {
+ case "filegroup":
+ return createFromFilegroup(lookup, javaHomeTarget, cpu);
+ case "java_runtime_suite":
+ return createFromRuntimeSuite(lookup, (Rule) javaHomeTarget, cpu);
+ default:
+ throw new InvalidConfigurationException(
+ "Unexpected javabase rule kind '" + ((Rule) javaHomeTarget).getRuleClass() + "'");
}
}
- throw new InvalidConfigurationException("No JVM target found under " + javaHome
- + " that would work for " + cpu);
- } catch (NoSuchPackageException | NoSuchTargetException e) {
+ throw new InvalidConfigurationException(
+ "No JVM target found under " + javaHome + " that would work for " + cpu);
+ } catch (NoSuchThingException e) {
lookup.getEventHandler().handle(Event.error(e.getMessage()));
throw new InvalidConfigurationException(e.getMessage(), e);
}
}
- private Jvm createLegacy(String javaHome)
+ private static Jvm createFromFilegroup(
+ ConfigurationEnvironment lookup, Target javaHomeTarget, String cpu)
+ throws InvalidConfigurationException, InterruptedException, NoSuchPackageException,
+ NoSuchTargetException {
+
+ RawAttributeMapper javaHomeAttributes = RawAttributeMapper.of((Rule) javaHomeTarget);
+ if (javaHomeAttributes.isConfigurable("srcs", BuildType.LABEL_LIST)) {
+ throw new InvalidConfigurationException(
+ String.format(
+ "\"srcs\" in %s is configurable. JAVABASE targets don't support configurable"
+ + " attributes",
+ javaHomeTarget));
+ }
+ List<Label> labels = javaHomeAttributes.get("srcs", BuildType.LABEL_LIST);
+ Label selectedJvmLabel = null;
+ Label defaultJvmLabel = null;
+ for (Label jvmLabel : labels) {
+ if (jvmLabel.getName().endsWith("-" + cpu)) {
+ selectedJvmLabel = jvmLabel;
+ break;
+ }
+ // When we open sourced Bazel, we used the string "default" to look up the Jvm. This is
+ // incorrect for cross-platform builds, but works for purely local builds. Since we now
+ // need to support cross-platform builds, we need to look up by the CPU, rather than the
+ // hard-coded string "default". However, for local builds the Jvm is setup with a
+ // mechanism where we don't currently have access to the CPU value (this is different from
+ // C++, where we infer the CPU from the local machine). As such, looking up only by CPU
+ // breaks builds that currently work, unless we add alias rules for all possible CPU
+ // values (but this is problematic if Bazel is ported to more platforms). For now, we're
+ // working around this problem by falling back to -default if we can't find a Jvm ending
+ // in -<cpu>. This is backwards compatible, but still allows cross-platform builds. In the
+ // medium term, we should rewrite Jvm setup to use a Skylark remote repository, and also
+ // remove the necessity of having a Jvm defined for all platforms even if there's no Java
+ // code.
+ if (jvmLabel.getName().endsWith("-default")) {
+ defaultJvmLabel = jvmLabel;
+ }
+ }
+ if (selectedJvmLabel == null) {
+ selectedJvmLabel = defaultJvmLabel;
+ }
+ if (selectedJvmLabel != null) {
+ selectedJvmLabel =
+ RedirectChaser.followRedirects(lookup, selectedJvmLabel, "Architecture-specific JDK");
+ if (selectedJvmLabel == null) {
+ return null;
+ }
+
+ Target jvmTarget = lookup.getTarget(selectedJvmLabel);
+
+ PathFragment javaHomePath = defaultJavaHome(jvmTarget.getLabel());
+
+ if ((jvmTarget instanceof Rule) && "filegroup".equals(((Rule) jvmTarget).getRuleClass())) {
+ RawAttributeMapper jvmTargetAttributes = RawAttributeMapper.of((Rule) jvmTarget);
+ if (jvmTargetAttributes.isConfigurable("path", Type.STRING)) {
+ throw new InvalidConfigurationException(
+ String.format(
+ "\"path\" in %s is configurable. JVM targets don't support configurable"
+ + " attributes",
+ jvmTarget));
+ }
+ String path = jvmTargetAttributes.get("path", Type.STRING);
+ if (path != null) {
+ javaHomePath = javaHomePath.getRelative(path);
+ }
+ }
+ return new Jvm(javaHomePath, selectedJvmLabel);
+ }
+ throw new InvalidConfigurationException(
+ String.format("No JVM target found under %s that would work for %s", javaHomeTarget, cpu));
+ }
+
+ // TODO(b/34175492): this is temporary until support for filegroup-based javabases is removed.
+ // Eventually the Jvm fragement will containg only the label of a java_runtime rule, and all of
+ // the configuration will be accessed using JavaRuntimeProvider.
+ private static Jvm createFromRuntimeSuite(
+ ConfigurationEnvironment lookup, Rule javaRuntimeSuite, String cpu)
+ throws InvalidConfigurationException, InterruptedException, NoSuchTargetException,
+ NoSuchPackageException {
+ Label javaRuntimeLabel = selectRuntime(javaRuntimeSuite, cpu);
+ Target javaRuntimeTarget = lookup.getTarget(javaRuntimeLabel);
+ if (javaRuntimeTarget == null) {
+ return null;
+ }
+ if (!(javaRuntimeTarget instanceof Rule)) {
+ throw new InvalidConfigurationException(
+ String.format("Invalid java_runtime '%s'", javaRuntimeLabel));
+ }
+ Rule javaRuntimeRule = (Rule) javaRuntimeTarget;
+ if (!javaRuntimeRule.getRuleClass().equals("java_runtime")) {
+ throw new InvalidConfigurationException(
+ String.format("Expected a java_runtime rule, was '%s'", javaRuntimeRule.getRuleClass()));
+ }
+ RawAttributeMapper attributes = RawAttributeMapper.of(javaRuntimeRule);
+ PathFragment javaHomePath = defaultJavaHome(javaRuntimeLabel);
+ if (attributes.isAttributeValueExplicitlySpecified("java_home")) {
+ javaHomePath = javaHomePath.getRelative(attributes.get("java_home", Type.STRING));
+ }
+ return new Jvm(javaHomePath, javaRuntimeLabel);
+ }
+
+ private static Label selectRuntime(Rule javaRuntimeSuite, String cpu)
throws InvalidConfigurationException {
+ RawAttributeMapper suiteAttributes = RawAttributeMapper.of(javaRuntimeSuite);
+ Map<String, Label> runtimes = suiteAttributes.get("runtimes", BuildType.LABEL_DICT_UNARY);
+ if (runtimes.containsKey(cpu)) {
+ return runtimes.get(cpu);
+ }
+ if (suiteAttributes.isAttributeValueExplicitlySpecified("default")) {
+ return suiteAttributes.get("default", BuildType.LABEL);
+ }
+ throw new InvalidConfigurationException(
+ "No JVM target found under " + javaRuntimeSuite + " that would work for " + cpu);
+ }
+
+ private static PathFragment defaultJavaHome(Label javaBase) {
+ if (javaBase.getPackageIdentifier().getRepository().isDefault()) {
+ return javaBase.getPackageFragment();
+ }
+ return javaBase.getPackageIdentifier().getSourceRoot();
+ }
+
+ private static Jvm createLegacy(String javaHome) throws InvalidConfigurationException {
if (!javaHome.startsWith("/")) {
- throw new InvalidConfigurationException("Illegal javabase value '" + javaHome +
- "', javabase must be an absolute path or label");
+ throw new InvalidConfigurationException(
+ "Illegal javabase value '" + javaHome + "', javabase must be an absolute path or label");
}
return new Jvm(new PathFragment(javaHome), null);
}