-
-
Notifications
You must be signed in to change notification settings - Fork 347
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add kotlinlib
example/module
examples (#3585)
This PR adds more stuff for #3451, namely `example/kotlinlib/module` examples. Few notes about things being done: * `1-compilation-execution-flags` - there is not so many flags which can be passed to the Kotlin Compiler itself. I simply used [-Werror](https://kotlinlang.org/docs/compiler-reference.html#werror). * `6-annotation-processors` - I used `kotlinx.serialization` as proposed by @lefou. It seems Kotlin Compiler doesn't automatically pick compilation plugins from the classpath, so I had to pass path to it explicitly using `-Xplugin` option. * `7-dokkajar` - obviously `javadoc` cannot be used to generate docs for Kotlin classes, so I added support for [Dokka](https://github.com/Kotlin/dokka) to `KotlinModule` and added a forwarding of `docJar` calls to `dokkaJar`. * `13-jni` - there is no possibility to generate header files from Kotlin files (unless an ugly trick is used to take compiled `.class` files, decompile them back, clean-up and pass to `javac` to generate headers), so I dropped header generation. --------- Co-authored-by: 0xnm <[email protected]>
- Loading branch information
Showing
43 changed files
with
733 additions
and
4 deletions.
There are no files selected for viewing
17 changes: 17 additions & 0 deletions
17
example/kotlinlib/module/1-compilation-execution-flags/build.mill
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
//// SNIPPET:BUILD | ||
package build | ||
import mill._, kotlinlib._ | ||
|
||
object `package` extends RootModule with KotlinModule { | ||
|
||
def kotlinVersion = "1.9.24" | ||
|
||
def mainClass = Some("foo.FooKt") | ||
|
||
def forkArgs = Seq("-Xmx4g", "-Dmy.jvm.property=hello") | ||
def forkEnv = Map("MY_ENV_VAR" -> "WORLD") | ||
|
||
def kotlincOptions = super.kotlincOptions() ++ Seq("-Werror") | ||
} | ||
|
||
//// SNIPPET:END |
7 changes: 7 additions & 0 deletions
7
example/kotlinlib/module/1-compilation-execution-flags/src/foo/Foo.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package foo | ||
|
||
fun main() { | ||
val jvmProperty = System.getProperty("my.jvm.property") | ||
val envVar = System.getenv("MY_ENV_VAR") | ||
println("$jvmProperty $envVar") | ||
} |
20 changes: 20 additions & 0 deletions
20
example/kotlinlib/module/10-downloading-non-maven-jars/build.mill
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
//// SNIPPET:BUILD | ||
package build | ||
import mill._, kotlinlib._ | ||
|
||
object `package` extends RootModule with KotlinModule { | ||
|
||
def kotlinVersion = "1.9.24" | ||
|
||
def mainClass = Some("foo.FooKt") | ||
|
||
def unmanagedClasspath = T { | ||
os.write( | ||
T.dest / "fastjavaio.jar", | ||
requests.get.stream( | ||
"https://github.com/williamfiset/FastJavaIO/releases/download/1.1/fastjavaio.jar" | ||
) | ||
) | ||
Agg(PathRef(T.dest / "fastjavaio.jar")) | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
example/kotlinlib/module/10-downloading-non-maven-jars/src/foo/Foo.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package foo | ||
|
||
import com.williamfiset.fastjavaio.InputReader | ||
|
||
import java.io.FileInputStream | ||
import java.io.IOException | ||
|
||
fun main(args: Array<String>) { | ||
val filePath = args[0] | ||
val fi = try { | ||
InputReader(FileInputStream(filePath)) | ||
} catch (e: IOException) { | ||
e.printStackTrace() | ||
null | ||
} | ||
|
||
var line: String? = fi?.nextLine() | ||
while (line != null) { | ||
println(line) | ||
line = fi?.nextLine() | ||
} | ||
|
||
try { | ||
fi?.close() | ||
} catch (e: IOException) { | ||
e.printStackTrace() | ||
} | ||
} |
3 changes: 3 additions & 0 deletions
3
example/kotlinlib/module/10-downloading-non-maven-jars/textfile.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
I am cow | ||
hear me moo | ||
I weigh twice as much as you |
1 change: 1 addition & 0 deletions
1
example/kotlinlib/module/11-assembly-config/bar/resources/application.conf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Bar Application Conf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
//// SNIPPET:BUILD | ||
package build | ||
import mill._, kotlinlib._ | ||
import mill.javalib.Assembly._ | ||
|
||
object foo extends KotlinModule { | ||
|
||
def kotlinVersion = "1.9.24" | ||
|
||
def mainClass = Some("foo.FooKt") | ||
|
||
def moduleDeps = Seq(bar) | ||
def assemblyRules = Seq( | ||
// all application.conf files will be concatenated into single file | ||
Rule.Append("application.conf"), | ||
// all *.conf files will be concatenated into single file | ||
Rule.AppendPattern(".*\\.conf"), | ||
// all *.temp files will be excluded from a final jar | ||
Rule.ExcludePattern(".*\\.temp"), | ||
// the `shapeless` package will be shaded under the `shade` package | ||
Rule.Relocate("shapeless.**", "shade.shapless.@1") | ||
) | ||
} | ||
|
||
object bar extends KotlinModule { | ||
def kotlinVersion = "1.9.24" | ||
} |
1 change: 1 addition & 0 deletions
1
example/kotlinlib/module/11-assembly-config/foo/resources/application.conf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Foo Application Conf |
15 changes: 15 additions & 0 deletions
15
example/kotlinlib/module/11-assembly-config/foo/src/foo/Foo.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package foo | ||
|
||
import java.io.IOException | ||
import java.io.InputStream | ||
|
||
fun main(args: Array<String>) { | ||
::main.javaClass | ||
.classLoader | ||
.getResourceAsStream("application.conf") | ||
.use { | ||
val conf = it.readAllBytes().toString(Charsets.UTF_8) | ||
println("Loaded application.conf from resources: $conf") | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
//// SNIPPET:BUILD1 | ||
package build | ||
import mill._, kotlinlib._ | ||
import mill.javalib.{ZincWorkerModule, CoursierModule} | ||
import mill.define.ModuleRef | ||
import coursier.maven.MavenRepository | ||
|
||
val sonatypeReleases = Seq( | ||
MavenRepository("https://oss.sonatype.org/content/repositories/releases") | ||
) | ||
|
||
object foo extends KotlinModule { | ||
|
||
def mainClass = Some("foo.FooKt") | ||
|
||
def kotlinVersion = "1.9.24" | ||
|
||
def ivyDeps = Agg( | ||
ivy"com.github.ajalt.clikt:clikt-jvm:4.4.0", | ||
ivy"org.jetbrains.kotlinx:kotlinx-html-jvm:0.11.0" | ||
) | ||
|
||
def repositoriesTask = T.task { super.repositoriesTask() ++ sonatypeReleases } | ||
} | ||
|
||
//// SNIPPET:BUILD2 | ||
|
||
object CustomZincWorkerModule extends ZincWorkerModule with CoursierModule { | ||
def repositoriesTask = T.task { super.repositoriesTask() ++ sonatypeReleases } | ||
} | ||
|
||
object bar extends KotlinModule { | ||
|
||
def kotlinVersion = "1.9.24" | ||
|
||
def zincWorker = ModuleRef(CustomZincWorkerModule) | ||
// ... rest of your build definitions | ||
|
||
def repositoriesTask = T.task { super.repositoriesTask() ++ sonatypeReleases } | ||
} |
18 changes: 18 additions & 0 deletions
18
example/kotlinlib/module/12-repository-config/foo/src/foo/Foo.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package foo | ||
|
||
import com.github.ajalt.clikt.core.CliktCommand | ||
import com.github.ajalt.clikt.parameters.options.option | ||
import com.github.ajalt.clikt.parameters.options.required | ||
import foo.main as fooMain | ||
import kotlinx.html.h1 | ||
import kotlinx.html.stream.createHTML | ||
|
||
class Foo : CliktCommand() { | ||
val text by option("--text").required() | ||
|
||
override fun run() { | ||
println(createHTML(prettyPrint = false).h1 { text(text) }.toString()) | ||
} | ||
} | ||
|
||
fun main(args: Array<String>) = Foo().main(args) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package build | ||
import mill._, kotlinlib._, util.Jvm | ||
|
||
object `package` extends RootModule with KotlinModule { | ||
|
||
def mainClass = Some("foo.HelloWorldKt") | ||
|
||
def kotlinVersion = "1.9.24" | ||
|
||
// Additional source folder to put C sources | ||
def nativeSources = T.sources(millSourcePath / "native-src") | ||
|
||
// Compile C | ||
def nativeCompiled = T{ | ||
val cSourceFiles = nativeSources().map(_.path).flatMap(os.walk(_)).filter(_.ext == "c") | ||
val output = "libhelloworld.so" | ||
os.proc( | ||
"clang", "-shared", "-fPIC", | ||
"-I" + sys.props("java.home") + "/include/", // global JVM header files | ||
"-I" + sys.props("java.home") + "/include/darwin", | ||
"-I" + sys.props("java.home") + "/include/linux", | ||
"-o", T.dest / output, | ||
cSourceFiles | ||
) | ||
.call(stdout = os.Inherit) | ||
|
||
PathRef(T.dest / output) | ||
} | ||
|
||
def forkEnv = Map("HELLO_WORLD_BINARY" -> nativeCompiled().path.toString) | ||
|
||
object test extends KotlinModuleTests with TestModule.Junit5 { | ||
def ivyDeps = super.ivyDeps() ++ Agg( | ||
ivy"io.kotest:kotest-runner-junit5-jvm:5.9.1" | ||
) | ||
def forkEnv = Map("HELLO_WORLD_BINARY" -> nativeCompiled().path.toString) | ||
} | ||
} | ||
|
||
// This is an example of how use Mill to compile C code together with your Kotlin | ||
// code using JNI. There are three two steps: defining the C source folder, | ||
// and then compiling the C code using `clang`. After that we have the | ||
// `libhelloworld.so` on disk ready to use, and in this example we use an | ||
// environment variable to pass the path of that file to the application | ||
// code to load it using `System.load`. | ||
// | ||
// The above builds expect the following project layout: | ||
// | ||
// ---- | ||
// build.mill | ||
// src/ | ||
// foo/ | ||
// HelloWorld.kt | ||
// | ||
// native-src/ | ||
// HelloWorld.c | ||
// | ||
// test/ | ||
// src/ | ||
// foo/ | ||
// HelloWorldTest.kt | ||
// ---- | ||
// | ||
// This example is pretty minimal, but it demonstrates the core principles, and | ||
// can be extended if necessary to more elaborate use cases. The `native*` tasks | ||
// can also be extracted out into a `trait` for re-use if you have multiple | ||
// `KotlinModule`s that need native C components. | ||
|
||
/** Usage | ||
|
||
> ./mill run | ||
Hello, World! | ||
|
||
> ./mill test | ||
Test foo.HelloWorldTestsimple started | ||
Test foo.HelloWorldTestsimple finished... | ||
... | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#include <jni.h> | ||
#include <string.h> | ||
|
||
// Implementation of the native method | ||
JNIEXPORT jstring JNICALL Java_foo_HelloWorld_sayHello(JNIEnv *env, jobject obj) { | ||
return (*env)->NewStringUTF(env, "Hello, World!"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package foo | ||
|
||
class HelloWorld { | ||
// Declare a native method | ||
external fun sayHello(): String | ||
|
||
// Load the native library | ||
companion object { | ||
init { | ||
System.load(System.getenv("HELLO_WORLD_BINARY")) | ||
} | ||
} | ||
} | ||
|
||
|
||
fun main(args: Array<String>) { | ||
val helloWorld = HelloWorld() | ||
println(helloWorld.sayHello()) | ||
} |
10 changes: 10 additions & 0 deletions
10
example/kotlinlib/module/13-jni/test/src/foo/HelloWorldTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package foo | ||
|
||
import io.kotest.core.spec.style.FunSpec | ||
import io.kotest.matchers.shouldBe | ||
|
||
class HelloWorldTest : FunSpec({ | ||
test("simple") { | ||
HelloWorld().sayHello() shouldBe "Hello, World!" | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
//// SNIPPET:BUILD | ||
package build | ||
import mill._, kotlinlib._ | ||
|
||
object `package` extends RootModule with KotlinModule { | ||
|
||
def kotlinVersion = "1.9.24" | ||
|
||
def mainClass = Some("foo.FooKt") | ||
|
||
def ivyDeps = Agg( | ||
ivy"com.fasterxml.jackson.core:jackson-databind:2.13.4", | ||
) | ||
} | ||
|
||
//// SNIPPET:SCALAIVY | ||
|
||
//// SNIPPET:USAGE | ||
/** Usage | ||
|
||
> ./mill run i am cow | ||
JSONified using Jackson: ["i","am","cow"] | ||
|
||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package foo | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper | ||
import com.fasterxml.jackson.databind.SerializationFeature | ||
|
||
fun main(args: Array<String>) { | ||
val value = ObjectMapper().writeValueAsString(args) | ||
println("JSONified using Jackson: $value") | ||
} |
28 changes: 28 additions & 0 deletions
28
example/kotlinlib/module/3-run-compile-deps/bar/src/bar/Bar.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package bar | ||
|
||
import javax.servlet.ServletException | ||
import javax.servlet.http.HttpServlet | ||
import javax.servlet.http.HttpServletRequest | ||
import javax.servlet.http.HttpServletResponse | ||
import java.io.IOException | ||
import org.eclipse.jetty.server.Server | ||
import org.eclipse.jetty.servlet.ServletContextHandler | ||
import org.eclipse.jetty.servlet.ServletHolder | ||
|
||
class BarServlet : HttpServlet() { | ||
protected override fun doGet(request: HttpServletRequest, response: HttpServletResponse) { | ||
response.setContentType("text/html") | ||
response.setStatus(HttpServletResponse.SC_OK) | ||
response.getWriter().println("<html><body>Hello World!</body></html>") | ||
} | ||
} | ||
|
||
fun main(args: Array<String>) { | ||
val server = Server(8079) | ||
val context = ServletContextHandler() | ||
context.setContextPath("/") | ||
server.setHandler(context) | ||
context.addServlet(ServletHolder(BarServlet()), "/*") | ||
server.start() | ||
server.join() | ||
} |
Oops, something went wrong.