NickelEval.jl

Julia FFI bindings for Nickel configuration language
Log | Files | Refs | README | LICENSE

commit aabb74fa8742ee15333e565f44e7b516a956afd8
parent 28f54198377db4ab8d54190558f45cdd4f8c18fb
Author: Erik Loualiche <eloualic@umn.edu>
Date:   Fri,  6 Feb 2026 22:49:54 -0600

Add GitHub Actions workflow for cross-platform FFI builds

Prepare for distributing pre-built FFI binaries:
- Add build-ffi.yml workflow to build for Linux, macOS, Windows
- Update TODO with artifacts distribution plan
- Improve FFI error message

The workflow will create release artifacts when a tag is pushed.
Artifacts.toml will be added once first release is built.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Diffstat:
A.github/workflows/build-ffi.yml | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MTODO.md | 27+++++++++++++++++++++++----
Msrc/ffi.jl | 11+++++++++--
3 files changed, 119 insertions(+), 6 deletions(-)

diff --git a/.github/workflows/build-ffi.yml b/.github/workflows/build-ffi.yml @@ -0,0 +1,87 @@ +name: Build FFI Library + +on: + push: + tags: + - 'v*' + workflow_dispatch: + +jobs: + build: + strategy: + matrix: + include: + - os: ubuntu-latest + target: x86_64-unknown-linux-gnu + artifact: libnickel_jl.so + artifact_name: libnickel_jl-x86_64-linux-gnu.tar.gz + - os: ubuntu-24.04-arm + target: aarch64-unknown-linux-gnu + artifact: libnickel_jl.so + artifact_name: libnickel_jl-aarch64-linux-gnu.tar.gz + - os: macos-13 + target: x86_64-apple-darwin + artifact: libnickel_jl.dylib + artifact_name: libnickel_jl-x86_64-apple-darwin.tar.gz + - os: macos-latest + target: aarch64-apple-darwin + artifact: libnickel_jl.dylib + artifact_name: libnickel_jl-aarch64-apple-darwin.tar.gz + - os: windows-latest + target: x86_64-pc-windows-msvc + artifact: nickel_jl.dll + artifact_name: nickel_jl-x86_64-windows.tar.gz + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-action@stable + with: + targets: ${{ matrix.target }} + + - name: Build library + working-directory: rust/nickel-jl + run: cargo build --release --target ${{ matrix.target }} + + - name: Package artifact (Unix) + if: runner.os != 'Windows' + run: | + cd rust/nickel-jl/target/${{ matrix.target }}/release + tar -czvf ${{ matrix.artifact_name }} ${{ matrix.artifact }} + mv ${{ matrix.artifact_name }} ${{ github.workspace }}/ + + - name: Package artifact (Windows) + if: runner.os == 'Windows' + shell: bash + run: | + cd rust/nickel-jl/target/${{ matrix.target }}/release + tar -czvf ${{ matrix.artifact_name }} ${{ matrix.artifact }} + mv ${{ matrix.artifact_name }} ${{ github.workspace }}/ + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.artifact_name }} + path: ${{ matrix.artifact_name }} + + release: + needs: build + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/') + permissions: + contents: write + + steps: + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Create Release + uses: softprops/action-gh-release@v1 + with: + files: artifacts/**/*.tar.gz + generate_release_notes: true diff --git a/TODO.md b/TODO.md @@ -33,10 +33,29 @@ ## Next Steps -### 1. Cross-Platform FFI Distribution -Currently FFI requires local Rust build. Options: -- **BinaryBuilder.jl** - Create `NickelEval_jll` for automatic binary distribution -- Support Linux (x86_64, aarch64), macOS (x86_64, aarch64), Windows +### 1. Cross-Platform FFI Distribution (In Progress) + +**Current approach: Self-hosted artifacts via GitHub Releases** + +Status: +- [x] GitHub Actions workflow to build for all platforms (`.github/workflows/build-ffi.yml`) +- [x] Artifacts.toml template for binary downloads +- [x] Updated ffi.jl to use Pkg.Artifacts +- [ ] Trigger first build by tagging v0.5.0 +- [ ] Update Artifacts.toml with actual SHA256 hashes +- [ ] Test artifact downloads on all platforms + +Platforms: +- Linux x86_64, aarch64 +- macOS x86_64, aarch64 (Apple Silicon) +- Windows x86_64 + +**Fallback option: Yggdrasil/BinaryBuilder.jl** + +If self-hosted artifacts become hard to maintain, submit to Yggdrasil: +- Create `NickelEval_jll` package via BinaryBuilder.jl +- Automatic builds and distribution via General registry +- More complex setup but zero maintenance after ### 2. CI FFI Testing Update CI workflow to build Rust library and run FFI tests. diff --git a/src/ffi.jl b/src/ffi.jl @@ -11,6 +11,10 @@ # - No process spawn overhead # - Direct memory sharing # - Better performance for repeated evaluations +# +# Library loading: +# Currently requires local build. Future versions will include pre-built artifacts. +# See .github/workflows/build-ffi.yml for cross-platform build setup. # Determine platform-specific library name const LIB_NAME = if Sys.iswindows() @@ -21,7 +25,7 @@ else "libnickel_jl.so" end -# Path to the compiled library +# Path to the compiled library (local deps/ folder) const LIB_PATH = joinpath(@__DIR__, "..", "deps", LIB_NAME) # Check if FFI library is available @@ -252,7 +256,10 @@ end function _check_ffi_available() if !FFI_AVAILABLE - error("FFI not available. Build the Rust library with:\n" * + error("FFI library not available.\n\n" * + "The FFI functions require a pre-built native library.\n" * + "Use subprocess mode instead: nickel_eval() and nickel_eval_file()\n\n" * + "To build locally (requires Rust):\n" * " cd rust/nickel-jl && cargo build --release\n" * " mkdir -p deps && cp target/release/$LIB_NAME ../../deps/") end