Bazel | Kotlin |
Build Kotlin source with with Bazel.
Rule | Description |
---|---|
kotlin_repositories |
Load workspace dependencies |
kotlin_library |
Build a java library from kotlin source |
kotlin_binary |
Build a java binary from kotlin source |
kotlin_android_library |
Build an android library from kotlin source |
kotlin_test |
Run a kotlin test |
Note: Bazel 0.7.0 or higher is required for rules_kotlin 0.5.0.
Add the following to your WORKSPACE
file:
git_repository(
name = "org_pubref_rules_kotlin",
remote = "https://github.com/pubref/rules_kotlin.git",
tag = "v0.5.0", # update as needed
)
load("@org_pubref_rules_kotlin//kotlin:rules.bzl", "kotlin_repositories")
kotlin_repositories()
This will fetch a
kotlin release
(currently 1.1.4-3) and load a number of dependencies related to
dagger (used to build the KotlinCompiler
bazel worker).
You can override kotlin release via the
com_github_jetbrains_kotlin_url
,com_github_jetbrains_kotlin_sha256
options and various dependencies loaded in thekotlin_repositories
rule via theomit_*
options; see the source file for details.
Add the following to your BUILD file:
load("@org_pubref_rules_kotlin//kotlin:rules.bzl", "kotlin_library")
Example:
kotlin_library(
name = "my_kotlin_lib",
srcs = ["kotlin_source_file.kt"],
deps = [":some_other_kotlin_library_rule"],
java_deps = [":some_other_java_library_rule", "@another_maven_jar//jar"],
)
Use the deps
attribute to name other kotlin_library
targets as jar
providers for this rule. Use the java_deps
attribute to name other
java_library
or java_import
targets (to expose traditional java
classes in your kotlin source).
To compile a set of kotlin sources files with the kotlinc
tool and
emit the corresponding jar file, use:
$ bazel build :my_kotlin_lib
Target :my_kotlin_lib up-to-date:
bazel-bin/.../my_kotlin_lib.jar
To use the output of a kotlin_library
as input to a java_library
rule (and make your compiled kotlin classes available to your
traditional java source files), name it as a dependency using the
deps
attribute, just as you would any other java_library
target.
The name of this target must be of the form
{kotlin_library_target_name}_kt
. For example, to use the
:my_kotlin_lib
in an android_binary
target, the name would be
:my_kotlin_lib_kt
, such as:
android_binary(
name = "foo",
deps = [
":my_kotlin_lib_kt`,
]
)
Name | Type | Description |
---|---|---|
srcs |
label_list |
Kotlin source files *.kt |
deps |
label_list |
List of kotlin_library targets |
java_deps |
label_list |
List of java provider targets (java_library , java_import , ... ) |
android_deps |
label_list |
List of android provider targets (android_library ) |
jars |
label_list |
List of jar file targets (*.jar ) |
x_opts |
string_list |
List of additional -X options to kotlinc |
plugin_opts |
string_dict |
List of additional -P options to kotlinc |
A kotlin_binary
macro takes the same arguments as a
kotlin_library
, plus a required main_class
argument (the name of
the compiled kotlin class to run, in java package notation). This
class should have a fun main(...)
entrypoint. Example:
kotlin_binary(
name = "main_kt",
main_class = "my.project.MainKt",
srcs = ["main.kt"],
deps = [":my_kotlin_lib"]
java_deps = [":javalib"]
)
To create a self-contained executable jar, invoke the implicit
_deploy.jar
target. For example:
$ bazel build :main_kt_deploy.jar
Target :main_kt_deploy.jar up-to-date:
bazel-bin/.../main_kt_deploy.jar
$ java -jar ./bazel-bin/.../main_kt_deploy.jar
The
kotlin-runtime.jar
is implicitly included by thekotlin_binary
rule.
Includes all kotlin_library
attributes as well as:
Name | Type | Description |
---|---|---|
main_class |
string |
Main class to run with the kotlin_binary rule |
A kotlin_android_library
macro takes mostly the same arguments as a
kotlin_library
,
plus some Android specific arguments like
aar_deps
, resource_files
, custom_package
, manifest
, etc.
An example with combined source and resource:
PACKAGE = "com.company.app"
MANIFEST = "AndroidManifest.xml"
kotlin_android_library(
name = "src",
srcs = glob(["src/**/*.kt"]),
custom_package = PACKAGE,
manifest = MANIFEST,
resource_files = glob(["res/**/*"]),
java_deps = [
"@com_squareup_okhttp3_okhttp//jar",
"@com_squareup_okio_okio//jar",
],
aar_deps = [
"@androidsdk//com.android.support:appcompat-v7-25.3.1",
"@androidsdk//com.android.support:cardview-v7-25.3.1",
"@androidsdk//com.android.support:recyclerview-v7-25.3.1",
],
)
android_binary(
name = "app",
custom_package = PACKAGE,
manifest = MANIFEST,
deps = [
":src",
],
)
If you prefer to separate your source files and resource files in
different Bazel rules (for example the resource files are also used
by java android_library
rules), you can do so as example:
PACKAGE = "com.company.app"
MANIFEST = "AndroidManifest.xml"
android_library(
name = "res",
custom_package = PACKAGE,
manifest = MANIFEST,
resource_files = glob(["res/**/*"]),
aar_deps = [
"@androidsdk//com.android.support:appcompat-v7-25.3.1",
"@androidsdk//com.android.support:cardview-v7-25.3.1",
"@androidsdk//com.android.support:recyclerview-v7-25.3.1",
],
)
android_library(
name = "java",
srcs = glob(["src/**/*.java"]),
deps = [
":res",
# And other depedencies
]
)
kotlin_android_library(
name = "kt",
srcs = glob(["src/**/*.kt"]),
aar_deps = [
"@androidsdk//com.android.support:appcompat-v7-25.3.1",
"@androidsdk//com.android.support:cardview-v7-25.3.1",
"@androidsdk//com.android.support:recyclerview-v7-25.3.1",
],
android_deps = [
":res",
]
)
android_binary(
name = "app",
custom_package = PACKAGE,
manifest = MANIFEST,
deps = [
":java",
":kt",
":res",
],
)
Please note that if you want to use R
class in your Kotlin code,
your kotlin_android_library
rule need to either have the
resource_files
and related arguments,
or have the resource rule in android_deps
.
Includes all kotlin_library
attributes as well as:
Name | Type | Description |
---|---|---|
aar_deps |
label_list |
List of AAR library targets |
And also android_library
arguments.
The kotlin_test
rule is nearly identical the kotlin_binary
rule
(other than calling java_test
internally rather than java_binary
).
kotlin_test(
name = "main_kt_test",
test_class = "examples.helloworld.MainKtTest",
srcs = ["MainKtTest.kt"],
size = "small",
deps = [
":rules",
],
java_deps = [
"@junit4//jar",
],
)
$ bazel test :main_kt_test.jar
The
kotlin-test.jar
is implicitly included by thekotlin_test
rule.
TL;DR; You most likely do not need to interact with the
kotlin_compile
rule directly.
The kotlin_compile
rule runs the kotlin compiler to generate a
.jar
file from a list of kotlin source files. The kotlin_library
rule calls this internally and then makes the jarfile available to
other java rules via a java_import
rule.
That's it! Hopefully these rules with make it easy to mix kotlin and traditional java code in your projects and take advantage of bazel's approach to fast, repeatable, and reliable builds.
Note: Consider rules_maven for handling transitive maven dependencies with your java/kotlin projects.
To run the examples in this repository, clone the repo:
$ git clone https://github.com/pubref/rules_kotlin
$ cd rules_kotlin
$ bazel query //... --output label_kind
$ bazel run examples/helloworld:main_kt
$ bazel run examples/helloworld:main_java
$ bazel test examples/helloworld:main_test
$ bazel test examples/helloworld:main_kt_test
data
and runfiles support.