A scala-kotlin-java
union compile Gradle plugin
, for native Android.
- Also refers demo project scalroid-build-demo
- Clone this repository to your project's
buildSrc
directory (optional):
cd <PATH/TO/YOUR_PROJECT>
git clone git@github.com:chenakam/scalroid.git buildSrc
- Below is your project's directory structure as possibly looks like:
/your_project
/app
/src
/main
/java # Your java/kotlin code dir
/scala # Your scala code dir (java files can also compile)
/build.gradle
/...
/buildSrc # This repo dir
/other_modules
/...
- Add
apply plugin: 'cash.bdo.scalroid'
to yourapp/build.gradle
file:
- See https://plugins.gradle.org/plugin/cash.bdo.scalroid if Step 1 was not done.
plugins {
id 'com.android.application'
// Alternatively, for your library subproject
//id 'com.android.library'
id 'org.jetbrains.kotlin.android' // Required
// or (abbr)
//id 'kotlin-android'
// This plugin
id 'cash.bdo.scalroid'
}
android {
scalroid {
// scala.zincVersion.set('1.6.1')
// scalaCodeReferToKt = false
// ktCodeReferToScala = true
javaDirsExcludes = ['/main/kotlin/']
}
// ...
}
dependencies {
implementation "androidx.core:core-ktx:1.8.0"
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
// ...
// `scala-library` must be set. Scala 2 or Scala 3
// Scala 2
implementation "org.scala-lang:scala-library:2.12.17"
// Scala 3
// implementation 'org.scala-lang:scala3-library_3:3.2.0-RC2'
}
- You can edit any code in
your_project/buildSrc/src
as needed, and then click the button with tooltipSync Project with Gradle Files
in the toolbar of yourAndroid Studio
, your modified code will be applied immediately.
It's not that easy to get scala
and kotlin
code to compile together in one go. Especially when it comes to cross-referencing code. So, here are two options to help
you compile through.
You can use Java as a transition, scala and kotlin both refer to java instead of directly referencing each other. At most, you can also use kotlin code to refer directly to scala (by default). That should do it.
Don't forget the following settings if you put java source files in a non-default folder, e.g.src/aaa/xxx
. The default folders are src/main/java
and src/main/kotlin
and do not need to be set.
scalroid {
javaDirsExcludes = ['src/main/xxx', 'src/aaa/xxx']
}
Note: .java
(and .scala
) files written in src/main/scala
directory will be compiled and output by the scala compiler. .java
files written in other directories
will NOT be compiled and output by scala even if they are referenced by .scala
files (which would be compiled for output by the java compiler). But if NOT
configured in javaDirsExcludes
, output is compiled by scala by default, which may results in duplicate .class
files and an error is reported. If similar error occurs,
try adding the directories to javaDirsExcludes
.
In other words, if you want scala to compile, you should written .java
(and .scala
) files in the src/main/scala
directory (or other directories you configured
in sourceSets
), otherwise you should written them in the java/kotlin
directories.
There are two parameters you can use conveniently, and they are:
scalroid {
scalaCodeReferToKt = false // `false` by default
ktCodeReferToScala = true // `true` by default
}
The default value means the kotlin code references scala code, but it cannot be back referenced because of scala-kotlin cross compilation has not implemented. If this is the case, do nothing else, leave the defaults, and the project compiles. Or the opposite one-way reference works:
scalroid {
// One-way reference works
scalaCodeReferToKt = false // `false` by default
ktCodeReferToScala = true // `true` by default
// Alternatively:
// The opposite one-way reference also works too
scalaCodeReferToKt = true
ktCodeReferToScala = false
}
But given the existence of such a situation of scala/kotlin code tends to cross-reference, I also made compatible reluctantly so that we can compile finally. It's theoretically set up like this (but the truth is not so simple):
scalroid {
scalaCodeReferToKt = true
ktCodeReferToScala = true
}
- If this is set, once you
clean
the project, you will got errors the next time you compile.
The correct steps are (tentatively and reluctantly):
Clean
project (run./gradlew clean
);- Comment out any code in
scala
that referenceskotlin
(or vice versa) and uniformize the two parameters setting to maintain a one-way reference (no need to clickSync
, which doesn't matter); - Try compiling until you pass (
./gradlew :app:compile{VARIANT}JavaWithJavac
),kotlin-classes
andscala-classes
inapp/build/tmp/
have output associated withVARIANT
; - Sets the two parameters both to
true
and uncomment any code commented out in Step 2; - Try compiling until you pass.
- Note: repeat these steps each time you
clean
your project.