diff --git a/.gitignore b/.gitignore index 04ad0610..ff217dc8 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,9 @@ target .cargo/ app/src/main/jniLibs macos/cert.pem -linux/Grim.AppDir/AppRun +linux/Goblin.AppDir/AppRun .intentionally-empty-file.o Cargo.toml-e screenshots/ +# GRIM-canonical build toolchains fetched by scripts/toolchain.sh +.toolchains/ diff --git a/linux/build_release.sh b/linux/build_release.sh index 09127722..bf9437c8 100755 --- a/linux/build_release.sh +++ b/linux/build_release.sh @@ -21,14 +21,24 @@ esac BASEDIR=$(cd "$(dirname "$0")" && pwd) cd "${BASEDIR}/.." +# Prefer the GRIM-canonical toolchains (zig + appimagetool from code.gri.mw/DEV); +# scripts/toolchain.sh fetches them and writes this env. Falls back to system +# installs when it's absent. +[ -f .toolchains/env.sh ] && source .toolchains/env.sh + rustup target add "${arch}" command -v cargo-zigbuild >/dev/null || cargo install cargo-zigbuild -# Portable cross-build to glibc 2.17. Two zig-specific fixes: +# Portable cross-build to glibc 2.17. Three zig-specific fixes: # - CRoaring's AVX512 path won't compile under zig's clang (evex512 error). # - OpenSSL is vendored in Cargo.toml, so no system libssl is needed. +# - v4l2-sys (camera/QR backend) runs bindgen over linux/videodev2.h, a kernel +# UAPI header missing from zig 0.12.1's glibc-2.17 sysroot; point bindgen at +# the host's kernel headers. This only reads struct layouts — the actual libc +# linkage stays glibc-2.17, so portability is unaffected. export CFLAGS_x86_64_unknown_linux_gnu="-DCROARING_COMPILER_SUPPORTS_AVX512=0" export CXXFLAGS_x86_64_unknown_linux_gnu="-DCROARING_COMPILER_SUPPORTS_AVX512=0" +export BINDGEN_EXTRA_CLANG_ARGS="${BINDGEN_EXTRA_CLANG_ARGS:-} -I/usr/include" cargo zigbuild --release --target "${arch}.2.17" # Assemble the AppDir: AppRun IS the goblin binary (Nym SDK linked in), plus the @@ -39,5 +49,9 @@ chmod +x "${appdir}/AppRun" out="target/${arch}/release/Goblin-${platform}.AppImage" rm -f "target/${arch}/release/"*.AppImage -ARCH=x86_64 appimagetool "${appdir}" "${out}" +# Use the DEV appimagetool + type2 runtime when fetched, else the system tool. +appimagetool_bin="${GOBLIN_APPIMAGETOOL:-appimagetool}" +runtime_arg=() +[ -n "${GOBLIN_APPIMAGE_RUNTIME:-}" ] && runtime_arg=(--runtime-file "${GOBLIN_APPIMAGE_RUNTIME}") +ARCH=x86_64 "${appimagetool_bin}" "${runtime_arg[@]}" "${appdir}" "${out}" echo "built: ${out}" diff --git a/scripts/android.sh b/scripts/android.sh index 81af9274..cb545ef9 100755 --- a/scripts/android.sh +++ b/scripts/android.sh @@ -24,6 +24,11 @@ BASEDIR=$(cd "$(dirname "$0")" && pwd) cd "${BASEDIR}" || exit 1 cd .. +# Prefer the GRIM-canonical toolchain: the custom NDK r29 (rebuilt LLVM, 16 KB +# page-aligned) + Android SDK from code.gri.mw/DEV. scripts/toolchain.sh fetches +# them and writes this env; falls back to whatever NDK/SDK is on the system. +[ -f .toolchains/env.sh ] && source .toolchains/env.sh + # Install platforms and tools rustup target add armv7-linux-androideabi rustup target add aarch64-linux-android diff --git a/scripts/toolchain.sh b/scripts/toolchain.sh new file mode 100755 index 00000000..d3fe6403 --- /dev/null +++ b/scripts/toolchain.sh @@ -0,0 +1,125 @@ +#!/bin/bash +# +# Fetch the canonical GRIM build toolchains (code.gri.mw/DEV) into .toolchains/. +# +# These mirror exactly what upstream GRIM's CI uses, so Goblin cross-builds every +# platform from one Linux box the same way GRIM does — instead of relying on +# whatever NDK/zig/appimagetool happens to be installed on the machine. +# +# Idempotent: each tool is skipped if already present. Linux x86_64 host only +# (the box we build releases on). Writes .toolchains/env.sh with the exports the +# build scripts source; run nothing else by hand. +# +# Usage: +# scripts/toolchain.sh # core: ndk zig appimage (what desktop+android need) +# scripts/toolchain.sh sdk gradle # add the Android SDK + Gradle +# scripts/toolchain.sh osxcross # build the macOS cross-toolchain (heavy) +# scripts/toolchain.sh all # everything +# +set -euo pipefail + +BASEDIR=$(cd "$(dirname "$0")/.." && pwd) +TC="${BASEDIR}/.toolchains" +DEV="https://code.gri.mw/DEV" +mkdir -p "${TC}" + +dl() { echo " ↓ $(basename "$2")"; curl -fSL --retry 3 -o "$2" "$1"; } + +# Pinned versions — bump here to track GRIM's DEV releases. +NDK_TAG="r29"; NDK_ARCHIVE="android-ndk-${NDK_TAG}-x86_64-linux-musl.tar.xz"; NDK_DIR="${TC}/android-ndk-${NDK_TAG}" +ZIG_VER="0.12.1"; ZIG_DIR="${TC}/zig" +AT_VER="1.9.1"; RT_TAG="20251108" +SDK_TAG="r36"; SDK_DIR="${TC}/android-sdk" +GRADLE_VER="8.13"; GRADLE_DIR="${TC}/gradle-${GRADLE_VER}" +SDK_VER="12.3"; OSX_DIR="${TC}/osxcross" + +fetch_ndk() { + [ -e "${NDK_DIR}/source.properties" ] && { echo "ndk r29: present"; return; } + echo "ndk: fetching custom NDK ${NDK_TAG} (rebuilt LLVM, 16 KB-aligned)…" + dl "${DEV}/android-ndk-custom/releases/download/${NDK_TAG}/${NDK_ARCHIVE}" "${TC}/ndk.tar.xz" + tar -xJf "${TC}/ndk.tar.xz" -C "${TC}"; rm -f "${TC}/ndk.tar.xz" +} + +fetch_zig() { + [ -x "${ZIG_DIR}/zig" ] && { echo "zig ${ZIG_VER}: present"; return; } + echo "zig: fetching ${ZIG_VER} (linker for cargo-zigbuild)…" + dl "${DEV}/zig/releases/download/${ZIG_VER}/zig-linux-x86_64-${ZIG_VER}.tar.xz" "${TC}/zig.tar.xz" + tar -xJf "${TC}/zig.tar.xz" -C "${TC}"; rm -f "${TC}/zig.tar.xz" + rm -rf "${ZIG_DIR}"; mv "${TC}/zig-linux-x86_64-${ZIG_VER}" "${ZIG_DIR}" +} + +fetch_appimage() { + [ -x "${TC}/appimagetool" ] && [ -e "${TC}/runtime-x86_64" ] && { echo "appimagetool ${AT_VER}: present"; return; } + echo "appimage: fetching appimagetool ${AT_VER} + type2 runtime…" + dl "${DEV}/appimagetool/releases/download/${AT_VER}/appimagetool-x86_64.AppImage" "${TC}/appimagetool" + dl "${DEV}/appimage-type2-runtime/releases/download/${RT_TAG}/runtime-x86_64" "${TC}/runtime-x86_64" + chmod +x "${TC}/appimagetool" "${TC}/runtime-x86_64" +} + +# Assemble a minimal Android SDK (build-tools + platform + platform-tools) from +# the DEV mirror so gradle has an SDK without a system install. +fetch_sdk() { + [ -d "${SDK_DIR}/platform-tools" ] && { echo "android-sdk ${SDK_TAG}: present"; return; } + echo "android-sdk: fetching build-tools + platform-36 + platform-tools (${SDK_TAG})…" + local base="${DEV}/android-platform-tools/releases/download/${SDK_TAG}" + mkdir -p "${SDK_DIR}/build-tools" "${SDK_DIR}/platforms" + dl "${base}/build-tools_r36.1_linux.zip" "${TC}/bt.zip" + dl "${base}/platform-36_r02.zip" "${TC}/pf.zip" + dl "${base}/platform-tools_r36.0.0-linux.zip" "${TC}/pt.zip" + # build-tools zip unzips to android-NN/ → rename to the version dir gradle wants. + local tmp; tmp=$(mktemp -d) + unzip -q "${TC}/bt.zip" -d "${tmp}"; mv "${tmp}"/*/ "${SDK_DIR}/build-tools/36.1.0" + unzip -q "${TC}/pf.zip" -d "${tmp}"; mv "${tmp}"/*/ "${SDK_DIR}/platforms/android-36" + unzip -q "${TC}/pt.zip" -d "${SDK_DIR}" + rm -rf "${tmp}" "${TC}/bt.zip" "${TC}/pf.zip" "${TC}/pt.zip" +} + +fetch_gradle() { + [ -x "${GRADLE_DIR}/bin/gradle" ] && { echo "gradle ${GRADLE_VER}: present"; return; } + echo "gradle: fetching ${GRADLE_VER}…" + dl "${DEV}/gradle/releases/download/v${GRADLE_VER}/gradle-${GRADLE_VER}-bin.zip" "${TC}/gradle.zip" + unzip -q "${TC}/gradle.zip" -d "${TC}"; rm -f "${TC}/gradle.zip" +} + +# osxcross: build the macOS cross-toolchain from source + the DEV macOS SDK. +# Heavy (compiles cctools/ld64); enables building macOS binaries off-Mac. CI also +# builds macOS natively, so this is the local/offline path — experimental. +fetch_osxcross() { + [ -x "${OSX_DIR}/target/bin/o64-clang" ] && { echo "osxcross: present"; return; } + command -v clang >/dev/null || { echo "osxcross: needs system clang/cmake — skipping"; return; } + echo "osxcross: cloning + building with macOS SDK ${SDK_VER} (slow)…" + [ -d "${OSX_DIR}/.git" ] || git clone --depth 1 "${DEV}/osxcross" "${OSX_DIR}" + dl "${DEV}/macosx-sdks/releases/download/${SDK_VER}/MacOSX${SDK_VER}.sdk.tar.xz" "${OSX_DIR}/tarballs/MacOSX${SDK_VER}.sdk.tar.xz" + ( cd "${OSX_DIR}" && UNATTENDED=1 ./build.sh ) +} + +write_env() { + { + echo "# Auto-generated by scripts/toolchain.sh — source me for GRIM-canonical builds." + [ -e "${NDK_DIR}/source.properties" ] && { echo "export ANDROID_NDK_HOME=\"${NDK_DIR}\""; echo "export ANDROID_NDK_ROOT=\"${NDK_DIR}\""; } + [ -d "${SDK_DIR}/platform-tools" ] && echo "export ANDROID_HOME=\"${SDK_DIR}\"" + local p="${TC}" + [ -x "${ZIG_DIR}/zig" ] && p="${ZIG_DIR}:${p}" + [ -x "${GRADLE_DIR}/bin/gradle" ] && p="${GRADLE_DIR}/bin:${p}" + [ -x "${OSX_DIR}/target/bin/o64-clang" ] && p="${OSX_DIR}/target/bin:${p}" + echo "export PATH=\"${p}:\$PATH\"" + echo "export GOBLIN_APPIMAGETOOL=\"${TC}/appimagetool\"" + echo "export GOBLIN_APPIMAGE_RUNTIME=\"${TC}/runtime-x86_64\"" + } > "${TC}/env.sh" +} + +tools=("$@"); [ ${#tools[@]} -eq 0 ] && tools=(ndk zig appimage) +[ "${tools[0]:-}" = "all" ] && tools=(ndk zig appimage sdk gradle osxcross) +for t in "${tools[@]}"; do + case "$t" in + ndk) fetch_ndk ;; + zig) fetch_zig ;; + appimage) fetch_appimage ;; + sdk) fetch_sdk ;; + gradle) fetch_gradle ;; + osxcross) fetch_osxcross ;; + *) echo "unknown tool: $t (ndk|zig|appimage|sdk|gradle|osxcross|all)" >&2; exit 1 ;; + esac +done +write_env +echo "toolchain ready → ${TC}/env.sh"