Build bytecode compilers #2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build bytecode compilers | |
| # Builds the per-host bytecode compiler CLIs for every engine that supports | |
| # ahead-of-time bytecode, by cloning each engine's UPSTREAM repo (not the | |
| # android-runtime vendored sources) and building the CLI there. | |
| # | |
| # Output: one artifact per (engine, host), named `bytecode-compiler-<engine>-<host>`, | |
| # each containing `<engine>/<host>/<binary>` so the downloads merge straight into | |
| # tools/bytecode-compiler/bin/. | |
| # | |
| # NOTE ON COMPATIBILITY: the produced bytecode must be loadable by the engine | |
| # library the runtime ships. Hermes/PrimJS runtimes link prebuilt .so's and | |
| # QuickJS/QuickJS-NG compile from vendored source, so the refs below must be kept | |
| # in step with what the runtime actually bundles. Pin these to exact commits once | |
| # validated instead of moving branches. | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| hermes_ref: | |
| description: "facebook/hermes ref" | |
| default: "10a40b5f1de81d007cba6afe567c4ba7a0b45f5d" | |
| quickjs_ref: | |
| # MUST match the quickjs submodule pin (BC_VERSION must agree with the | |
| # runtime). See .gitmodules / scripts/vendor-engines-as-submodules.sh. | |
| description: "bellard/quickjs ref (match the submodule pin)" | |
| default: "04be246001599f5995fa2f2d8c91a0f198d3f34c" | |
| quickjs_ng_ref: | |
| # MUST match the quickjs_ng submodule pin (BC_VERSION must agree with the | |
| # runtime, or JS_ReadObject rejects the blob). See .gitmodules / | |
| # scripts/vendor-engines-as-submodules.sh. | |
| description: "quickjs-ng/quickjs ref (match the submodule pin)" | |
| default: "d950d55e950dd7994a96c669c31efa967b8b79f3" | |
| primjs_ref: | |
| description: "lynx-family/primjs ref" | |
| default: "9c1fe150179b86f0ae5c6fbe670af7d76eca9df6" | |
| env: | |
| HERMES_REPO: https://github.com/facebook/hermes | |
| QUICKJS_REPO: https://github.com/bellard/quickjs | |
| QUICKJS_NG_REPO: https://github.com/quickjs-ng/quickjs | |
| PRIMJS_REPO: https://github.com/lynx-family/primjs | |
| jobs: | |
| # --------------------------------------------------------------------------- | |
| # Hermes — `hermesc` already emits a loadable HBC blob; no shim needed. | |
| # --------------------------------------------------------------------------- | |
| hermes: | |
| name: hermes (${{ matrix.host }}) | |
| runs-on: ${{ matrix.runner }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - { host: linux-x64, runner: ubuntu-24.04 } | |
| - { host: linux-arm64, runner: ubuntu-24.04-arm } | |
| - { host: darwin-x64, runner: macos-13 } | |
| - { host: darwin-arm64, runner: macos-14 } | |
| - { host: win32-x64, runner: windows-2022 } | |
| - { host: win32-arm64, runner: windows-11-arm } | |
| steps: | |
| - name: Install toolchain (Linux) | |
| if: runner.os == 'Linux' | |
| run: sudo apt-get update && sudo apt-get install -y cmake ninja-build build-essential python3 | |
| - name: Install toolchain (macOS) | |
| if: runner.os == 'macOS' | |
| run: brew install cmake ninja | |
| - name: Install toolchain (Windows) | |
| if: runner.os == 'Windows' | |
| run: choco install ninja -y | |
| - name: Clone Hermes | |
| shell: bash | |
| # Fetch by ref so an exact commit SHA works (git clone --branch only | |
| # accepts branch/tag names). GitHub allows fetching arbitrary SHAs. | |
| run: | | |
| set -euxo pipefail | |
| ref="${{ github.event.inputs.hermes_ref || 'master' }}" | |
| git init hermes | |
| git -C hermes remote add origin "$HERMES_REPO" | |
| git -C hermes fetch --depth 1 origin "$ref" | |
| git -C hermes -c advice.detachedHead=false checkout FETCH_HEAD | |
| - name: Build hermesc (Unix) | |
| if: runner.os != 'Windows' | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| cmake -S hermes -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DHERMES_BUILD_APPLE_FRAMEWORK=OFF | |
| cmake --build build --target hermesc | |
| - name: Build hermesc (Windows) | |
| if: runner.os == 'Windows' | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| # Use the default (Visual Studio) generator; Ninja+MSVC also works if the | |
| # VS dev environment is on PATH. | |
| cmake -S hermes -B build -DCMAKE_BUILD_TYPE=Release | |
| cmake --build build --target hermesc --config Release | |
| - name: Stage binary | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| mkdir -p "out/hermes/${{ matrix.host }}" | |
| bin="$(find build -type f \( -name hermesc -o -name hermesc.exe \) | head -n1)" | |
| test -n "$bin" | |
| cp "$bin" "out/hermes/${{ matrix.host }}/" | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: bytecode-compiler-hermes-${{ matrix.host }} | |
| path: out/hermes/${{ matrix.host }} | |
| if-no-files-found: error | |
| # --------------------------------------------------------------------------- | |
| # QuickJS (bellard) — build the engine lib, then our blob-emitting shim. | |
| # --------------------------------------------------------------------------- | |
| quickjs: | |
| name: quickjs (${{ matrix.host }}) | |
| runs-on: ${{ matrix.runner }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - { host: linux-x64, runner: ubuntu-24.04 } | |
| - { host: linux-arm64, runner: ubuntu-24.04-arm } | |
| - { host: darwin-x64, runner: macos-13 } | |
| - { host: darwin-arm64, runner: macos-14 } | |
| - { host: win32-x64, runner: windows-2022 } | |
| - { host: win32-arm64, runner: windows-11-arm } | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install toolchain (Linux) | |
| if: runner.os == 'Linux' | |
| run: sudo apt-get update && sudo apt-get install -y build-essential | |
| - name: Install toolchain (Windows) | |
| if: runner.os == 'Windows' | |
| run: choco install llvm -y | |
| - name: Clone QuickJS | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| ref="${{ github.event.inputs.quickjs_ref || 'master' }}" | |
| git init quickjs | |
| git -C quickjs remote add origin "$QUICKJS_REPO" | |
| git -C quickjs fetch --depth 1 origin "$ref" | |
| git -C quickjs -c advice.detachedHead=false checkout FETCH_HEAD | |
| - name: Build shim | |
| shell: bash | |
| env: | |
| SHIM: ${{ github.workspace }}/tools/bytecode-compiler/native/qjs-compile.c | |
| run: | | |
| set -euxo pipefail | |
| cd quickjs | |
| CC="cc"; [ "${{ runner.os }}" = "Windows" ] && CC="clang" | |
| # Compile the lib sources directly (avoids qjs/qjsc main() collisions). | |
| # If bellard changes the source set, adjust this list. | |
| libsrc="quickjs.c cutils.c libregexp.c libunicode.c" | |
| [ -f dtoa.c ] && libsrc="$libsrc dtoa.c" | |
| out="../out/quickjs/${{ matrix.host }}"; mkdir -p "$out" | |
| bin="$out/nsbc-quickjs"; [ "${{ runner.os }}" = "Windows" ] && bin="$bin.exe" | |
| $CC -O2 -DNSBC_MAGIC='"NSBCQJS"' -I. -o "$bin" "$SHIM" $libsrc -lm | |
| "$bin" || true # usage line (exit 2) proves it links & runs | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: bytecode-compiler-quickjs-${{ matrix.host }} | |
| path: out/quickjs/${{ matrix.host }} | |
| if-no-files-found: error | |
| # --------------------------------------------------------------------------- | |
| # QuickJS-NG — CMake build of libqjs, then our shim (same JS_* API). | |
| # --------------------------------------------------------------------------- | |
| quickjs-ng: | |
| name: quickjs-ng (${{ matrix.host }}) | |
| runs-on: ${{ matrix.runner }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - { host: linux-x64, runner: ubuntu-24.04 } | |
| - { host: linux-arm64, runner: ubuntu-24.04-arm } | |
| - { host: darwin-x64, runner: macos-13 } | |
| - { host: darwin-arm64, runner: macos-14 } | |
| - { host: win32-x64, runner: windows-2022 } | |
| - { host: win32-arm64, runner: windows-11-arm } | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install toolchain (Linux) | |
| if: runner.os == 'Linux' | |
| run: sudo apt-get update && sudo apt-get install -y cmake ninja-build build-essential | |
| - name: Install toolchain (macOS) | |
| if: runner.os == 'macOS' | |
| run: brew install cmake ninja | |
| - name: Install toolchain (Windows) | |
| if: runner.os == 'Windows' | |
| run: choco install ninja llvm -y | |
| - name: Clone QuickJS-NG | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| ref="${{ github.event.inputs.quickjs_ng_ref || 'master' }}" | |
| git init quickjs-ng | |
| git -C quickjs-ng remote add origin "$QUICKJS_NG_REPO" | |
| git -C quickjs-ng fetch --depth 1 origin "$ref" | |
| git -C quickjs-ng -c advice.detachedHead=false checkout FETCH_HEAD | |
| - name: Build lib + shim | |
| shell: bash | |
| env: | |
| SHIM: ${{ github.workspace }}/tools/bytecode-compiler/native/qjs-compile.c | |
| run: | | |
| set -euxo pipefail | |
| cmake -S quickjs-ng -B quickjs-ng/build -DCMAKE_BUILD_TYPE=Release -DBUILD_QJS_LIBC=OFF | |
| cmake --build quickjs-ng/build --config Release | |
| lib="$(find quickjs-ng/build -type f \( -name 'libqjs.a' -o -name 'qjs.lib' \) | head -n1)" | |
| test -n "$lib" | |
| CC="cc"; [ "${{ runner.os }}" = "Windows" ] && CC="clang" | |
| out="out/quickjs-ng/${{ matrix.host }}"; mkdir -p "$out" | |
| bin="$out/nsbc-quickjs-ng"; [ "${{ runner.os }}" = "Windows" ] && bin="$bin.exe" | |
| $CC -O2 -DNSBC_MAGIC='"NSBCNGS"' -I quickjs-ng -o "$bin" "$SHIM" "$lib" -lm | |
| "$bin" || true | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: bytecode-compiler-quickjs-ng-${{ matrix.host }} | |
| path: out/quickjs-ng/${{ matrix.host }} | |
| if-no-files-found: error | |
| # --------------------------------------------------------------------------- | |
| # PrimJS — build the engine, then our LEPUS_* shim. | |
| # NOTE: PrimJS's build system is nonstandard; the steps below are best-effort | |
| # and will very likely need adjustment against lynx-family/primjs@develop | |
| # (its actual CMake targets / include + lib paths). Treat the first CI run as | |
| # the source of truth and pin once green. | |
| # --------------------------------------------------------------------------- | |
| primjs: | |
| name: primjs (${{ matrix.host }}) | |
| runs-on: ${{ matrix.runner }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - { host: linux-x64, runner: ubuntu-24.04 } | |
| - { host: linux-arm64, runner: ubuntu-24.04-arm } | |
| - { host: darwin-x64, runner: macos-13 } | |
| - { host: darwin-arm64, runner: macos-14 } | |
| - { host: win32-x64, runner: windows-2022 } | |
| - { host: win32-arm64, runner: windows-11-arm } | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install toolchain (Linux) | |
| if: runner.os == 'Linux' | |
| run: sudo apt-get update && sudo apt-get install -y cmake ninja-build build-essential python3 | |
| - name: Install toolchain (macOS) | |
| if: runner.os == 'macOS' | |
| run: brew install cmake ninja | |
| - name: Install toolchain (Windows) | |
| if: runner.os == 'Windows' | |
| run: choco install ninja llvm -y | |
| - name: Clone PrimJS | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| ref="${{ github.event.inputs.primjs_ref || 'develop' }}" | |
| git init primjs | |
| git -C primjs remote add origin "$PRIMJS_REPO" | |
| git -C primjs fetch --depth 1 origin "$ref" | |
| git -C primjs -c advice.detachedHead=false checkout FETCH_HEAD | |
| # PrimJS vendors deps via a script in some layouts; run it if present. | |
| if [ -f primjs/tools/hooks/generate_gni.py ]; then python3 primjs/tools/hooks/generate_gni.py || true; fi | |
| - name: Build engine + shim | |
| shell: bash | |
| env: | |
| SHIM: ${{ github.workspace }}/tools/bytecode-compiler/native/primjs-compile.c | |
| run: | | |
| set -euxo pipefail | |
| # Best-effort CMake build of the PrimJS/quickjs static lib. Adjust the | |
| # target and include/lib paths to match the repo once observed in CI. | |
| cmake -S primjs -B primjs/build -DCMAKE_BUILD_TYPE=Release || { | |
| echo "::warning::PrimJS cmake configure needs adjustment for this repo layout"; exit 1; } | |
| cmake --build primjs/build --config Release | |
| lib="$(find primjs/build -type f \( -name 'libquick*.a' -o -name 'libprimjs*.a' -o -name '*.lib' \) | head -n1)" | |
| inc="$(dirname "$(find primjs -name quickjs.h | head -n1)")" | |
| test -n "$lib" && test -n "$inc" | |
| CC="cc"; [ "${{ runner.os }}" = "Windows" ] && CC="clang" | |
| out="out/primjs/${{ matrix.host }}"; mkdir -p "$out" | |
| bin="$out/nsbc-primjs"; [ "${{ runner.os }}" = "Windows" ] && bin="$bin.exe" | |
| $CC -O2 -I"$inc" -o "$bin" "$SHIM" "$lib" -lm | |
| "$bin" || true | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: bytecode-compiler-primjs-${{ matrix.host }} | |
| path: out/primjs/${{ matrix.host }} | |
| if-no-files-found: error |