aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools
diff options
context:
space:
mode:
authorGravatar Laurent Le Brun <laurentlb@google.com>2015-09-01 14:11:59 +0000
committerGravatar John Field <jfield@google.com>2015-09-02 00:58:08 +0000
commit868d40c777d4365e7a639e849253f6056af43128 (patch)
treec965f3a0a9b1816e6c7d251b1663765684cfca78 /tools
parent410405e1d5f20a3b0bc1d9f994a921a33d91c2b6 (diff)
Add Scala library rule.
-- MOS_MIGRATED_REVID=102038201
Diffstat (limited to 'tools')
-rw-r--r--tools/build_defs/scala/README.md17
-rw-r--r--tools/build_defs/scala/scala.bzl97
-rw-r--r--tools/build_defs/scala/test/BUILD28
-rw-r--r--tools/build_defs/scala/test/Hello.java22
-rw-r--r--tools/build_defs/scala/test/HelloLib.scala7
-rw-r--r--tools/build_defs/scala/test/OtherLib.scala8
6 files changed, 179 insertions, 0 deletions
diff --git a/tools/build_defs/scala/README.md b/tools/build_defs/scala/README.md
new file mode 100644
index 0000000000..be8ede2e1d
--- /dev/null
+++ b/tools/build_defs/scala/README.md
@@ -0,0 +1,17 @@
+# Scala Rules for Bazel
+
+## Overview
+
+This rule is used for building [Scala][scala] projects with Bazel. There is
+currently only one rule, `scala_library`. More features will be added in the
+future, e.g. `scala_binary`, `scala_test`, etc.
+
+[scala]: http://www.scala-lang.org/
+
+### `scala_library`
+
+`scala_library` generates a `.jar` file from `.scala` source files. In order to
+make a java rule use this jar file, use the `java_import` rule.
+
+The current implementation assumes that the files `/usr/bin/scalac` and
+`/usr/share/java/scala-library.jar` exist.
diff --git a/tools/build_defs/scala/scala.bzl b/tools/build_defs/scala/scala.bzl
new file mode 100644
index 0000000000..d923094714
--- /dev/null
+++ b/tools/build_defs/scala/scala.bzl
@@ -0,0 +1,97 @@
+# Copyright 2015 Google Inc. 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.
+
+"""Rules for supporting the Scala language."""
+
+
+_scala_filetype = FileType([".scala"])
+
+# TODO(bazel-team): Add local_repository to properly declare the dependency.
+_scala_library_path = "/usr/share/java/scala-library.jar"
+_scalac_path = "/usr/bin/scalac"
+
+def _compile(ctx, jars):
+ cmd = """
+mkdir -p {out}_tmp
+{scalac} -classpath "{jars}" $@ -d {out}_tmp &&
+# Make jar file deterministic by setting the timestamp of files
+touch -t 198001010000 $(find .)
+jar cmf {manifest} {out} -C {out}_tmp .
+"""
+ cmd = cmd.format(
+ scalac=_scalac_path,
+ out=ctx.outputs.jar.path,
+ manifest=ctx.outputs.manifest.path,
+ jars=':'.join([j.path for j in jars]))
+
+ ctx.action(
+ inputs=list(jars) + ctx.files.srcs + [ctx.outputs.manifest],
+ outputs=[ctx.outputs.jar],
+ command=cmd,
+ progress_message="scala %s" % ctx.label,
+ arguments=[f.path for f in ctx.files.srcs])
+
+
+def _write_manifest(ctx):
+ manifest = """Main-Class: {main_class}
+Class-Path: {cp}
+"""
+ manifest = manifest.format(
+ main_class=ctx.attr.main_class,
+ cp=_scala_library_path)
+
+ ctx.file_action(
+ output = ctx.outputs.manifest,
+ content = manifest)
+
+
+def _collect_jars(ctx):
+ jars = set()
+ for target in ctx.attr.deps:
+ if hasattr(target, "jar_files"):
+ jars += target.jar_files
+ elif hasattr(target, "java"):
+ jars += target.java.transitive_runtime_deps
+ return jars
+
+
+def _scala_library_impl(ctx):
+ jars = _collect_jars(ctx)
+ _write_manifest(ctx)
+ _compile(ctx, jars)
+
+ all_jars = jars + [ctx.outputs.jar]
+
+ runfiles = ctx.runfiles(
+ files = list(all_jars) + [ctx.outputs.jar],
+ collect_data = True)
+ return struct(
+ files=all_jars,
+ jar_files=all_jars,
+ runfiles=runfiles)
+
+
+scala_library = rule(
+ implementation=_scala_library_impl,
+ attrs={
+ "main_class": attr.string(mandatory=True),
+ "srcs": attr.label_list(allow_files=_scala_filetype),
+ "deps": attr.label_list(),
+ "data": attr.label_list(allow_files=True, cfg=DATA_CFG),
+ },
+ outputs={
+ "jar": "%{name}_deploy.jar",
+ "manifest": "%{name}_MANIFEST.MF",
+ },
+)
diff --git a/tools/build_defs/scala/test/BUILD b/tools/build_defs/scala/test/BUILD
new file mode 100644
index 0000000000..971819b055
--- /dev/null
+++ b/tools/build_defs/scala/test/BUILD
@@ -0,0 +1,28 @@
+load("/tools/build_defs/scala/scala", "scala_library")
+
+java_binary(
+ name = "Hello",
+ srcs = ["Hello.java"],
+ main_class = "scala.test.Hello",
+ deps = [":lib_import"],
+)
+
+# TODO(bazel-team): Allow java rules to depend directly on scala_library.
+# For now, we have to use a java_import proxy.
+java_import(
+ name = "lib_import",
+ jars = [":HelloLib"],
+)
+
+scala_library(
+ name = "HelloLib",
+ srcs = ["HelloLib.scala"],
+ main_class = "scala.test.HelloLib",
+ deps = ["OtherLib"],
+)
+
+scala_library(
+ name = "OtherLib",
+ srcs = ["OtherLib.scala"],
+ main_class = "scala.test.OtherLib",
+)
diff --git a/tools/build_defs/scala/test/Hello.java b/tools/build_defs/scala/test/Hello.java
new file mode 100644
index 0000000000..55baa73868
--- /dev/null
+++ b/tools/build_defs/scala/test/Hello.java
@@ -0,0 +1,22 @@
+// Copyright 2015 Google Inc. 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 scala.test;
+
+/** Example class */
+public class Hello {
+ public static void main(String[] args) {
+ HelloLib.printMessage("Hello");
+ }
+}
diff --git a/tools/build_defs/scala/test/HelloLib.scala b/tools/build_defs/scala/test/HelloLib.scala
new file mode 100644
index 0000000000..afd4ec2f07
--- /dev/null
+++ b/tools/build_defs/scala/test/HelloLib.scala
@@ -0,0 +1,7 @@
+package scala.test
+
+object HelloLib {
+ def printMessage(arg: String) {
+ println(arg + " " + OtherLib.getMessage())
+ }
+}
diff --git a/tools/build_defs/scala/test/OtherLib.scala b/tools/build_defs/scala/test/OtherLib.scala
new file mode 100644
index 0000000000..f696242d40
--- /dev/null
+++ b/tools/build_defs/scala/test/OtherLib.scala
@@ -0,0 +1,8 @@
+package scala.test
+
+// It is just to show how a Scala library can depend on another Scala library.
+object OtherLib {
+ def getMessage(): String = {
+ return "scala!"
+ }
+}