aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/build_defs
diff options
context:
space:
mode:
authorGravatar Erik Kuefler <ekuefler@gmail.com>2015-08-12 15:02:06 +0000
committerGravatar Kristina Chodorow <kchodorow@google.com>2015-08-12 15:23:58 +0000
commitf4b07dbdb4bf5d4ae2b743d50f8e43ff49770987 (patch)
tree705757261d37095ecdf88217d33da6c37d4cf222 /tools/build_defs
parenta55377241e2ec9f5280744c61302a7eda07d282c (diff)
Add Skylark rules for groovy_library and groovy_binary.
This is a slightly cleaned-up version of the rules from https://github.com/ekuefler/bazel-groovy, which my team has been using for a few months. I'll add the test rules from there separately. -- Change-Id: I07b5270bfdada5244ed82dee617b4997855747d8 Reviewed-on: https://bazel-review.googlesource.com/#/c/1590/ MOS_MIGRATED_REVID=100476149
Diffstat (limited to 'tools/build_defs')
-rw-r--r--tools/build_defs/groovy/README.md269
-rw-r--r--tools/build_defs/groovy/groovy.BUILD5
-rw-r--r--tools/build_defs/groovy/groovy.WORKSPACE11
-rw-r--r--tools/build_defs/groovy/groovy.bzl157
4 files changed, 442 insertions, 0 deletions
diff --git a/tools/build_defs/groovy/README.md b/tools/build_defs/groovy/README.md
new file mode 100644
index 0000000000..e881a15510
--- /dev/null
+++ b/tools/build_defs/groovy/README.md
@@ -0,0 +1,269 @@
+# Groovy Rules for Bazel
+
+## Overview
+
+These build rules are used for building [Groovy](http://www.groovy-lang.org/)
+projects with Bazel. Groovy libraries may interoperate with and depend on Java
+libraries and vice-versa.
+
+* [Setup](#setup)
+* [Basic Example](#basic-example)
+* [Build Rule Reference](#reference)
+ * [`groovy_library`](#groovy_library)
+ * [`groovy_and_java_library`](#groovy_and_java_library)
+ * [`groovy_binary`](#groovy_binary)
+
+<a name="setup"></a>
+## Setup
+
+To be able to use the Groovy rules, you must make the Groovy binaries available
+to Bazel. The easiest way to do so is by copying the content of
+`groovy.WORKSPACE` to your workspace file and putting `groovy.BUILD` at the root
+or your workspace.
+
+<a name="basic-example"></a>
+## Basic Example
+
+Suppose you have the following directory structure for a simple Groovy and Java
+application:
+
+```
+[workspace]/
+ WORKSPACE
+ app/
+ BUILD
+ GroovyApp.groovy
+ lib/
+ BUILD
+ GroovyLib.groovy
+ JavaLib.java
+```
+
+Then, to build the code under lib/, your `lib/BUILD` can look like this:
+
+```python
+load("/tools/build_rules/groovy/groovy", "groovy_library")
+
+groovy_library(
+ name = "groovylib",
+ srcs = glob(["*.groovy"]),
+ deps = [
+ ":javalib",
+ ],
+)
+
+java_library(
+ name = "javalib",
+ srcs = glob(["*.java"]),
+)
+```
+
+For simplicity, you can combine Groovy and Java sources into a single library
+using `groovy_and_java_library`. Note that this allows the Groovy code to
+reference the Java code, but not vice-versa. Your `lib/BUILD` file would then
+look like this:
+
+```python
+load("/tools/build_rules/groovy/groovy", "groovy_and_java_library")
+
+groovy_and_java_library(
+ name = "lib",
+ srcs = glob(["*.groovy", "*.java"]),
+)
+```
+
+Finally, you can define a binary using `groovy_binary` as follows:
+
+```python
+load("/tools/build_rules/groovy/groovy", "groovy_binary")
+
+groovy_binary(
+ name = "GroovyApp",
+ srcs = glob(["*.groovy"]),
+ main_class = "GroovyApp",
+ deps = [
+ "//lib",
+ ],
+)
+```
+
+You can then build the application with `bazel build //app:GroovyApp` and run it
+with `bazel run //app:GroovyApp`.
+
+<a name="reference"></a>
+## Build Rule Reference [reference]
+
+<a name="groovy_library"></a>
+### `groovy_library`
+
+`groovy_library(name, srcs, deps, **kwargs)`
+
+<table>
+ <thead>
+ <tr>
+ <th>Attribute</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code>name</code></td>
+ <td>
+ <code>Name, required</code>
+ <p>A unique name for this rule.</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>srcs</code></td>
+ <td>
+ <code>List of labels, required</code>
+ <p>List of .groovy source files used to build the library.</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>deps</code></td>
+ <td>
+ <code>List of labels or .jar files, optional</code>
+ <p>
+ List of other libraries to be included on the compile-time classpath
+ when building this library.
+ </p>
+ <p>
+ These can be either other `groovy_library` targets, `java_library`
+ targets, `groovy_and_java_library` targets, or raw .jar files.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>**kwargs</code></td>
+ <td>
+ <code>see <a href="http://bazel.io/docs/build-encyclopedia.html#java_import">java_binary</a></code>
+ <p>
+ The other arguments of this rule will be passed to the `java_import`
+ that wraps the groovy library.
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<a name="groovy_and_java_library">
+### `groovy_and_java_library`
+
+`groovy_and_java_library(name, srcs, deps, **kwargs)`
+
+<table>
+ <thead>
+ <tr>
+ <th>Attribute</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code>name</code></td>
+ <td>
+ <code>Name, required</code>
+ <p>A unique name for this rule.</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>srcs</code></td>
+ <td>
+ <code>List of labels, required</code>
+ <p>List of .groovy and .java source files used to build the library.</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>deps</code></td>
+ <td>
+ <code>List of labels or .jar files, optional</code>
+ <p>
+ List of other libraries to be included on the compile-time classpath
+ when building this library.
+ </p>
+ <p>
+ These can be either other `groovy_library` targets, `java_library`
+ targets, `groovy_and_java_library` targets, or raw .jar files.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>**kwargs</code></td>
+ <td>
+ <code>see <a href="http://bazel.io/docs/build-encyclopedia.html#java_import">java_binary</a></code>
+ <p>
+ The other arguments of this rule will be passed to the `java_import`
+ that wraps the groovy library.
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<a name="groovy_binary"></a>
+### `groovy_binary`
+
+`groovy_binary(name, main_class, srcs, deps, **kwargs)`
+
+<table>
+ <thead>
+ <tr>
+ <th>Attribute</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code>name</code></td>
+ <td>
+ <code>Name, required</code>
+ <p>A unique name for this rule.</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>main_class</code></td>
+ <td>
+ <code>String, required</code>
+ <p>
+ The name of either a class containing a `main` method or a Groovy
+ script file to use as an entry point (see
+ <a href="http://www.groovy-lang.org/structure.html#_scripts_versus_classes">
+ here</a> for more details on scripts vs. classes).
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>srcs</code></td>
+ <td>
+ <code>List of labels, required</code>
+ <p>List of .groovy source files used to build the application.</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>deps</code></td>
+ <td>
+ <code>List of labels or .jar files, optional</code>
+ <p>
+ List of other libraries to be included on both the compile-time
+ classpath when building this application and the runtime classpath
+ when executing it.
+ </p>
+ <p>
+ These can be `groovy_library` targets, `java_library` targets,
+ `groovy_and_java_library` targets, or raw .jar files.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>**kwargs</code></td>
+ <td>
+ <code>see <a href="http://bazel.io/docs/build-encyclopedia.html#java_binary">java_binary</a></code>
+ <p>
+ The other arguments of this rule will be passed to the `java_binary`
+ underlying the `groovy_binary`.
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
diff --git a/tools/build_defs/groovy/groovy.BUILD b/tools/build_defs/groovy/groovy.BUILD
new file mode 100644
index 0000000000..05f378467c
--- /dev/null
+++ b/tools/build_defs/groovy/groovy.BUILD
@@ -0,0 +1,5 @@
+filegroup(
+ name = "groovyc",
+ srcs = ["groovy-2.4.4/bin/groovyc"],
+ visibility = ["//visibility:public"],
+)
diff --git a/tools/build_defs/groovy/groovy.WORKSPACE b/tools/build_defs/groovy/groovy.WORKSPACE
new file mode 100644
index 0000000000..8fce2532b1
--- /dev/null
+++ b/tools/build_defs/groovy/groovy.WORKSPACE
@@ -0,0 +1,11 @@
+new_http_archive(
+ name = "groovy",
+ url = "http://dl.bintray.com/groovy/maven/apache-groovy-binary-2.4.4.zip",
+ sha256 = "a7cc1e5315a14ea38db1b2b9ce0792e35174161141a6a3e2ef49b7b2788c258c",
+ build_file = "tools/build_defs/groovy/groovy.BUILD",
+)
+
+bind(
+ name = "groovy/groovyc",
+ actual = "@groovy//:groovyc",
+)
diff --git a/tools/build_defs/groovy/groovy.bzl b/tools/build_defs/groovy/groovy.bzl
new file mode 100644
index 0000000000..f435890e9d
--- /dev/null
+++ b/tools/build_defs/groovy/groovy.bzl
@@ -0,0 +1,157 @@
+# Copyright 2015 Erik Kuefler. 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.
+
+
+def _groovy_jar_impl(ctx):
+ """Creates a .jar file from Groovy sources. Users should rely on
+ groovy_library instead of using this rule directly.
+ """
+ class_jar = ctx.outputs.class_jar
+ build_output = class_jar.path + ".build_output"
+
+ # Extract all transitive dependencies
+ # TODO(bazel-team): get transitive dependencies from other groovy libraries
+ all_deps = set(ctx.files.deps)
+ for this_dep in ctx.attr.deps:
+ if hasattr(this_dep, "java"):
+ all_deps += this_dep.java.transitive_runtime_deps
+
+ # Compile all files in srcs with groovyc
+ cmd = "rm -rf %s; mkdir -p %s\n" % (build_output, build_output)
+ cmd += "%s -cp %s -d %s %s\n" % (
+ ctx.file._groovyc.short_path,
+ ":".join([dep.path for dep in all_deps]),
+ build_output,
+ " ".join([src.path for src in ctx.files.srcs]),
+ )
+
+ # Jar them together to produce a single output. To make this work we have
+ # to cd into the output directory, run find to locate all of the generated
+ # class files, pass the result to cut to trim the leading "./", then pass
+ # the resulting paths to the zipper.
+ cmd += "root=`pwd`\n"
+ cmd += "cd %s; $root/%s c ../%s `find . -name '*.class' | cut -c 3-`\n" % (
+ build_output,
+ ctx.executable._jar.path,
+ class_jar.basename,
+ )
+ cmd += "cd $root\n"
+
+ # Clean up temporary output
+ cmd += "rm -rf %s" % build_output
+
+ # Execute the command
+ ctx.action(
+ inputs = ctx.files.srcs + ctx.files.deps + ctx.files._jar,
+ outputs = [class_jar],
+ mnemonic = "Groovyc",
+ command = "set -e;" + cmd,
+ use_default_shell_env = True,
+ )
+
+_groovy_jar = rule(
+ implementation = _groovy_jar_impl,
+ attrs = {
+ "srcs": attr.label_list(
+ mandatory=False,
+ allow_files=FileType([".groovy"])),
+ "deps": attr.label_list(
+ mandatory=False,
+ allow_files=FileType([".jar"])),
+ "_groovyc": attr.label(
+ default=Label("//external:groovy/groovyc"),
+ single_file=True),
+ "_jar": attr.label(
+ default=Label("//third_party/ijar:zipper"),
+ executable=True,
+ single_file=True),
+ },
+ outputs = {
+ "class_jar": "lib%{name}.jar",
+ },
+)
+
+def groovy_library(name, srcs=[], deps=[], **kwargs):
+ """Rule analagous to java_library that accepts .groovy sources instead of
+ .java sources. The result is wrapped in a java_import so that java rules may
+ depend on it.
+ """
+ _groovy_jar(
+ name = name + "-impl",
+ srcs = srcs,
+ deps = deps,
+ )
+ native.java_import(
+ name = name,
+ jars = [name + "-impl"],
+ **kwargs
+ )
+
+
+def groovy_and_java_library(name, srcs=[], deps=[], **kwargs):
+ """Accepts .groovy and .java srcs to create a groovy_library and a
+ java_library. The groovy_library will depend on the java_library, so the
+ Groovy code may reference the Java code but not vice-versa.
+ """
+ groovy_deps = deps
+ jars = []
+
+ # Put all .java sources in a java_library
+ java_srcs = [src for src in srcs if src.endswith(".java")]
+ if java_srcs:
+ native.java_library(
+ name = name + "-java",
+ srcs = java_srcs,
+ deps = deps,
+ )
+ groovy_deps += [name + "-java"]
+ jars += ["lib" + name + "-java.jar"]
+
+ # Put all .groovy sources in a groovy_library depending on the java_library
+ groovy_srcs = [src for src in srcs if src.endswith(".groovy")]
+ if groovy_srcs:
+ _groovy_jar(
+ name = name + "-groovy",
+ srcs = groovy_srcs,
+ deps = groovy_deps,
+ )
+ jars += ["lib" + name + "-groovy.jar"]
+
+ # Output a java_import combining both libraries
+ native.java_import(
+ name = name,
+ jars = jars,
+ **kwargs
+ )
+
+
+def groovy_binary(name, main_class, srcs=[], deps=[], **kwargs):
+ """Rule analagous to java_binary that accepts .groovy sources instead of .java
+ sources.
+ """
+ all_deps = deps
+ if srcs:
+ groovy_library(
+ name = name + "-lib",
+ srcs = srcs,
+ deps = deps,
+ )
+ all_deps += [name + "-lib"]
+
+ native.java_binary(
+ name = name,
+ main_class = main_class,
+ runtime_deps = all_deps,
+ **kwargs
+ )