From 3068939d93ebd0e1a4d8c5de1fa2bab4a4385d37 Mon Sep 17 00:00:00 2001 From: Shihaam Abdul Rahman Date: Fri, 13 Mar 2026 22:58:15 +0500 Subject: [PATCH] build isodrive is missing during apk build --- app/build.gradle.kts | 112 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 745ffb0..c2c8797 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -4,6 +4,118 @@ plugins { alias(libs.plugins.kotlin.compose) } +// Build isodrive native binary from submodule (only if binaries are missing) +val buildIsodrive by tasks.registering { + group = "native" + description = "Build isodrive binary for all Android architectures" + + val isodriveDir = rootProject.file("isodrive") + val outputDir = file("src/main/assets/bin") + val architectures = listOf("arm64-v8a", "armeabi-v7a", "x86_64", "x86") + + // Check if all binaries exist + val allBinariesExist = architectures.all { arch -> + outputDir.resolve("$arch/isodrive").exists() + } + + // Skip if all binaries already exist + onlyIf { !allBinariesExist } + + doLast { + // Verify submodule is initialized + if (!isodriveDir.resolve("src").exists()) { + throw GradleException("isodrive submodule not initialized. Run: git submodule update --init") + } + + val sourceFiles = listOf( + "src/util.cpp", + "src/configfsisomanager.cpp", + "src/androidusbisomanager.cpp", + "src/main.cpp" + ) + val srcs = sourceFiles.joinToString(" ") { "$isodriveDir/$it" } + val cflags = "-I$isodriveDir/src/include -static-libstdc++ -Os -s" + + val compilers = mapOf( + "arm64-v8a" to "aarch64-linux-android26-clang++", + "armeabi-v7a" to "armv7a-linux-androideabi26-clang++", + "x86_64" to "x86_64-linux-android26-clang++", + "x86" to "i686-linux-android26-clang++" + ) + + // Check if we're on NixOS (nix-shell available) + val useNixShell = File("/etc/NIXOS").exists() || + Runtime.getRuntime().exec(arrayOf("which", "nix-shell")).waitFor() == 0 + + if (useNixShell) { + println("NixOS detected, using nix-shell for NDK...") + + // Build all architectures in one nix-shell invocation + val buildScript = compilers.entries.joinToString("\n") { (arch, compiler) -> + val archDir = outputDir.resolve(arch) + val output = archDir.resolve("isodrive") + if (output.exists()) { + "echo 'isodrive for $arch already exists, skipping'" + } else { + """ + mkdir -p "$archDir" + echo "Building isodrive for $arch..." + "${'$'}TOOLCHAIN/$compiler" $cflags $srcs -o "$output" + """.trimIndent() + } + } + + exec { + environment("SRCS", srcs) + environment("CFLAGS", cflags) + environment("NIXPKGS_ALLOW_UNFREE", "1") + commandLine("nix-shell", "-p", "androidenv.androidPkgs.ndk-bundle", "--run", """ + SDK_ROOT=${'$'}(find /nix/store -maxdepth 1 -name "*android-sdk-ndk*" -type d 2>/dev/null | head -1) + NDK=${'$'}(ls -d "${'$'}SDK_ROOT/libexec/android-sdk/ndk/"* | head -1) + TOOLCHAIN="${'$'}NDK/toolchains/llvm/prebuilt/linux-x86_64/bin" + echo "Using NDK: ${'$'}NDK" + $buildScript + echo "Done building isodrive" + """.trimIndent()) + } + } else { + // Standard NDK lookup for non-NixOS + val ndkDir = listOfNotNull( + System.getenv("ANDROID_NDK_HOME"), + System.getenv("ANDROID_NDK") + ).firstOrNull { File(it).exists() } + ?: throw GradleException("Android NDK not found. Set ANDROID_NDK_HOME or install NDK via SDK Manager.") + + val toolchain = "$ndkDir/toolchains/llvm/prebuilt/linux-x86_64/bin" + if (!File(toolchain).exists()) { + throw GradleException("NDK toolchain not found at: $toolchain") + } + + compilers.forEach { (arch, compiler) -> + val archDir = outputDir.resolve(arch) + val output = archDir.resolve("isodrive") + + if (output.exists()) { + println("isodrive for $arch already exists, skipping") + return@forEach + } + + archDir.mkdirs() + println("Building isodrive for $arch...") + exec { + commandLine("sh", "-c", "$toolchain/$compiler $cflags $srcs -o $output") + } + } + println("Done building isodrive") + } + } +} + +// Hook into the build process - build isodrive before merging assets +tasks.matching { it.name.startsWith("merge") && it.name.endsWith("Assets") }.configureEach { + dependsOn(buildIsodrive) +} + android { namespace = "sh.sar.isodroid" compileSdk = 36