From 04aeee2e7bf84ed00a0ef80d7653922dbc4a76e9 Mon Sep 17 00:00:00 2001 From: Jamil Date: Fri, 12 Jan 2024 08:16:43 -0800 Subject: [PATCH] fix(android): Simplify connlib gradle build configuration to ensure libconnlib.so is packaged (#3207) Fixes #3205 --- .github/workflows/_kotlin.yml | 4 +- kotlin/android/app/build.gradle.kts | 26 +++- .../android/core/presentation/MainActivity.kt | 7 + .../firezone/android/tunnel/TunnelManager.kt | 7 - kotlin/android/build.gradle.kts | 1 - kotlin/android/settings.gradle.kts | 2 - .../clients/android/connlib/build.gradle.kts | 126 ------------------ .../connlib/src/main/AndroidManifest.xml | 4 - 8 files changed, 32 insertions(+), 145 deletions(-) delete mode 100644 rust/connlib/clients/android/connlib/build.gradle.kts delete mode 100644 rust/connlib/clients/android/connlib/src/main/AndroidManifest.xml diff --git a/.github/workflows/_kotlin.yml b/.github/workflows/_kotlin.yml index 63489f7f3..42919e641 100644 --- a/.github/workflows/_kotlin.yml +++ b/.github/workflows/_kotlin.yml @@ -39,7 +39,7 @@ jobs: - uses: actions/checkout@v4 - uses: ./.github/actions/setup-rust with: - targets: armv7-linux-androideabi aarch64-linux-android x86_64-linux-android + targets: armv7-linux-androideabi aarch64-linux-android x86_64-linux-android i686-linux-android - uses: actions/setup-java@v4 with: distribution: oracle @@ -60,7 +60,7 @@ jobs: run: | KEYSTORE_PATH=$(pwd)/app/keystore.jks echo -n "$KEYSTORE_BASE64" | base64 --decode > $KEYSTORE_PATH - ./gradlew --info assembleRelease bundleRelease + ./gradlew --info bundleRelease - name: Run Test run: | # TODO: See https://github.com/firezone/firezone/issues/2311 diff --git a/kotlin/android/app/build.gradle.kts b/kotlin/android/app/build.gradle.kts index 473f63afe..cc5cab5c9 100644 --- a/kotlin/android/app/build.gradle.kts +++ b/kotlin/android/app/build.gradle.kts @@ -1,5 +1,6 @@ plugins { id("com.android.application") + id("org.mozilla.rust-android-gradle.rust-android") id("com.google.dagger.hilt.android") id("com.google.gms.google-services") id("com.google.firebase.crashlytics") @@ -32,6 +33,8 @@ spotless { } } +apply(plugin = "org.mozilla.rust-android-gradle.rust-android") + android { buildFeatures { buildConfig = true @@ -39,6 +42,7 @@ android { namespace = "dev.firezone.android" compileSdk = 34 + ndkVersion = "25.2.9519653" defaultConfig { applicationId = "dev.firezone.android" @@ -135,9 +139,6 @@ dependencies { val coreVersion = "1.12.0" val navVersion = "2.7.4" - // Connlib - implementation(project(":connlib")) - // AndroidX implementation("androidx.core:core-ktx:$coreVersion") implementation("androidx.appcompat:appcompat:1.6.1") @@ -199,3 +200,22 @@ dependencies { implementation("com.google.firebase:firebase-analytics-ktx") implementation("com.google.firebase:firebase-installations-ktx") } + +cargo { + if (gradle.startParameter.taskNames.any { it.lowercase().contains("release") }) { + profile = "release" + } else { + profile = "debug" + } + prebuiltToolchains = true + verbose = true + module = "../../../rust/connlib/clients/android" + libname = "connlib" + targets = listOf("arm", "arm64", "x86_64", "x86") + targetDirectory = "../../../rust/target" +} + +tasks.matching { it.name.matches(Regex("merge.*JniLibFolders")) }.configureEach { + inputs.dir(File(buildDir, "rustJniLibs/android")) + dependsOn("cargoBuild") +} diff --git a/kotlin/android/app/src/main/java/dev/firezone/android/core/presentation/MainActivity.kt b/kotlin/android/app/src/main/java/dev/firezone/android/core/presentation/MainActivity.kt index 71005e80c..263d913c2 100644 --- a/kotlin/android/app/src/main/java/dev/firezone/android/core/presentation/MainActivity.kt +++ b/kotlin/android/app/src/main/java/dev/firezone/android/core/presentation/MainActivity.kt @@ -8,6 +8,13 @@ import dev.firezone.android.R @AndroidEntryPoint internal class MainActivity : AppCompatActivity(R.layout.activity_main) { + // fail fast if the native library is not loaded + companion object { + init { + System.loadLibrary("connlib") + } + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) } diff --git a/kotlin/android/app/src/main/java/dev/firezone/android/tunnel/TunnelManager.kt b/kotlin/android/app/src/main/java/dev/firezone/android/tunnel/TunnelManager.kt index a70a4f80d..ee07beddb 100644 --- a/kotlin/android/app/src/main/java/dev/firezone/android/tunnel/TunnelManager.kt +++ b/kotlin/android/app/src/main/java/dev/firezone/android/tunnel/TunnelManager.kt @@ -4,7 +4,6 @@ package dev.firezone.android.tunnel import android.content.Context import android.content.Intent import android.content.SharedPreferences -import android.util.Log import dev.firezone.android.core.data.PreferenceRepository import dev.firezone.android.tunnel.callback.TunnelListener import dev.firezone.android.tunnel.data.TunnelRepository @@ -92,11 +91,5 @@ internal class TunnelManager internal companion object { private const val TAG: String = "TunnelManager" - - init { - Log.d(TAG, "Attempting to load library from main app...") - System.loadLibrary("connlib") - Log.d(TAG, "Library loaded from main app!") - } } } diff --git a/kotlin/android/build.gradle.kts b/kotlin/android/build.gradle.kts index 5b4fc17ff..77580c0e4 100644 --- a/kotlin/android/build.gradle.kts +++ b/kotlin/android/build.gradle.kts @@ -15,7 +15,6 @@ buildscript { plugins { id("org.jetbrains.kotlin.android") version "1.8.22" apply false id("com.android.application") version "8.2.0" apply false - id("com.android.library") version "8.2.0" apply false id("com.google.firebase.appdistribution") version "4.0.1" apply false id("com.google.dagger.hilt.android") version "2.50" apply false id("com.google.gms.google-services") version "4.4.0" apply false diff --git a/kotlin/android/settings.gradle.kts b/kotlin/android/settings.gradle.kts index beacae95c..fc66f8328 100644 --- a/kotlin/android/settings.gradle.kts +++ b/kotlin/android/settings.gradle.kts @@ -16,8 +16,6 @@ dependencyResolutionManagement { rootProject.name = "Firezone App" include(":app") -include(":connlib") -project(":connlib").projectDir = file("../../rust/connlib/clients/android/connlib") buildCache { local { diff --git a/rust/connlib/clients/android/connlib/build.gradle.kts b/rust/connlib/clients/android/connlib/build.gradle.kts deleted file mode 100644 index 131bb72d2..000000000 --- a/rust/connlib/clients/android/connlib/build.gradle.kts +++ /dev/null @@ -1,126 +0,0 @@ -plugins { - id("org.mozilla.rust-android-gradle.rust-android") - id("com.android.library") - id("kotlin-android") - id("org.jetbrains.kotlin.android") -} - -android { - namespace = "dev.firezone.connlib" - compileSdk = 34 - - defaultConfig { - minSdk = 30 - consumerProguardFiles("consumer-rules.pro") - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - } - externalNativeBuild { - cmake { - version = "3.22.1" - } - } - ndkVersion = "25.2.9519653" - buildTypes { - getByName("release") { - // Won't build if set to true - isMinifyEnabled = false - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") - } - } - compileOptions { - sourceCompatibility(JavaVersion.VERSION_17) - targetCompatibility(JavaVersion.VERSION_17) - } - kotlinOptions { - jvmTarget = "17" - } - publishing { - singleVariant("release") - } - sourceSets["main"].jniLibs { - srcDir("jniLibs") - } -} - -dependencies { - implementation("androidx.core:core-ktx:1.7.0") - implementation("androidx.test.ext:junit-gtest:1.0.0-alpha01") - implementation("com.android.ndk.thirdparty:googletest:1.11.0-beta-1") - implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) - implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.22") - testImplementation("junit:junit:4.13.2") - androidTestImplementation("androidx.test.ext:junit:1.1.3") - androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0") -} - -apply(plugin = "org.mozilla.rust-android-gradle.rust-android") - -fun copyJniShared(task: Task, buildType: String) = task.apply { - outputs.upToDateWhen { false } - - val jniTargets = mapOf( - "armv7-linux-androideabi" to "armeabi-v7a", - "aarch64-linux-android" to "arm64-v8a", - "i686-linux-android" to "x86", - "x86_64-linux-android" to "x86_64", - ) - - jniTargets.forEach { entry -> - val soFile = File( - project.projectDir.parentFile.parentFile.parentFile.parentFile, - "target/${entry.key}/$buildType/libconnlib.so", - ) - val targetDir = File(project.projectDir, "/jniLibs/${entry.value}").apply { - if (!exists()) { - mkdirs() - } - } - - copy { - with( - copySpec { - from(soFile) - }, - ) - into(targetDir) - } - } -} - -cargo { - // TODO: Read the build variant from the android plugin instead - if (gradle.startParameter.taskNames.any{it.lowercase().contains("release")}) { - profile = "release" - } else { - profile = "debug" - } - prebuiltToolchains = true - verbose = true - module = "../" - libname = "connlib" - targets = listOf("arm", "arm64", "x86_64") - targetDirectory = "../../../../target" - targetIncludes = arrayOf("connlib.dylib") -} - -tasks.register("copyJniSharedObjectsDebug") { - copyJniShared(this, "debug") -} - -tasks.register("copyJniSharedObjectsRelease") { - copyJniShared(this, "release") -} - -tasks.whenTaskAdded { - if (name.startsWith("javaPreCompile")) { - val newTasks = arrayOf( - tasks.named("cargoBuild"), - if (name.endsWith("Debug")) { - tasks.named("copyJniSharedObjectsDebug") - } else { - tasks.named("copyJniSharedObjectsRelease") - }, - ) - dependsOn(*newTasks) - } -} diff --git a/rust/connlib/clients/android/connlib/src/main/AndroidManifest.xml b/rust/connlib/clients/android/connlib/src/main/AndroidManifest.xml deleted file mode 100644 index 8bdb7e14b..000000000 --- a/rust/connlib/clients/android/connlib/src/main/AndroidManifest.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - -