#!/bin/sh # 관리자 지시 (10/20): Android (arm64) 에서 HWP · HWPX 를 PDF 로 바꿔 앱의 보기 화면으로 연다 - rhwp (Rust, MIT) 를 # tool/rhwp_ffi (얇은 C ABI) 와 함께 NDK 로 빌드해 third_party/rhwp/android/arm64-v8a/libjj_rhwp.so 로 둔다 (rsync · 7zz 와 같은 방식 - # APK 의 jniLibs 로 들어가 앱이 dart:ffi 로 읽는다). # 소스: https://github.com/edwardkim/rhwp v0.8.7 = 커밋 1a76570 (고정 - git 커밋 해시가 내용의 SHA-1 지문이다, 고치지 않음). # 저장소가 크므로 (예제 문서 · PDF 로 4GB 넘음) 빌드에 쓰는 폴더만 받는다 (git sparse, 깊이 1). # 라이선스: rhwp MIT (LICENSE) · 의존 crate 들 (THIRD_PARTY_LICENSES.md) - 둘 다 third_party/rhwp 에 함께 둔다. # 도구: Rust 1.93.1 (rhwp 의 rust-toolchain.toml 과 같음, tools/rust - RUSTUP_HOME · CARGO_HOME) + Android NDK clang (링커). # Windows 에서는 호스트 쪽 (빌드 스크립트) 을 MSVC 로 링크하므로 tools/VSBuildTools 의 vcvars64 환경을 읽어 온다. # 16KB 쪽 기기 (Android 15+) 에서도 읽히게 -z max-page-size=16384, 다시 만들어도 같은 파일이 되게 경로를 /jj 로 바꿔 적는다. # 의존 crate 판은 tool/rhwp_ffi/Cargo.lock 으로 고정 (--locked). # 사용법 (Git Bash): sh tool/build_rhwp_android.sh - Android NDK 가 필요 (ANDROID_NDK 또는 tools/android-sdk/ndk/*) # 다시 만들어지는지 보기: JJ_RHWP_CHECK=1 sh tool/build_rhwp_android.sh (깨끗한 target 으로 두 번 빌드해 해시를 견줌) set -e APP=$(cd "$(dirname "$0")/.." && pwd) TOOLS=$(cd "$APP/.." && pwd)/tools VER=0.8.7 REV=1a76570e833917d15817415a53c09ad61ab3203f NDK_ROOT=${ANDROID_NDK:-$(ls -d "$TOOLS"/android-sdk/ndk/* | sort | tail -1)} case "$(uname -s)" in MINGW*|MSYS*|CYGWIN*) HOST=windows-x86_64; EXE=.exe; CMD=.cmd ;; Darwin) HOST=darwin-x86_64; EXE=; CMD= ;; *) HOST=linux-x86_64; EXE=; CMD= ;; esac TC=$NDK_ROOT/toolchains/llvm/prebuilt/$HOST/bin export RUSTUP_HOME=${RUSTUP_HOME:-$TOOLS/rust/rustup} export CARGO_HOME=${CARGO_HOME:-$TOOLS/rust/cargo} export PATH="$CARGO_HOME/bin:$PATH" # Windows: 호스트 링커 (MSVC) 환경 if [ "$HOST" = windows-x86_64 ] && [ -z "$VCINSTALLDIR" ]; then VC=$(cygpath -w "$TOOLS/VSBuildTools/VC/Auxiliary/Build/vcvars64.bat") ENVF=$(mktemp) # cmd 에 따옴표를 넘기면 Git Bash 가 바꿔 버려, 부를 것을 .cmd 파일로 적어 그것을 돌린다 BAT=$(mktemp --suffix=.cmd) printf '@call "%s" >nul\r\n@set\r\n' "$VC" > "$BAT" cmd //c "$(cygpath -w "$BAT")" | tr -d '\r' > "$ENVF" rm -f "$BAT" while IFS='=' read -r k v; do case "$k" in Path|PATH) PATH="$(cygpath -u -p "$v"):$PATH" ;; LIB|LIBPATH|INCLUDE|VCINSTALLDIR|VCToolsInstallDir|WindowsSdkDir|WindowsSDKVersion|UCRTVersion|UniversalCRTSdkDir) export "$k=$v" ;; esac done < "$ENVF" rm -f "$ENVF" export PATH [ -n "$VCINSTALLDIR" ] || { echo "vcvars64 환경을 읽지 못함: $VC"; exit 1; } fi # 작업 폴더: tools 아래 (빌드 캐시가 수 GB - 시스템 임시 폴더 (C:) 가 모자라 시험이 실패했다, 10/20). 다시 빌드할 때 이어 쓴다 WORK=${JJ_RHWP_WORK:-$TOOLS/src/rhwp/build} mkdir -p "$WORK" SRC=$WORK/rhwp if [ "$(git -C "$SRC" rev-parse HEAD 2>/dev/null)" != "$REV" ]; then rm -rf "$SRC" git init -q "$SRC" git -C "$SRC" remote add origin https://github.com/edwardkim/rhwp.git git -C "$SRC" sparse-checkout init --no-cone printf '%s\n' '/*' '!/samples/' '!/pdf/' '!/mydocs/' '!/saved/' '!/tests/' '!/gym/' '!/rhwp-*/' '!/npm/' '!/typescript/' \ '!/tools/' '!/fuzz/' '!/scripts/' '/saved/blank2010.hwp' '/mydocs/manual/' '/mydocs/tech/' > "$SRC/.git/info/sparse-checkout" git -C "$SRC" fetch -q --depth 1 --filter=blob:none origin "$REV" git -C "$SRC" checkout -q FETCH_HEAD fi [ "$(git -C "$SRC" rev-parse HEAD)" = "$REV" ] || { echo "rhwp 커밋이 다름"; exit 1; } [ -z "$(git -C "$SRC" status --porcelain)" ] || { echo "rhwp 소스가 바뀌어 있음"; exit 1; } rm -rf "$WORK/ffi" cp -r "$APP/tool/rhwp_ffi" "$WORK/ffi" # 처음 한 번: 의존 판을 rhwp 의 Cargo.lock 그대로 이어받아 tool/rhwp_ffi/Cargo.lock 을 만든다 (그 뒤로는 --locked) LOCKED=--locked if [ ! -f "$APP/tool/rhwp_ffi/Cargo.lock" ]; then cp "$SRC/Cargo.lock" "$WORK/ffi/Cargo.lock" LOCKED= fi export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="$TC/aarch64-linux-android24-clang$CMD" export CC_aarch64_linux_android="$TC/aarch64-linux-android24-clang$CMD" export AR_aarch64_linux_android="$TC/llvm-ar$EXE" W=$WORK [ "$HOST" = windows-x86_64 ] && W=$(cygpath -m "$WORK") export RUSTFLAGS="-C link-arg=-Wl,-z,max-page-size=16384 -C link-arg=-Wl,--build-id=none --remap-path-prefix=$W=/jj --remap-path-prefix=$(cygpath -m "$CARGO_HOME" 2>/dev/null || echo "$CARGO_HOME")=/cargo" export JJ_RHWP_VERSION=$VER build() { cargo build -q --release $LOCKED --target aarch64-linux-android --manifest-path "$WORK/ffi/Cargo.toml" --target-dir "$1" "$TC/llvm-strip$EXE" -o "$2" "$1/aarch64-linux-android/release/libjj_rhwp.so" } OUT="$APP/third_party/rhwp/android/arm64-v8a" mkdir -p "$OUT" build "$WORK/target" "$OUT/libjj_rhwp.so" [ -n "$LOCKED" ] || cp "$WORK/ffi/Cargo.lock" "$APP/tool/rhwp_ffi/Cargo.lock" cp "$SRC/LICENSE" "$OUT/../LICENSE.txt" cp "$SRC/THIRD_PARTY_LICENSES.md" "$OUT/../THIRD_PARTY_LICENSES.md" if [ -n "$JJ_RHWP_CHECK" ]; then rm -rf "$WORK/target2" build "$WORK/target2" "$WORK/again.so" A=$(sha256sum < "$OUT/libjj_rhwp.so"); B=$(sha256sum < "$WORK/again.so") [ "$A" = "$B" ] && echo "다시 만들어도 같음" || { echo "다시 만들면 다름: $A / $B"; exit 1; } fi ls -l "$OUT/libjj_rhwp.so" sha256sum "$OUT/libjj_rhwp.so"