Skip to content

scala_inlined_library #1753

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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 README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ This project defines core build rules for [Scala](https://www.scala-lang.org/) t

- [scala_library](./docs/scala_library.md)
- [scala_macro_library](./docs/scala_macro_library.md)
- [scala_inlined_library](./docs/scala_inlined_library.md)
- [scala_binary](./docs/scala_binary.md)
- [scala_test](./docs/scala_test.md)
- [scala_repl](./docs/scala_repl.md)
Expand Down
1 change: 1 addition & 0 deletions docs/customizable_phase.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ Currently phase architecture is used by 7 rules:

- scala_library
- scala_macro_library
- scala_inlined_library
- scala_library_for_plugin_bootstrapping
- scala_binary
- scala_test
Expand Down
177 changes: 177 additions & 0 deletions docs/scala_inline_library.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
# scala_inlined_library

```py
scala_inlined_library(
name,
srcs,
deps,
runtime_deps,
exports,
data,
main_class,
resources,
resource_strip_prefix,
scalacopts,
jvm_flags,
scalac_jvm_flags,
javac_jvm_flags,
unused_dependency_checker_mode
)
```

`scala_inlined_library` generates a `.jar` file from `.scala` source files. This rule
has the interface jar (`ijar`) functionality disabled.
This is to enable inlining the compiled code, when it is given as a dependency for another Scala target (`ijar`
does not contain an implementation, so it cannot be used for inlining).

In order to have a Java rule use this jar file, use the `java_import` rule.

<table class="table table-condensed table-bordered table-params">
<colgroup>
<col class="col-param" />
<col class="param-description" />
</colgroup>
<thead>
<tr>
<th colspan="2">Attributes</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>name</code></td>
<td>
<p><code>Name, required</code></p>
<p>A unique name for this target</p>
</td>
</tr>
<td><code>srcs</code></td>
<td>
<p><code>List of labels, required</code></p>
<p>List of Scala <code>.scala</code> source files used to build the
library. These may be .srcjar jar files that contain source code.</p>
</td>
</tr>
<tr>
<td><code>deps</code></td>
<td>
<p><code>List of labels, optional</code></p>
<p>List of other libraries to linked to this library target.
These must be jvm targets (scala_library, java_library, java_import, etc...)</p>
</td>
</tr>
<tr>
<td><code>runtime_deps</code></td>
<td>
<p><code>List of labels, optional</code></p>
<p>List of other libraries to put on the classpath only at runtime. This is rarely needed in Scala.
These must be jvm targets (scala_library, java_library, java_import, etc...)</p>
</td>
</tr>
<tr>
<td><code>exports</code></td>
<td>
<p><code>List of labels, optional</code></p>
<p>List of targets to add to the dependencies of those that depend on this target. Similar
to the `java_library` parameter of the same name. Use this sparingly as it weakens the
precision of the build graph.
These must be jvm targets (scala_library, java_library, java_import, etc...)</p>
</td>
</tr>
<tr>
<td><code>data</code></td>
<td>
<p><code>List of labels, optional</code></p>
<p>List of files needed by this rule at runtime.</p>
</td>
</tr>
<tr>
<td><code>main_class</code></td>
<td>
<p><code>String, optional</code></p>
<p>Name of class with main() method to use as an entry point</p>
<p>
The value of this attribute is a class name, not a source file. The
class must be available at runtime: it may be compiled by this rule
(from <code>srcs</code>) or provided by direct or transitive
dependencies (through <code>deps</code>). If the class is unavailable,
the binary will fail at runtime; there is no build-time check.
</p>
</td>
</tr>
<tr>
<td><code>resources</code></td>
<td>
<p><code>List of labels; optional</code></p>
<p>A list of data files to be included in the JAR.</p>
</td>
</tr>
<tr>
<td><code>resource_strip_prefix</code></td>
<td>
<p><code>String; optional</code></p>
<p>
The path prefix to strip from Java resources. If specified,
this path prefix is stripped from every file in the `resources` attribute.
It is an error for a resource file not to be under this directory.
</p>
</td>
</tr>
<tr>
<td><code>scalacopts</code></td>
<td>
<p><code>List of strings; optional</code></p>
<p>
Extra compiler options for this library to be passed to scalac. Subject to
<a href="https://bazel.build/reference/be/make-variables.html">Make variable
substitution</a> and
<a href="https://bazel.build/reference/be/common-definitions.html#sh-tokenization">Bourne shell tokenization.</a>
</p>
</td>
</tr>
<tr>
<td><code>jvm_flags</code></td>
<td>
<p><code>List of strings; optional; deprecated</code></p>
<p>
Deprecated, superseded by scalac_jvm_flags and javac_jvm_flags. Is not used and is kept as backwards compatibility for the near future. Effectively jvm_flags is now an executable target attribute only.
</p>
</td>
</tr>
<tr>
<td><code>scalac_jvm_flags</code></td>
<td>
<p><code>List of strings; optional</code></p>
<p>
List of JVM flags to be passed to scalac after the
<code>scalacopts</code>. Subject to
<a href="https://bazel.build/reference/be/make-variables.html">Make variable
substitution</a> and
<a href="https://bazel.build/reference/be/common-definitions.html#sh-tokenization">Bourne shell tokenization.</a>
</p>
</td>
</tr>
<tr>
<td><code>javac_jvm_flags</code></td>
<td>
<p><code>List of strings; optional</code></p>
<p>
List of JVM flags to be passed to javac after the
<code>javacopts</code>. Subject to
<a href="https://bazel.build/reference/be/make-variables.html">Make variable
substitution</a> and
<a href="https://bazel.build/reference/be/common-definitions.html#sh-tokenization">Bourne shell tokenization.</a>
</p>
</td>
</tr>
<tr>
<td><code>unused_dependency_checker_mode</code></td>
<td>
<p><code>String; optional</code></p>
<p>
Enable unused dependency checking (see <a href="https://github.com/bazelbuild/rules_scala#experimental-unused-dependency-checking">Unused dependency checking</a>).
Possible values are: <code>off</code>, <code>warn</code> and <code>error</code>.
</p>
</td>
</tr>
</tbody>
</table>
2 changes: 2 additions & 0 deletions scala/advanced_usage/scala.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ load(
)
load(
"//scala/private:rules/scala_library.bzl",
_make_scala_inlined_library = "make_scala_inlined_library",
_make_scala_library = "make_scala_library",
_make_scala_library_for_plugin_bootstrapping = "make_scala_library_for_plugin_bootstrapping",
_make_scala_macro_library = "make_scala_macro_library",
Expand All @@ -28,6 +29,7 @@ load(

make_scala_binary = _make_scala_binary
make_scala_library = _make_scala_library
make_scala_inlined_library = _make_scala_inlined_library
make_scala_library_for_plugin_bootstrapping = _make_scala_library_for_plugin_bootstrapping
make_scala_macro_library = _make_scala_macro_library
make_scala_repl = _make_scala_repl
Expand Down
12 changes: 12 additions & 0 deletions scala/private/phases/phase_compile.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@ def phase_compile_library(ctx, p):
)
return _phase_compile_default(ctx, p, args)

def phase_compile_inlined_library(ctx, p):
args = struct(
buildijar = False,
srcjars = p.collect_srcjars,
unused_dependency_checker_ignored_targets = [
target.label
for target in p.scalac_provider.default_classpath + ctx.attr.exports +
ctx.attr.unused_dependency_checker_ignored_targets
],
)
return _phase_compile_default(ctx, p, args)

def phase_compile_library_for_plugin_bootstrapping(ctx, p):
args = struct(
buildijar = ctx.attr.build_ijar,
Expand Down
2 changes: 2 additions & 0 deletions scala/private/phases/phases.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ load(
"//scala/private:phases/phase_compile.bzl",
_phase_compile_binary = "phase_compile_binary",
_phase_compile_common = "phase_compile_common",
_phase_compile_inlined_library = "phase_compile_inlined_library",
_phase_compile_junit_test = "phase_compile_junit_test",
_phase_compile_library = "phase_compile_library",
_phase_compile_library_for_plugin_bootstrapping = "phase_compile_library_for_plugin_bootstrapping",
Expand Down Expand Up @@ -135,6 +136,7 @@ phase_collect_jars_common = _phase_collect_jars_common
# compile
phase_compile_binary = _phase_compile_binary
phase_compile_library = _phase_compile_library
phase_compile_inlined_library = _phase_compile_inlined_library
phase_compile_library_for_plugin_bootstrapping = _phase_compile_library_for_plugin_bootstrapping
phase_compile_junit_test = _phase_compile_junit_test
phase_compile_repl = _phase_compile_repl
Expand Down
63 changes: 63 additions & 0 deletions scala/private/rules/scala_library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ load(
"phase_collect_jars_common",
"phase_collect_jars_macro_library",
"phase_collect_srcjars",
"phase_compile_inlined_library",
"phase_compile_library",
"phase_compile_library_for_plugin_bootstrapping",
"phase_coverage_common",
Expand Down Expand Up @@ -218,6 +219,68 @@ def make_scala_library_for_plugin_bootstrapping(*extras):

scala_library_for_plugin_bootstrapping = make_scala_library_for_plugin_bootstrapping()

##
# scala_inlined_library
##

def _scala_inlined_library_impl(ctx):
# Build up information from dependency-like attributes
return run_phases(
ctx,
# customizable phases
[
("scalac_provider", phase_scalac_provider),
("scalainfo_provider", phase_scalainfo_provider_non_macro),
("collect_srcjars", phase_collect_srcjars),
("write_manifest", phase_write_manifest),
("dependency", phase_dependency_common),
("collect_jars", phase_collect_jars_common),
("scalacopts", phase_scalacopts),
("semanticdb", phase_semanticdb),
("compile", phase_compile_inlined_library),
("coverage", phase_coverage_library),
("merge_jars", phase_merge_jars),
("runfiles", phase_runfiles_library),
("collect_exports_jars", phase_collect_exports_jars),
("default_info", phase_default_info),
],
)

_scala_inlined_library_attrs = {}

_scala_inlined_library_attrs.update(implicit_deps)

_scala_inlined_library_attrs.update(common_attrs)

_scala_inlined_library_attrs.update(_library_attrs)

_scala_inlined_library_attrs.update(resolve_deps)

_scala_inlined_library_attrs.update(toolchain_transition_attr)

def make_scala_inlined_library(*extras):
return rule(
attrs = _dicts.add(
_scala_inlined_library_attrs,
extras_phases(extras),
*[extra["attrs"] for extra in extras if "attrs" in extra]
),
fragments = ["java"],
outputs = _dicts.add(
common_outputs,
*[extra["outputs"] for extra in extras if "outputs" in extra]
),
toolchains = [
"//scala:toolchain_type",
"@bazel_tools//tools/jdk:toolchain_type",
],
cfg = scala_version_transition,
provides = [JavaInfo],
implementation = _scala_inlined_library_impl,
)

scala_inlined_library = make_scala_inlined_library()

##
# scala_macro_library
##
Expand Down
2 changes: 2 additions & 0 deletions scala/scala.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ load(
)
load(
"//scala/private:rules/scala_library.bzl",
_scala_inlined_library = "scala_inlined_library",
_scala_library = "scala_library",
_scala_library_for_plugin_bootstrapping = "scala_library_for_plugin_bootstrapping",
_scala_library_suite = "scala_library_suite",
Expand Down Expand Up @@ -63,6 +64,7 @@ scala_library = _scala_library
scala_library_for_plugin_bootstrapping = _scala_library_for_plugin_bootstrapping
scala_library_suite = _scala_library_suite
scala_macro_library = _scala_macro_library
scala_inlined_library = _scala_inlined_library
scala_repl = _scala_repl
scala_test = _scala_test
scala_test_suite = _scala_test_suite
Expand Down
22 changes: 22 additions & 0 deletions test/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ load(
"//scala:scala.bzl",
"scala_binary",
"scala_doc",
"scala_inlined_library",
"scala_junit_test",
"scala_library",
"scala_library_suite",
Expand Down Expand Up @@ -832,3 +833,24 @@ scala_test(
srcs = ["ScalaTestResourcesFromLocalTargetTest.scala"],
resources = [":py_resource_binary"],
)

# scala_inlined_library

# If this target is a scala_library instead, then InlinedExported will fail to compile.
scala_inlined_library(
name = "InlinableExported",
srcs = ["Exported.scala"],
runtime_deps = ["Runtime"],
)

scala_library(
name = "InlinedExported",
srcs = ["OtherLib.scala"],
scalacopts = [
"-opt:l:inline",
"-opt-inline-from:scalarules.test.**",
# We need fatal warnings to ensure that the inlining actually worked.
"-Xfatal-warnings",
],
deps = [":InlinableExported"],
)