Add `just appimage` to bundle the demo as a self-contained AppImage
The AppImage carries a jlink'd java.base runtime, so the demo binary is linked with an $ORIGIN-relative rpath instead of the build machine's JDK path. appimagetool is fetched to build/tools on first use. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
12f125f parent: 066bac4 modified
justfile +64 -0 | @@ -47,3 +47,67 @@ jdk: | ||
| 47 | 47 | trap 'rm -rf "$d"' EXIT |
| 48 | 48 | printf 'import libjava/config\necho javaHome\n' > "$d/jdk.nim" |
| 49 | 49 | nim c -r --path:src --hints:off -d:libjavaNoLink --nimcache:"$d/cache" -o:"$d/jdk" "$d/jdk.nim" |
| 50 | + | |
| 51 | +# The AppImage carries its own jlink'd Java runtime, so the demo binary is | |
| 52 | +# linked against $ORIGIN/../lib/jvm rather than the build machine's JDK. | |
| 53 | +# appimagetool is downloaded to build/tools on first use; set APPIMAGETOOL to | |
| 54 | +# point at your own copy instead. | |
| 55 | +# | |
| 56 | +# Bundle the example into a self-contained AppImage in out/ | |
| 57 | +appimage: java | |
| 58 | + #!/usr/bin/env bash | |
| 59 | + set -euo pipefail | |
| 60 | + home="${JAVA_HOME:-$(dirname "$(dirname "$(readlink -f "$(command -v javac)")")")}" | |
| 61 | + arch=$(uname -m) | |
| 62 | + | |
| 63 | + tool="${APPIMAGETOOL:-build/tools/appimagetool}" | |
| 64 | + if [ ! -x "$tool" ]; then | |
| 65 | + mkdir -p "$(dirname "$tool")" | |
| 66 | + curl -fsSL -o "$tool" \ | |
| 67 | + "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-$arch.AppImage" | |
| 68 | + chmod +x "$tool" | |
| 69 | + fi | |
| 70 | + | |
| 71 | + rm -rf build/AppDir | |
| 72 | + mkdir -p build/AppDir/usr/bin build/AppDir/build | |
| 73 | + | |
| 74 | + # A minimal runtime: the demo only touches java.base. | |
| 75 | + "$home/bin/jlink" --add-modules java.base \ | |
| 76 | + --strip-debug --no-header-files --no-man-pages --compress=2 \ | |
| 77 | + --output build/AppDir/usr/lib/jvm | |
| 78 | + | |
| 79 | + # Headers from the build JDK; libjvm resolved next to the binary at runtime. | |
| 80 | + # (nim links through a shell, so $ORIGIN needs escaping twice over.) | |
| 81 | + nim c -d:release --path:src -d:libjavaNoLink --nimcache:build/nimcache \ | |
| 82 | + --passL:"-L$home/lib/server -ljvm -Wl,-rpath,\\\$ORIGIN/../lib/jvm/lib/server" \ | |
| 83 | + -o:build/AppDir/usr/bin/demo examples/demo.nim | |
| 84 | + | |
| 85 | + # demo.nim looks for its classes at the relative path build/classes, | |
| 86 | + # so AppRun runs from the AppDir root. | |
| 87 | + cp -r build/classes build/AppDir/build/classes | |
| 88 | + | |
| 89 | + printf '%s\n' \ | |
| 90 | + '#!/usr/bin/env bash' \ | |
| 91 | + 'cd "$(dirname "$(readlink -f "$0")")"' \ | |
| 92 | + 'exec ./usr/bin/demo "$@"' > build/AppDir/AppRun | |
| 93 | + chmod +x build/AppDir/AppRun | |
| 94 | + | |
| 95 | + printf '%s\n' \ | |
| 96 | + '[Desktop Entry]' \ | |
| 97 | + 'Type=Application' \ | |
| 98 | + 'Name=libjava demo' \ | |
| 99 | + 'Exec=AppRun' \ | |
| 100 | + 'Icon=libjava-demo' \ | |
| 101 | + 'Categories=Development;' \ | |
| 102 | + 'Terminal=true' > build/AppDir/libjava-demo.desktop | |
| 103 | + | |
| 104 | + printf '%s\n' \ | |
| 105 | + '<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">' \ | |
| 106 | + ' <rect width="256" height="256" rx="32" fill="#1b1f23"/>' \ | |
| 107 | + ' <text x="128" y="164" font-family="sans-serif" font-size="104"' \ | |
| 108 | + ' font-weight="bold" fill="#ffe873" text-anchor="middle">Jn</text>' \ | |
| 109 | + '</svg>' > build/AppDir/libjava-demo.svg | |
| 110 | + ln -sf libjava-demo.svg build/AppDir/.DirIcon | |
| 111 | + | |
| 112 | + mkdir -p out | |
| 113 | + ARCH="$arch" "$tool" build/AppDir "out/libjava-demo-$arch.AppImage" | |
| @@ -47,3 +47,67 @@ jdk: | |||
| 47 | trap 'rm -rf "$d"' EXIT | 47 | trap 'rm -rf "$d"' EXIT |
| 48 | printf 'import libjava/config\necho javaHome\n' > "$d/jdk.nim" | 48 | printf 'import libjava/config\necho javaHome\n' > "$d/jdk.nim" |
| 49 | nim c -r --path:src --hints:off -d:libjavaNoLink --nimcache:"$d/cache" -o:"$d/jdk" "$d/jdk.nim" | 49 | nim c -r --path:src --hints:off -d:libjavaNoLink --nimcache:"$d/cache" -o:"$d/jdk" "$d/jdk.nim" |
| 50 | + | ||
| 51 | +# The AppImage carries its own jlink'd Java runtime, so the demo binary is | ||
| 52 | +# linked against $ORIGIN/../lib/jvm rather than the build machine's JDK. | ||
| 53 | +# appimagetool is downloaded to build/tools on first use; set APPIMAGETOOL to | ||
| 54 | +# point at your own copy instead. | ||
| 55 | +# | ||
| 56 | +# Bundle the example into a self-contained AppImage in out/ | ||
| 57 | +appimage: java | ||
| 58 | + #!/usr/bin/env bash | ||
| 59 | + set -euo pipefail | ||
| 60 | + home="${JAVA_HOME:-$(dirname "$(dirname "$(readlink -f "$(command -v javac)")")")}" | ||
| 61 | + arch=$(uname -m) | ||
| 62 | + | ||
| 63 | + tool="${APPIMAGETOOL:-build/tools/appimagetool}" | ||
| 64 | + if [ ! -x "$tool" ]; then | ||
| 65 | + mkdir -p "$(dirname "$tool")" | ||
| 66 | + curl -fsSL -o "$tool" \ | ||
| 67 | + "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-$arch.AppImage" | ||
| 68 | + chmod +x "$tool" | ||
| 69 | + fi | ||
| 70 | + | ||
| 71 | + rm -rf build/AppDir | ||
| 72 | + mkdir -p build/AppDir/usr/bin build/AppDir/build | ||
| 73 | + | ||
| 74 | + # A minimal runtime: the demo only touches java.base. | ||
| 75 | + "$home/bin/jlink" --add-modules java.base \ | ||
| 76 | + --strip-debug --no-header-files --no-man-pages --compress=2 \ | ||
| 77 | + --output build/AppDir/usr/lib/jvm | ||
| 78 | + | ||
| 79 | + # Headers from the build JDK; libjvm resolved next to the binary at runtime. | ||
| 80 | + # (nim links through a shell, so $ORIGIN needs escaping twice over.) | ||
| 81 | + nim c -d:release --path:src -d:libjavaNoLink --nimcache:build/nimcache \ | ||
| 82 | + --passL:"-L$home/lib/server -ljvm -Wl,-rpath,\\\$ORIGIN/../lib/jvm/lib/server" \ | ||
| 83 | + -o:build/AppDir/usr/bin/demo examples/demo.nim | ||
| 84 | + | ||
| 85 | + # demo.nim looks for its classes at the relative path build/classes, | ||
| 86 | + # so AppRun runs from the AppDir root. | ||
| 87 | + cp -r build/classes build/AppDir/build/classes | ||
| 88 | + | ||
| 89 | + printf '%s\n' \ | ||
| 90 | + '#!/usr/bin/env bash' \ | ||
| 91 | + 'cd "$(dirname "$(readlink -f "$0")")"' \ | ||
| 92 | + 'exec ./usr/bin/demo "$@"' > build/AppDir/AppRun | ||
| 93 | + chmod +x build/AppDir/AppRun | ||
| 94 | + | ||
| 95 | + printf '%s\n' \ | ||
| 96 | + '[Desktop Entry]' \ | ||
| 97 | + 'Type=Application' \ | ||
| 98 | + 'Name=libjava demo' \ | ||
| 99 | + 'Exec=AppRun' \ | ||
| 100 | + 'Icon=libjava-demo' \ | ||
| 101 | + 'Categories=Development;' \ | ||
| 102 | + 'Terminal=true' > build/AppDir/libjava-demo.desktop | ||
| 103 | + | ||
| 104 | + printf '%s\n' \ | ||
| 105 | + '<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">' \ | ||
| 106 | + ' <rect width="256" height="256" rx="32" fill="#1b1f23"/>' \ | ||
| 107 | + ' <text x="128" y="164" font-family="sans-serif" font-size="104"' \ | ||
| 108 | + ' font-weight="bold" fill="#ffe873" text-anchor="middle">Jn</text>' \ | ||
| 109 | + '</svg>' > build/AppDir/libjava-demo.svg | ||
| 110 | + ln -sf libjava-demo.svg build/AppDir/.DirIcon | ||
| 111 | + | ||
| 112 | + mkdir -p out | ||
| 113 | + ARCH="$arch" "$tool" build/AppDir "out/libjava-demo-$arch.AppImage" | ||