Skip to content

Support empty srcs #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 24, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bazel-*
71 changes: 58 additions & 13 deletions scala/scala.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,40 @@ def _adjust_resources_path(path):
return dir_1 + dir_2, rel_path
return "", path

def _build_nosrc_jar(ctx, buildijar):
res_cmd = ""
for f in ctx.files.resources:
c_dir, res_path = _adjust_resources_path(f.path)
change_dir = "-C " + c_dir if c_dir else ""
res_cmd = "\n{jar} uf {out} " + change_dir + " " + res_path
ijar_cmd = ""
if buildijar:
ijar_cmd = "\ncp {out} {ijar_out}".format(
out=ctx.outputs.jar.path,
ijar_out=ctx.outputs.ijar.path)
cmd = """
set -e
# Make jar file deterministic by setting the timestamp of files
touch -t 198001010000 {manifest}
{jar} cmf {manifest} {out}
""" + ijar_cmd + res_cmd
cmd = cmd.format(
out=ctx.outputs.jar.path,
manifest=ctx.outputs.manifest.path,
jar=ctx.file._jar.path)
outs = [ctx.outputs.jar]
if buildijar:
outs.extend([ctx.outputs.ijar])
ctx.action(
inputs=
ctx.files.resources +
ctx.files._jdk +
[ctx.outputs.manifest, ctx.file._jar],
outputs=outs,
command=cmd,
progress_message="scala %s" % ctx.label,
arguments=[])

def _compile(ctx, jars, buildijar):
res_cmd = ""
for f in ctx.files.resources:
Expand Down Expand Up @@ -71,6 +105,21 @@ touch -t 198001010000 {manifest}
progress_message="scala %s" % ctx.label,
arguments=[f.path for f in ctx.files.srcs])

def _compile_or_empty(ctx, jars, buildijar):
if len(ctx.files.srcs) == 0:
_build_nosrc_jar(ctx, buildijar)
# no need to build ijar when empty
return struct(ijar=ctx.outputs.jar, class_jar=ctx.outputs.jar)
else:
_compile(ctx, jars, buildijar)
ijar = None
if buildijar:
ijar = ctx.outputs.ijar
else:
# macro code needs to be available at compile-time, so set ijar == jar
ijar = ctx.outputs.jar
return struct(ijar=ijar, class_jar=ctx.outputs.jar)

def _write_manifest(ctx):
# TODO(bazel-team): I don't think this classpath is what you want
manifest = "Class-Path: %s\n" % ctx.file._scalalib.path
Expand Down Expand Up @@ -142,24 +191,22 @@ def _collect_jars(targets):
compile_jars += target.files
return struct(compiletime = compile_jars, runtime = runtime_jars)

def _lib(ctx, use_ijar):
def _lib(ctx, non_macro_lib):
jars = _collect_jars(ctx.attr.deps)
(cjars, rjars) = (jars.compiletime, jars.runtime)
_write_manifest(ctx)
_compile(ctx, cjars, use_ijar)
outputs = _compile_or_empty(ctx, cjars, non_macro_lib)

rjars += [ctx.outputs.jar]
rjars += _collect_jars(ctx.attr.runtime_deps).runtime

ijar = None
if use_ijar:
ijar = ctx.outputs.ijar
else:
# macro code needs to be available at compile-time, so set ijar == jar
ijar = ctx.outputs.jar
if not non_macro_lib:
# macros need the scala reflect jar
cjars += [ctx.file._scalareflect]
rjars += [ctx.file._scalareflect]

