import org.gradle.internal.jvm.Jvm plugins { kotlin("jvm") version "2.3.0" kotlin("plugin.serialization") version "2.0.0" } group = "su.sonoma" version = "0.1" repositories { mavenCentral() } dependencies { testImplementation(kotlin("test")) implementation("io.ktor:ktor-network:3.1.3") implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.22") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.0") } kotlin { jvmToolchain(25) } tasks.jar { dependsOn("buildTunLib") dependsOn(configurations.runtimeClasspath) manifest { attributes["Main-Class"] = "su.sonoma.MainKt" } duplicatesStrategy = DuplicatesStrategy.EXCLUDE from(sourceSets.main.get().output) from({ configurations.runtimeClasspath.get().filter { it.name.endsWith("jar") }.map { zipTree(it) } }) archiveBaseName.set(rootProject.name) archiveVersion.set(version.toString()) } tasks.test { useJUnitPlatform() } tasks.register("generateTestServerConfig") { val outputFile = layout.buildDirectory.file("tmp/server.json") outputs.file(outputFile) doLast { val file = outputFile.get().asFile file.parentFile.mkdirs() file.writeText(""" { "type": "server", "address": "10.1.0.1", "port": 9093 } """.trimIndent()) } } tasks.register("generateTestClientConfig") { val outputFile = layout.buildDirectory.file("tmp/client.json") outputs.file(outputFile) doLast { val file = outputFile.get().asFile file.parentFile.mkdirs() file.writeText(""" { "type": "client", "host": "192.168.88.247", "address": "10.1.0.2", "port": 9093 } """.trimIndent()) } } tasks.register("runServer") { group = "app" description = "Run server" classpath = sourceSets["main"].runtimeClasspath mainClass.set("su.sonoma.MainKt") args = listOf("${projectDir}/build/tmp/server.json") jvmArgs = listOf( "--add-opens=java.base/java.io=ALL-UNNAMED" ) dependsOn("buildTunLib") dependsOn("generateTestServerConfig") systemProperty( "java.library.path", "${projectDir}/build/native/" ) } tasks.register("runClient") { group = "app" description = "Run client" classpath = sourceSets["main"].runtimeClasspath mainClass.set("su.sonoma.MainKt") args = listOf("${projectDir}/build/tmp/client.json") jvmArgs = listOf( "--add-opens=java.base/java.io=ALL-UNNAMED" ) dependsOn("buildTunLib") dependsOn("generateTestClientConfig") systemProperty( "java.library.path", "${projectDir}/build/native/" ) } val javaHome = Jvm.current().javaHome.absolutePath tasks.register("buildTunLib") { group = "build" val outputDir = layout.buildDirectory.dir("native").get().asFile doFirst { outputDir.mkdirs() } commandLine( "gcc", "-shared", "-fPIC", "-z", "noexecstack", "-o", "${outputDir.absolutePath}/libtun.so", "src/main/c/tun.c", "-I$javaHome/include", "-I$javaHome/include/linux" ) } tasks.register("generateRunScript") { val output = layout.buildDirectory.file("tmp/${rootProject.name}") val name = rootProject.name.plus('-').plus(version) val jarName = name.plus(".jar") outputs.file(output) doLast { val script = output.get().asFile script.parentFile.mkdirs() script.writeText(""" #!/bin/bash java \ -Djava.library.path="." \ -jar "$jarName" "$@" """.trimIndent()) script.setExecutable(true) } } tasks.register("packageApp") { group = "build" destinationDirectory.set(layout.buildDirectory.dir("dist")) compression = Compression.GZIP dependsOn("jar") dependsOn("generateRunScript") val name = rootProject.name.plus('-').plus(version) val jarName = name.plus(".jar") archiveFileName.set("$name.tar.gz") from("build/libs/$jarName") from("build/native/libtun.so") from("build/tmp/${rootProject.name}") }