diff --git a/CrossCompileGitForAndroid.sh b/CrossCompileGitForAndroid.sh index 530ea90..5c99d98 100644 --- a/CrossCompileGitForAndroid.sh +++ b/CrossCompileGitForAndroid.sh @@ -9,7 +9,7 @@ NDK_DIR="$SDK_DIR/ndk/27.2.12479018" TOOLBIN="$NDK_DIR/toolchains/llvm/prebuilt/linux-x86_64/bin" TMP_DIR="$PROJECT_DIR/.tmp-android-build" GIT_SRC_DIR="$TMP_DIR/git-src" -ASSET_DIR="$PROJECT_DIR/app/src/main/assets/native-git/arm64-v8a" +JNI_LIB_DIR="$PROJECT_DIR/app/src/main/jniLibs/arm64-v8a" log() { printf '\n[%s] %s\n' "cross-compile" "$1" @@ -88,12 +88,12 @@ main() { readelf -h git | sed -n '1,20p' readelf -d git | sed -n '1,40p' - mkdir -p "$ASSET_DIR" - llvm-strip -s git -o "$ASSET_DIR/git" - chmod 755 "$ASSET_DIR/git" + mkdir -p "$JNI_LIB_DIR" + llvm-strip -s git -o "$JNI_LIB_DIR/libgit.so" + chmod 755 "$JNI_LIB_DIR/libgit.so" - log "Bundled stripped binary at: $ASSET_DIR/git" - ls -lh "$ASSET_DIR/git" + log "Bundled stripped binary at: $JNI_LIB_DIR/libgit.so" + ls -lh "$JNI_LIB_DIR/libgit.so" } main "$@" \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index de23f5b..31a78d8 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -11,8 +11,8 @@ android { applicationId = "com.kawomi.githugandroid" minSdk = 26 targetSdk = 34 - versionCode = 10 - versionName = "0.1.9" + versionCode = 11 + versionName = "0.1.10" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true diff --git a/app/src/main/java/com/kawomi/githugandroid/GitRuntime.kt b/app/src/main/java/com/kawomi/githugandroid/GitRuntime.kt index fb50c5e..968202b 100644 --- a/app/src/main/java/com/kawomi/githugandroid/GitRuntime.kt +++ b/app/src/main/java/com/kawomi/githugandroid/GitRuntime.kt @@ -2,6 +2,7 @@ package com.kawomi.githugandroid import android.os.Build import android.content.Context +import android.content.pm.ApplicationInfo import java.io.File class GitRepositoryRuntime(private val context: Context) { @@ -9,7 +10,7 @@ class GitRepositoryRuntime(private val context: Context) { private val extractedGitDir = File(context.filesDir, "native-git/bin") fun startupBanner(): String { - return if (ensureNativeGitBinary() != null) { + return if (nativeGitBinary() != null) { "Welcome to GitHug Android. Native Git prototype ready." } else { "Welcome to GitHug Android. Native Git binary not bundled for this ABI yet; using in-memory fallback." @@ -17,7 +18,7 @@ class GitRepositoryRuntime(private val context: Context) { } fun prepareLevel(level: Level): RepoState { - val nativeGit = ensureNativeGitBinary() + val nativeGit = nativeGitBinary() if (nativeGit == null) { return level.setup() } @@ -52,7 +53,7 @@ class GitRepositoryRuntime(private val context: Context) { } fun execute(level: Level, currentRepo: RepoState, command: String): Pair> { - val nativeGit = ensureNativeGitBinary() + val nativeGit = nativeGitBinary() if (nativeGit == null) { return GitSandboxEngine.execute(currentRepo, command) } @@ -78,7 +79,8 @@ class GitRepositoryRuntime(private val context: Context) { return buildList { addAll(GitSandboxEngine.commandReferenceLines()) add("Native Git prototype:") - add(" extracted binary path: files/native-git/bin/git") + add(" preferred binary path: nativeLibraryDir/libgit.so") + add(" fallback binary path: files/native-git/bin/git") add(" selected ABI: ${Build.SUPPORTED_ABIS.firstOrNull() ?: "unknown"}") add(" helper commands: ls, pwd, cat, touch, mkdir, rm, echo") } @@ -132,7 +134,7 @@ class GitRepositoryRuntime(private val context: Context) { private fun inspectSandbox(level: Level): RepoState { val sandbox = sandboxDir(level) - val nativeGit = ensureNativeGitBinary() + val nativeGit = nativeGitBinary() val filesOnDisk = sandbox.listFiles() ?.filter { it.isFile && it.name != ".git" } .orEmpty() @@ -180,7 +182,22 @@ class GitRepositoryRuntime(private val context: Context) { ) } - private fun ensureNativeGitBinary(): File? { + private fun nativeGitBinary(): File? { + val packaged = packagedNativeGitBinary() + if (packaged != null) { + return packaged + } + + return ensureExtractedAssetGitBinary() + } + + private fun packagedNativeGitBinary(): File? { + val nativeLibraryDir = context.applicationInfo.nativeLibraryDir ?: return null + val candidate = File(nativeLibraryDir, "libgit.so") + return candidate.takeIf { it.exists() && it.canExecute() } + } + + private fun ensureExtractedAssetGitBinary(): File? { val extracted = File(extractedGitDir, "git") if (extracted.exists() && extracted.canExecute()) { return extracted diff --git a/app/src/main/jniLibs/arm64-v8a/libgit.so b/app/src/main/jniLibs/arm64-v8a/libgit.so new file mode 100755 index 0000000..90532c8 Binary files /dev/null and b/app/src/main/jniLibs/arm64-v8a/libgit.so differ