aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar lberki <lberki@google.com>2017-07-11 11:39:59 +0200
committerGravatar László Csomor <laszlocsomor@google.com>2017-07-11 11:42:00 +0200
commit4634ff903d1aaec59d545bd28a139d6cf2b95e0d (patch)
tree8e39ea1f67cae6e27c9c53fa657b1af707789c5c
parente0ea0f6c3f0121ca5e5ac54b0a6ffabc53efbc67 (diff)
Make information about the Java runtime in use available in Skylark using a dependency.
RELNOTES: None. PiperOrigin-RevId: 161504700
-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.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeProvider.java67
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaRuntimeSuite.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java34
-rw-r--r--src/test/java/com/google/devtools/build/lib/rules/java/JavaRuntimeProviderTest.java48
-rw-r--r--src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java25
7 files changed, 173 insertions, 15 deletions
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 6a5c3d2b1d..f021bec6c8 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
@@ -519,8 +519,8 @@ public class BazelRuleClassProvider {
builder.addRuleDefinition(new AndroidDeviceRule());
builder.addSkylarkAccessibleTopLevels("android_common", new AndroidSkylarkCommon());
- builder.addSkylarkAccessibleTopLevels(
- "java_common", new JavaSkylarkCommon(BazelJavaSemantics.INSTANCE));
+ builder.addSkylarkAccessibleTopLevels("java_common", new JavaSkylarkCommon(
+ BazelJavaSemantics.INSTANCE, builder.getToolsRepository()));
builder.addSkylarkAccessibleTopLevels("java_proto_common", JavaProtoSkylarkCommon.class);
try {
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 73f9f09c51..108edd055c 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
@@ -73,6 +73,9 @@ public class JavaRuntime implements RuleConfiguredTargetFactory {
.addTransitiveArtifacts(filesToBuild)
.build();
+ JavaRuntimeProvider javaRuntime = new JavaRuntimeProvider(
+ filesToBuild, javaHome, javaBinaryExecPath, javaBinaryRunfilesPath);
+
MakeVariableProvider makeVariableProvider = new MakeVariableProvider(ImmutableMap.of(
"JAVA", javaBinaryExecPath.getPathString(),
"JAVABASE", javaHome.getPathString()));
@@ -80,8 +83,8 @@ public class JavaRuntime implements RuleConfiguredTargetFactory {
return new RuleConfiguredTargetBuilder(ruleContext)
.addProvider(RunfilesProvider.class, RunfilesProvider.simple(runfiles))
.setFilesToBuild(filesToBuild)
- .addProvider(JavaRuntimeProvider.class, JavaRuntimeProvider.create(
- filesToBuild, javaHome, javaBinaryExecPath, javaBinaryRunfilesPath))
+ .addProvider(JavaRuntimeProvider.class, javaRuntime)
+ .addNativeDeclaredProvider(javaRuntime)
.addProvider(MiddlemanProvider.class, new MiddlemanProvider(middleman))
.addProvider(makeVariableProvider)
.addNativeDeclaredProvider(makeVariableProvider)
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
index 7df3efcb7a..33235a3d04 100644
--- 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
@@ -14,34 +14,81 @@
package com.google.devtools.build.lib.rules.java;
-import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableMap;
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;
+import com.google.devtools.build.lib.packages.ClassObjectConstructor;
+import com.google.devtools.build.lib.packages.NativeClassObjectConstructor;
+import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.vfs.PathFragment;
/** Information about the Java runtime used by the <code>java_*</code> rules. */
-@AutoValue
+@SkylarkModule(
+ name = "JavaRuntimeInfo",
+ doc = "Information about the Java runtime being used."
+)
@Immutable
-public abstract class JavaRuntimeProvider implements TransitiveInfoProvider {
+public class JavaRuntimeProvider extends SkylarkClassObject
+ implements TransitiveInfoProvider {
+ public static final String SKYLARK_NAME = "JavaRuntimeInfo";
- public static JavaRuntimeProvider create(
+ public static final ClassObjectConstructor SKYLARK_CONSTRUCTOR =
+ new NativeClassObjectConstructor(JavaToolchainProvider.class, SKYLARK_NAME) {};
+
+ private final NestedSet<Artifact> javaBaseInputs;
+ private final PathFragment javaHome;
+ private final PathFragment javaBinaryExecPath;
+ private final PathFragment javaBinaryRunfilesPath;
+
+ public JavaRuntimeProvider(
NestedSet<Artifact> javaBaseInputs, PathFragment javaHome,
PathFragment javaBinaryExecPath, PathFragment javaBinaryRunfilesPath) {
- return new AutoValue_JavaRuntimeProvider(
- javaBaseInputs, javaHome, javaBinaryExecPath, javaBinaryRunfilesPath);
+ super(SKYLARK_CONSTRUCTOR, ImmutableMap.<String, Object>of());
+ this.javaBaseInputs = javaBaseInputs;
+ this.javaHome = javaHome;
+ this.javaBinaryExecPath = javaBinaryExecPath;
+ this.javaBinaryRunfilesPath = javaBinaryRunfilesPath;
}
/** All input artifacts in the javabase. */
- public abstract NestedSet<Artifact> javaBaseInputs();
+ public NestedSet<Artifact> javaBaseInputs() {
+ return javaBaseInputs;
+ }
/** The root directory of the Java installation. */
- public abstract PathFragment javaHome();
+ public PathFragment javaHome() {
+ return javaHome;
+ }
+ @SkylarkCallable(
+ name = "java_executable_exec_path",
+ doc = "Returns the execpath of the Java executable.",
+ structField = true
+ )
/** The execpath of the Java binary. */
- public abstract PathFragment javaBinaryExecPath();
+ public PathFragment javaBinaryExecPath() {
+ return javaBinaryExecPath;
+ }
/** The runfiles path of the Java binary. */
- public abstract PathFragment javaBinaryRunfilesPath();
+ public PathFragment javaBinaryRunfilesPath() {
+ return javaBinaryRunfilesPath;
+ }
+
+ // Not all of JavaRuntimeProvider is exposed to Skylark, which makes implementing deep equality
+ // impossible: if Java-only parts are considered, the behavior is surprising in Skylark, if they
+ // are not, the behavior is surprising in Java. Thus, object identity it is.
+ @Override
+ public boolean equals(Object other) {
+ return other == this;
+ }
+
+ @Override
+ public int hashCode() {
+ return System.identityHashCode(this);
+ }
}
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
index dfde6fd937..cab0d2c481 100644
--- 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
@@ -35,14 +35,17 @@ public class JavaRuntimeSuite implements RuleConfiguredTargetFactory {
if (runtime == null) {
runtime = ruleContext.getPrerequisite("default", Mode.TARGET);
}
+
if (runtime == null) {
ruleContext.throwWithRuleError(
"could not resolve runtime for cpu " + ruleContext.getConfiguration().getCpu());
}
MakeVariableProvider makeVariableProvider = runtime.getProvider(MakeVariableProvider.class);
+
return new RuleConfiguredTargetBuilder(ruleContext)
.addProvider(JavaRuntimeProvider.class, runtime.getProvider(JavaRuntimeProvider.class))
+ .addNativeDeclaredProvider(runtime.get(JavaRuntimeProvider.SKYLARK_CONSTRUCTOR.getKey()))
.addProvider(RunfilesProvider.class, runtime.getProvider(RunfilesProvider.class))
.addProvider(MiddlemanProvider.class, runtime.getProvider(MiddlemanProvider.class))
.addProvider(makeVariableProvider)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
index 7ac14a5c4e..4d3359161c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSkylarkCommon.java
@@ -16,6 +16,7 @@ package com.google.devtools.build.lib.rules.java;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.MiddlemanProvider;
import com.google.devtools.build.lib.analysis.RuleContext;
@@ -24,7 +25,10 @@ import com.google.devtools.build.lib.analysis.config.BuildConfiguration.StrictDe
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
+import com.google.devtools.build.lib.packages.Attribute;
+import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.ClassObjectConstructor;
+import com.google.devtools.build.lib.rules.SkylarkAttr;
import com.google.devtools.build.lib.rules.SkylarkRuleContext;
import com.google.devtools.build.lib.rules.java.proto.StrictDepsUtils;
import com.google.devtools.build.lib.skylarkinterface.Param;
@@ -40,9 +44,11 @@ import java.util.List;
@SkylarkModule(name = "java_common", doc = "Utilities for Java compilation support in Skylark.")
public class JavaSkylarkCommon {
private final JavaSemantics javaSemantics;
+ private final String toolsRepository;
- public JavaSkylarkCommon(JavaSemantics javaSemantics) {
+ public JavaSkylarkCommon(JavaSemantics javaSemantics, String toolsrepository) {
this.javaSemantics = javaSemantics;
+ this.toolsRepository = toolsrepository;
}
@SkylarkCallable(
@@ -452,4 +458,30 @@ public class JavaSkylarkCommon {
+ " Only OFF and ERROR values are accepted.");
}
}
+
+ @SkylarkCallable(
+ name = JavaRuntimeProvider.SKYLARK_NAME,
+ doc = "The key used to retrieve the provider that contains information about the Java "
+ + "runtime being used.",
+ structField = true
+ )
+ public static ClassObjectConstructor getJavaRuntimeProvider() {
+ return JavaRuntimeProvider.SKYLARK_CONSTRUCTOR;
+ }
+
+ @SkylarkCallable(
+ name = "java_runtime_attr",
+ doc = "A value that, when passed as a value in the attribute dictionary of a rule "
+ + "definition, will yield a dependency that describes the current Java runtime in use.",
+ documented = false,
+ structField = true
+ )
+ public SkylarkAttr.Descriptor getJvmAttribute() {
+ ConfiguredRuleClassProvider.Builder env = new ConfiguredRuleClassProvider.Builder();
+ env.setToolsRepository(toolsRepository);
+ return new SkylarkAttr.Descriptor(
+ "java_runtime_attr",
+ new Attribute.Builder<>("", BuildType.LABEL)
+ .value(JavaSemantics.jvmAttribute(env)));
+ }
}
diff --git a/src/test/java/com/google/devtools/build/lib/rules/java/JavaRuntimeProviderTest.java b/src/test/java/com/google/devtools/build/lib/rules/java/JavaRuntimeProviderTest.java
new file mode 100644
index 0000000000..750390dd5d
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/rules/java/JavaRuntimeProviderTest.java
@@ -0,0 +1,48 @@
+// 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.common.testing.EqualsTester;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.collect.nestedset.Order;
+import com.google.devtools.build.lib.vfs.PathFragment;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Unit tests for {@code JavaRuntimeProvider}
+ */
+@RunWith(JUnit4.class)
+public class JavaRuntimeProviderTest {
+ @Test
+ public void equalityIsObjectIdentity() {
+ JavaRuntimeProvider a = new JavaRuntimeProvider(
+ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
+ PathFragment.create(""),
+ PathFragment.create(""),
+ PathFragment.create(""));
+ JavaRuntimeProvider b = new JavaRuntimeProvider(
+ NestedSetBuilder.emptySet(Order.STABLE_ORDER),
+ PathFragment.create(""),
+ PathFragment.create(""),
+ PathFragment.create(""));
+
+ new EqualsTester()
+ .addEqualityGroup(a)
+ .addEqualityGroup(b)
+ .testEquals();
+ }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java b/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java
index f594ca2cfd..b16dd4e24e 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/java/JavaSkylarkApiTest.java
@@ -28,6 +28,7 @@ import com.google.devtools.build.lib.packages.SkylarkClassObjectConstructor.Skyl
import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider.OutputJar;
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
+import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
@@ -43,6 +44,30 @@ import org.junit.runners.JUnit4;
public class JavaSkylarkApiTest extends BuildViewTestCase {
@Test
+ public void testJavaRuntimeProvider() throws Exception {
+ scratch.file("a/BUILD",
+ "load(':rule.bzl', 'jrule')",
+ "java_runtime(name='jvm', srcs=[], java_home='/foo/bar/')",
+ "java_runtime_suite(name='suite', default=':jvm')",
+ "jrule(name='r')");
+
+ scratch.file(
+ "a/rule.bzl",
+ "def _impl(ctx):",
+ " provider = ctx.attr._java_runtime[java_common.JavaRuntimeInfo]",
+ " return struct(",
+ " java_executable = provider.java_executable_exec_path,",
+ ")",
+ "jrule = rule(_impl, attrs = { '_java_runtime': java_common.java_runtime_attr})");
+
+ useConfiguration("--javabase=//a:suite");
+ ConfiguredTarget ct = getConfiguredTarget("//a:r");
+ @SuppressWarnings("unchecked") PathFragment javaExecutable =
+ (PathFragment) ct.get("java_executable");
+ assertThat(javaExecutable.getPathString()).startsWith("/foo/bar/bin/java");
+ }
+
+ @Test
public void testExposesJavaSkylarkApiProvider() throws Exception {
scratch.file(
"java/test/BUILD",