nandi/libjavapublic Fork 0
main
Commits
Clone
git clone https://git.rickub.com/nandi/libjava.git
git clone ssh://git@rickub.com/nandi/libjava.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

justfile · 124 lines · 4.5 KBMakefile Blame HistoryRaw
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# libjava — embed a JVM in a Nim process and call Java from it, via JNI
#
# The nimble tasks remain the source of truth; these recipes are thin wrappers
# so the common loop is one word. `just -l` lists everything.

default: test

# Compile the example Java classes into build/classes
java:
    nimble java

# Run the test suite (compiles the Java fixtures first)
test:
    nimble test

# Run the example program
demo:
    nimble demo

# Resolve the Clojure classpath from deps.edn into build/clojure-classpath
clojure-cp:
    #!/usr/bin/env bash
    set -euo pipefail
    mkdir -p build
    clojure -Spath > build/clojure-classpath

# Run the Clojure interop example (needs the `clojure` CLI on PATH)
clojure: clojure-cp
    nim c -r --path:src examples/clojure_demo.nim

# Compile the example binary into out/ (release build, nothing left in-tree)
build: java
    nim c -d:release --path:src --nimcache:build/nimcache -o:out/demo examples/demo.nim

# Type-check the library without producing a binary
check:
    #!/usr/bin/env bash
    set -euo pipefail
    # `nim check` does not run `staticExec`, so config.nim's PATH-based JDK
    # fallback is unavailable there — resolve the home here and pass it in.
    home="${JAVA_HOME:-$(dirname "$(dirname "$(readlink -f "$(command -v javac)")")")}"
    nim check --path:src -d:javaHome="$home" src/libjava.nim

# Build the library's documentation into build/docs
docs:
    nim doc --project --index:on --outdir:build/docs --path:src src/libjava.nim

# Remove build outputs and compiled test/example binaries
clean:
    rm -rf build nimcache out .cpcache
    rm -f tests/tlibjava examples/demo

# Print the JDK this build will link against
jdk:
    #!/usr/bin/env bash
    set -euo pipefail
    d=$(mktemp -d)
    trap 'rm -rf "$d"' EXIT
    printf 'import libjava/config\necho javaHome\n' > "$d/jdk.nim"
    nim c -r --path:src --hints:off -d:libjavaNoLink --nimcache:"$d/cache" -o:"$d/jdk" "$d/jdk.nim"

# The AppImage carries its own jlink'd Java runtime, so the demo binary is
# linked against $ORIGIN/../lib/jvm rather than the build machine's JDK.
# appimagetool is downloaded to build/tools on first use; set APPIMAGETOOL to
# point at your own copy instead.
#
# Bundle the example into a self-contained AppImage in out/
appimage: java
    #!/usr/bin/env bash
    set -euo pipefail
    home="${JAVA_HOME:-$(dirname "$(dirname "$(readlink -f "$(command -v javac)")")")}"
    arch=$(uname -m)

    tool="${APPIMAGETOOL:-build/tools/appimagetool}"
    if [ ! -x "$tool" ]; then
        mkdir -p "$(dirname "$tool")"
        curl -fsSL -o "$tool" \
            "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-$arch.AppImage"
        chmod +x "$tool"
    fi

    rm -rf build/AppDir
    mkdir -p build/AppDir/usr/bin build/AppDir/build

    # A minimal runtime: the demo only touches java.base.
    "$home/bin/jlink" --add-modules java.base \
        --strip-debug --no-header-files --no-man-pages --compress=2 \
        --output build/AppDir/usr/lib/jvm

    # Headers from the build JDK; libjvm resolved next to the binary at runtime.
    # (nim links through a shell, so $ORIGIN needs escaping twice over.)
    nim c -d:release --path:src -d:libjavaNoLink --nimcache:build/nimcache \
        --passL:"-L$home/lib/server -ljvm -Wl,-rpath,\\\$ORIGIN/../lib/jvm/lib/server" \
        -o:build/AppDir/usr/bin/demo examples/demo.nim

    # demo.nim looks for its classes at the relative path build/classes,
    # so AppRun runs from the AppDir root.
    cp -r build/classes build/AppDir/build/classes

    printf '%s\n' \
        '#!/usr/bin/env bash' \
        'cd "$(dirname "$(readlink -f "$0")")"' \
        'exec ./usr/bin/demo "$@"' > build/AppDir/AppRun
    chmod +x build/AppDir/AppRun

    printf '%s\n' \
        '[Desktop Entry]' \
        'Type=Application' \
        'Name=libjava demo' \
        'Exec=AppRun' \
        'Icon=libjava-demo' \
        'Categories=Development;' \
        'Terminal=true' > build/AppDir/libjava-demo.desktop

    printf '%s\n' \
        '<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">' \
        '  <rect width="256" height="256" rx="32" fill="#1b1f23"/>' \
        '  <text x="128" y="164" font-family="sans-serif" font-size="104"' \
        '        font-weight="bold" fill="#ffe873" text-anchor="middle">Jn</text>' \
        '</svg>' > build/AppDir/libjava-demo.svg
    ln -sf libjava-demo.svg build/AppDir/.DirIcon

    mkdir -p out
    ARCH="$arch" "$tool" build/AppDir "out/libjava-demo-$arch.AppImage"