OXYGENHUB
# 03f2c0361594 +6 oxygenhub-android / app / build.gradle.kts
5.7 KiB · last changed CI on OxygenFlow: unit tests with JUnit and JaCoCo coverage, and a debug build, offline (closes #19) 12 days ago source blame history raw
57c08243 Andy McCall ↶ 1
import java.io.File
2
import java.util.Properties
3
e0e4a1c4 Andy McCall ↶ 4
plugins {
5
    alias(libs.plugins.android.application)
6
    alias(libs.plugins.kotlin.compose)
5ae4af48 Andy McCall ↶ 7
    alias(libs.plugins.kotlin.serialization)
0a2858c0 Andy McCall ↶ 8
    alias(libs.plugins.screenshot)
e0e4a1c4 Andy McCall ↶ 9
}
57c08243 Andy McCall ↶ 10
11
// The Rust core (rust-core/, over oxy-core) is built for the app's ABIs by
12
// cargo-ndk and its Kotlin bindings generated by uniffi at build time
13
// (oxygenhub-android#1): nothing built is kept in the repository.
14
val rustCore: File = rootProject.file("rust-core")
15
val rustJniLibs = layout.buildDirectory.dir("rustJniLibs")
16
val rustBindings = layout.buildDirectory.dir("generated/uniffi/kotlin")
17
18
fun androidNdk(): String {
19
    System.getenv("ANDROID_NDK_HOME")?.let { return it }
20
    val props = Properties()
21
    val local = rootProject.file("local.properties")
22
    if (local.exists()) local.inputStream().use { input -> props.load(input) }
23
    val sdk = props.getProperty("sdk.dir") ?: System.getenv("ANDROID_HOME")
24
        ?: error("set sdk.dir in local.properties or ANDROID_HOME")
25
    val ndks = File(sdk, "ndk").listFiles()?.filter { f -> f.isDirectory }?.sortedBy { f -> f.name }.orEmpty()
26
    return ndks.lastOrNull()?.path ?: error("no NDK under $sdk/ndk: install one with the SDK manager")
27
}
28
29
val buildRustCore = tasks.register("buildRustCore", Exec::class) {
30
    description = "Builds rust-core for arm64-v8a and x86_64 with cargo-ndk."
31
    workingDir = rustCore
32
    inputs.dir(rustCore.resolve("src"))
33
    inputs.files(rustCore.resolve("Cargo.toml"), rustCore.resolve("Cargo.lock"))
74bbbc25 Andy McCall ↶ 34
    // The runner's Rust (OxygenFlow and its oxy-core) is built in too.
35
    inputs.files(fileTree(rootProject.file("oxygenflow")) { include("**/*.rs", "**/Cargo.toml"); exclude("**/target/**") })
57c08243 Andy McCall ↶ 36
    outputs.dir(rustJniLibs)
37
    environment("ANDROID_NDK_HOME", androidNdk())
38
    commandLine("cargo", "ndk", "-t", "arm64-v8a", "-t", "x86_64", "--platform", "31", "-o", rustJniLibs.get().asFile.path, "build", "--release")
39
}
40
41
val generateRustBindings = tasks.register("generateRustBindings", Exec::class) {
42
    description = "Generates rust-core's Kotlin bindings with uniffi."
43
    dependsOn(buildRustCore)
44
    workingDir = rustCore
45
    inputs.dir(rustJniLibs)
46
    outputs.dir(rustBindings)
47
    commandLine(
48
        "cargo", "run", "--release", "--bin", "uniffi-bindgen", "generate",
49
        "--library", rustJniLibs.get().file("arm64-v8a/librust_core.so").asFile.path,
50
        "--language", "kotlin", "--out-dir", rustBindings.get().asFile.path,
51
    )
52
}
53
54
tasks.named("preBuild") { dependsOn(generateRustBindings) }
e0e4a1c4 Andy McCall ↶ 55
56
android {
57c08243 Andy McCall ↶ 57
    namespace = "io.oxygenhub.android"
e0e4a1c4 Andy McCall ↶ 58
    compileSdk {
59
        version = release(37)
60
    }
61
62
    defaultConfig {
57c08243 Andy McCall ↶ 63
        applicationId = "io.oxygenhub.android"
64
        minSdk = 31
e0e4a1c4 Andy McCall ↶ 65
        targetSdk = 37
66
        versionCode = 1
67
        versionName = "1.0"
68
69
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
70
    }
71
72
    buildTypes {
8a657957 Andy McCall ↶ 73
        // Unit test coverage as JaCoCo XML for the hub's Coverage tab
74
        // (#19): ./gradlew :app:createDebugUnitTestCoverageReport.
75
        debug {
76
            enableUnitTestCoverage = true
77
        }
e0e4a1c4 Andy McCall ↶ 78
        release {
79
            optimization {
80
                enable = false
81
            }
82
        }
83
    }
84
    compileOptions {
85
        sourceCompatibility = JavaVersion.VERSION_11
86
        targetCompatibility = JavaVersion.VERSION_11
87
    }
490d1806 Andy McCall ↶ 88
    packaging {
89
        jniLibs {
90
            useLegacyPackaging = true
91
        }
92
    }
e0e4a1c4 Andy McCall ↶ 93
    buildFeatures {
94
        compose = true
95
    }
0a2858c0 Andy McCall ↶ 96
    // README screenshots, rendered from previews without an emulator:
97
    // ./gradlew :app:updateDebugScreenshotTest (src/screenshotTest).
98
    experimentalProperties["android.experimental.enableScreenshotTest"] = true
57c08243 Andy McCall ↶ 99
    sourceSets["main"].jniLibs.directories.add(rustJniLibs.get().asFile.path)
100
    sourceSets["main"].kotlin.directories.add(rustBindings.get().asFile.path)
e0e4a1c4 Andy McCall ↶ 101
}
102
103
dependencies {
5ae4af48 Andy McCall ↶ 104
    implementation(libs.jna) { artifact { type = "aar" } }
e0e4a1c4 Andy McCall ↶ 105
    implementation(platform(libs.androidx.compose.bom))
106
    implementation(libs.androidx.activity.compose)
107
    implementation(libs.androidx.compose.material3)
5ae4af48 Andy McCall ↶ 108
    implementation(libs.androidx.compose.material3.navigation.suite)
109
    implementation(libs.androidx.compose.material3.adaptive)
110
    implementation(libs.androidx.compose.material3.adaptive.layout)
111
    implementation(libs.androidx.compose.material3.adaptive.navigation)
112
    implementation(libs.androidx.compose.material.icons.extended)
e0e4a1c4 Andy McCall ↶ 113
    implementation(libs.androidx.compose.ui)
114
    implementation(libs.androidx.compose.ui.graphics)
115
    implementation(libs.androidx.compose.ui.tooling.preview)
116
    implementation(libs.androidx.core.ktx)
117
    implementation(libs.androidx.lifecycle.runtime.ktx)
5ae4af48 Andy McCall ↶ 118
    implementation(libs.androidx.lifecycle.runtime.compose)
119
    implementation(libs.androidx.lifecycle.viewmodel.compose)
120
    implementation(libs.androidx.navigation.compose)
121
    implementation(libs.kotlinx.serialization.json)
122
    implementation(libs.kotlinx.coroutines.android)
123
    implementation(libs.okhttp)
98dbd122 Andy McCall ↶ 124
    implementation(libs.markdown.renderer.m3)
125
    implementation(libs.highlights)
e0e4a1c4 Andy McCall ↶ 126
    testImplementation(libs.junit)
5ae4af48 Andy McCall ↶ 127
    testImplementation(libs.kotlinx.coroutines.test)
128
    testImplementation(libs.okhttp.mockwebserver)
e0e4a1c4 Andy McCall ↶ 129
    androidTestImplementation(platform(libs.androidx.compose.bom))
130
    androidTestImplementation(libs.androidx.compose.ui.test.junit4)
131
    androidTestImplementation(libs.androidx.espresso.core)
132
    androidTestImplementation(libs.androidx.junit)
0a2858c0 Andy McCall ↶ 133
    screenshotTestImplementation(libs.screenshot.validation.api)
134
    screenshotTestImplementation(libs.androidx.compose.ui.tooling)
135
    screenshotTestImplementation(libs.kotlinx.coroutines.test)
e0e4a1c4 Andy McCall ↶ 136
    debugImplementation(libs.androidx.compose.ui.test.manifest)
137
    debugImplementation(libs.androidx.compose.ui.tooling)
5ae4af48 Andy McCall ↶ 138
}