@@ -34,6 +34,20 @@ ANDROID_TARGETS=(
3434 " i686-linux-android"
3535)
3636
37+ # Get ABI name for a target
38+ get_abi_for_target () {
39+ local target=$1
40+ case " $target " in
41+ aarch64-linux-android) echo " arm64-v8a" ;;
42+ armv7-linux-androideabi) echo " armeabi-v7a" ;;
43+ x86_64-linux-android) echo " x86_64" ;;
44+ i686-linux-android) echo " x86" ;;
45+ * ) echo " " ;;
46+ esac
47+ }
48+
49+ MIN_API=21
50+
3751# Check for required tools
3852check_requirements () {
3953 log_info " Checking requirements..."
@@ -49,6 +63,16 @@ check_requirements() {
4963 fi
5064}
5165
66+ # Check and install cargo-ndk if needed
67+ check_cargo_ndk () {
68+ if ! command -v cargo-ndk & > /dev/null; then
69+ log_info " Installing cargo-ndk..."
70+ cargo install cargo-ndk --locked
71+ else
72+ log_info " cargo-ndk is already installed"
73+ fi
74+ }
75+
5276# Check Android NDK
5377check_android_ndk () {
5478 if [[ -z " $ANDROID_NDK_HOME " ]] && [[ -z " $NDK_HOME " ]]; then
@@ -76,65 +100,23 @@ install_targets() {
76100 done
77101}
78102
79- # Setup cargo config for Android NDK
80- setup_cargo_config () {
81- local ndk_home=" ${ANDROID_NDK_HOME:- $NDK_HOME } "
82- local config_dir=" ${PROJECT_ROOT} /.cargo"
83- local config_file=" ${config_dir} /config.toml"
84-
85- mkdir -p " $config_dir "
86-
87- # Detect host OS
88- local host_os
89- case " $OSTYPE " in
90- linux* ) host_os=" linux" ;;
91- darwin* ) host_os=" darwin" ;;
92- * ) host_os=" linux" ;;
93- esac
94-
95- # Find the NDK toolchain
96- local toolchain_dir=" ${ndk_home} /toolchains/llvm/prebuilt/${host_os} -x86_64"
97- if [[ ! -d " $toolchain_dir " ]]; then
98- log_error " NDK toolchain not found at: $toolchain_dir "
99- return 1
100- fi
101-
102- local min_api=21
103-
104- cat > " $config_file " << EOF
105- # Auto-generated cargo config for Android NDK
106- # NDK Path: $ndk_home
107-
108- [target.aarch64-linux-android]
109- ar = "${toolchain_dir} /bin/llvm-ar"
110- linker = "${toolchain_dir} /bin/aarch64-linux-android${min_api} -clang"
111-
112- [target.armv7-linux-androideabi]
113- ar = "${toolchain_dir} /bin/llvm-ar"
114- linker = "${toolchain_dir} /bin/armv7a-linux-androideabi${min_api} -clang"
115-
116- [target.x86_64-linux-android]
117- ar = "${toolchain_dir} /bin/llvm-ar"
118- linker = "${toolchain_dir} /bin/x86_64-linux-android${min_api} -clang"
119-
120- [target.i686-linux-android]
121- ar = "${toolchain_dir} /bin/llvm-ar"
122- linker = "${toolchain_dir} /bin/i686-linux-android${min_api} -clang"
123- EOF
124-
125- log_info " Cargo config written to: $config_file "
103+ # Build uniffi-bindgen for the host platform first
104+ build_uniffi_bindgen () {
105+ log_info " Building uniffi-bindgen for host platform..."
106+ cd " $PROJECT_ROOT "
107+ cargo build --features cli --bin uniffi-bindgen --release
126108}
127109
128- # Build for a specific target
129- build_target () {
110+ # Build for a specific Android target using cargo-ndk
111+ build_android_target () {
130112 local target=$1
131113 log_info " Building for target: $target "
132114
133115 cd " $PROJECT_ROOT "
134- cargo build --release --target " $target "
116+ cargo ndk --target " $target " --platform " $MIN_API " build --release
135117}
136118
137- # Generate Kotlin bindings
119+ # Generate Kotlin bindings using pre-built uniffi-bindgen
138120generate_bindings () {
139121 log_info " Generating Kotlin bindings..."
140122
@@ -150,26 +132,51 @@ generate_bindings() {
150132 local candidate=" ${PROJECT_ROOT} /target/${target} /release/libcooklang_find.so"
151133 if [[ -f " $candidate " ]]; then
152134 lib_path=" $candidate "
135+ log_info " Using library: $lib_path "
153136 break
154137 fi
155138 done
156139
157140 # Fall back to host target
158141 if [[ -z " $lib_path " ]]; then
142+ log_info " No Android library found, building for host..."
159143 cargo build --release
160144 lib_path=" ${PROJECT_ROOT} /target/release/libcooklang_find.so"
161145 if [[ ! -f " $lib_path " ]]; then
162146 lib_path=" ${PROJECT_ROOT} /target/release/libcooklang_find.dylib"
163147 fi
148+ if [[ ! -f " $lib_path " ]]; then
149+ log_error " Could not find built library"
150+ exit 1
151+ fi
164152 fi
165153
166- cargo run --release --features cli --bin uniffi-bindgen -- generate \
154+ # Use the pre-built uniffi-bindgen binary
155+ local bindgen=" ${PROJECT_ROOT} /target/release/uniffi-bindgen"
156+ if [[ ! -f " $bindgen " ]]; then
157+ log_info " uniffi-bindgen not found, building it..."
158+ build_uniffi_bindgen
159+ fi
160+
161+ log_info " Running uniffi-bindgen..."
162+ " $bindgen " generate \
167163 --library " $lib_path " \
168164 --language kotlin \
169165 --config " ${PROJECT_ROOT} /uniffi.toml" \
170166 --out-dir " $OUTPUT_DIR "
171167
168+ # Verify and show what was generated
172169 log_info " Kotlin bindings generated at: $OUTPUT_DIR "
170+ log_info " Generated files:"
171+ find " $OUTPUT_DIR " -name " *.kt" -type f
172+
173+ # Verify the expected structure exists
174+ if [[ ! -d " $OUTPUT_DIR /org" ]]; then
175+ log_error " Expected directory structure not created: $OUTPUT_DIR /org"
176+ log_error " Contents of $OUTPUT_DIR :"
177+ ls -la " $OUTPUT_DIR "
178+ exit 1
179+ fi
173180}
174181
175182# Create Android library structure
@@ -186,25 +193,15 @@ create_android_lib() {
186193 # Copy native libraries
187194 local copied=0
188195
189- if [[ -f " ${PROJECT_ROOT} /target/aarch64-linux-android/release/libcooklang_find.so" ]]; then
190- cp " ${PROJECT_ROOT} /target/aarch64-linux-android/release/libcooklang_find.so" " $jni_dir /arm64-v8a/"
191- copied=$(( copied + 1 ))
192- fi
193-
194- if [[ -f " ${PROJECT_ROOT} /target/armv7-linux-androideabi/release/libcooklang_find.so" ]]; then
195- cp " ${PROJECT_ROOT} /target/armv7-linux-androideabi/release/libcooklang_find.so" " $jni_dir /armeabi-v7a/"
196- copied=$(( copied + 1 ))
197- fi
198-
199- if [[ -f " ${PROJECT_ROOT} /target/x86_64-linux-android/release/libcooklang_find.so" ]]; then
200- cp " ${PROJECT_ROOT} /target/x86_64-linux-android/release/libcooklang_find.so" " $jni_dir /x86_64/"
201- copied=$(( copied + 1 ))
202- fi
203-
204- if [[ -f " ${PROJECT_ROOT} /target/i686-linux-android/release/libcooklang_find.so" ]]; then
205- cp " ${PROJECT_ROOT} /target/i686-linux-android/release/libcooklang_find.so" " $jni_dir /x86/"
206- copied=$(( copied + 1 ))
207- fi
196+ for target in " ${ANDROID_TARGETS[@]} " ; do
197+ local abi
198+ abi=$( get_abi_for_target " $target " )
199+ local so_file=" ${PROJECT_ROOT} /target/${target} /release/libcooklang_find.so"
200+ if [[ -f " $so_file " ]]; then
201+ cp " $so_file " " $jni_dir /$abi /"
202+ copied=$(( copied + 1 ))
203+ fi
204+ done
208205
209206 if [[ $copied -eq 0 ]]; then
210207 log_warn " No Android native libraries found to copy"
@@ -371,7 +368,7 @@ main() {
371368 echo " Usage: $0 [OPTIONS]"
372369 echo " "
373370 echo " Options:"
374- echo " --all Build for all Android architectures"
371+ echo " --all Build for all Android architectures (requires cargo-ndk) "
375372 echo " --generate-only Only generate Kotlin bindings (no compilation)"
376373 echo " --help, -h Show this help message"
377374 echo " "
@@ -389,18 +386,21 @@ main() {
389386
390387 check_requirements
391388
389+ # Always build uniffi-bindgen first (before any cross-compilation)
390+ build_uniffi_bindgen
391+
392392 if [[ " $generate_only " == true ]]; then
393393 generate_bindings
394394 exit 0
395395 fi
396396
397397 if [[ " $build_all " == true ]]; then
398398 if check_android_ndk; then
399+ check_cargo_ndk
399400 install_targets
400- setup_cargo_config
401401
402402 for target in " ${ANDROID_TARGETS[@]} " ; do
403- build_target " $target "
403+ build_android_target " $target "
404404 done
405405 else
406406 log_info " Building for host platform only..."
0 commit comments