texp = _collect_jars(ctx.attr.exports)
scalaattr = struct(outputs = struct(ijar=ijar, class_jar=ctx.outputs.jar),
scalaattr = struct(outputs = outputs,
transitive_runtime_deps = rjars,
transitive_compile_exports = texp.compiletime,
transitive_runtime_exports = texp.runtime
Expand All @@ -180,7 +227,7 @@ def _scala_macro_library_impl(ctx):
# Common code shared by all scala binary implementations.
def _scala_binary_common(ctx, cjars, rjars):
_write_manifest(ctx)
_compile(ctx, cjars, False) # no need to build an ijar for an executable
_compile_or_empty(ctx, cjars, False) # no need to build an ijar for an executable

runfiles = ctx.runfiles(
files = list(rjars) + [ctx.outputs.executable] + [ctx.file._java] + ctx.files._jdk,
Expand Down Expand Up @@ -221,8 +268,7 @@ _implicit_deps = {
# Common attributes reused across multiple rules.
_common_attrs = {
"srcs": attr.label_list(
allow_files=_scala_filetype,
non_empty=True),
allow_files=_scala_filetype),
"deps": attr.label_list(),
"runtime_deps": attr.label_list(),
"data": attr.label_list(allow_files=True, cfg=DATA_CFG),
Expand All @@ -249,7 +295,6 @@ scala_macro_library = rule(
attrs={
"main_class": attr.string(),
"exports": attr.label_list(allow_files=False),
"_scala-reflect": attr.label(default=Label("@scala//:lib/scala-reflect.jar"), single_file=True, allow_files=True),
} + _implicit_deps + _common_attrs,
outputs={
"jar": "%{name}_deploy.jar",
Expand Down
18 changes: 15 additions & 3 deletions test/BUILD
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("//scala:scala.bzl", "scala_binary", "scala_library", "scala_test")
load("//scala:scala.bzl", "scala_binary", "scala_library", "scala_test", "scala_macro_library")

# The examples below show how to combine Scala and Java rules.
# ScalaBinary is the Scala equivalent of JavaBinary.
Expand All @@ -21,7 +21,7 @@ scala_binary(
name = "ScalaBinary",
srcs = ["ScalaBinary.scala"],
main_class = "scala.test.ScalaBinary",
deps = [":HelloLib"],
deps = [":HelloLib", ":MacroTest"],
)

scala_library(
Expand All @@ -30,6 +30,7 @@ scala_library(
deps = [
"OtherJavaLib",
"OtherLib",
"MacroTest"
],
)

Expand All @@ -49,7 +50,13 @@ scala_test(
scala_library(
name = "OtherLib",
srcs = ["OtherLib.scala"],
exports = ["Exported"], # test of exported target
exports = ["ExportOnly"], # test of exported target
)

# Test of library without src
scala_library(
name = "ExportOnly",
exports = [ "Exported" ],
)

scala_library(
Expand All @@ -58,6 +65,11 @@ scala_library(
runtime_deps = ["Runtime"],
)

scala_macro_library(
name = "MacroTest",
srcs = ["MacroTest.scala"]
)

scala_library(
name = "Runtime",
srcs = ["Runtime.scala"],
Expand Down
1 change: 1 addition & 0 deletions test/HelloLib.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package scala.test

object HelloLib {
def printMessage(arg: String) {
MacroTest.hello(arg == "yo")
println(getOtherLibMessage(arg))
println(getOtherJavaLibMessage(arg))
println(Exported.message)
Expand Down
17 changes: 17 additions & 0 deletions test/MacroTest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package scala.test

import language.experimental.macros

import reflect.macros.Context

object MacroTest {
def hello(param: Any): Unit = macro hello_impl

def hello_impl(c: Context)(param: c.Expr[Any]): c.Expr[Unit] = {
import c.universe._
val paramRep = show(param.tree)
val paramRepTree = Literal(Constant(paramRep))
val paramRepExpr = c.Expr[String](paramRepTree)
reify { println(paramRepExpr.splice + " = " + param.splice) }
}
}
1 change: 1 addition & 0 deletions test/ScalaBinary.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package scala.test

object ScalaBinary {
def main(args: Array[String]) {
println(MacroTest.hello(1 + 2))
HelloLib.printMessage("Hello");
}
}