NickelEval.jl

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

commit 091a0bab3f0b4bc4b253b835995e6fe85f4eb4ff
parent 54843f914e87a1396604d96ee9205f36d0accfbc
Author: Erik Loualiche <eloualic@umn.edu>
Date:   Sat,  7 Feb 2026 09:24:53 -0600

Add pre-built FFI artifact support for cross-platform distribution

- Add Artifacts.toml with platform-specific binary downloads
  (aarch64-darwin, x86_64-darwin, x86_64-linux, x86_64-windows)
- Update ffi.jl to load library from artifact or local deps/
- Add Artifacts and LazyArtifacts dependencies
- Bump version to 0.5.0

Artifacts are lazy-loaded from GitHub Releases on first use.

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

Diffstat:
AArtifacts.toml | 47+++++++++++++++++++++++++++++++++++++++++++++++
MProject.toml | 4+++-
Msrc/ffi.jl | 38+++++++++++++++++++++++++++++++-------
3 files changed, 81 insertions(+), 8 deletions(-)

diff --git a/Artifacts.toml b/Artifacts.toml @@ -0,0 +1,47 @@ +# Pre-built FFI library binaries +# Built by GitHub Actions: .github/workflows/build-ffi.yml +# Release: https://github.com/LouLouLibs/NickelEval/releases/tag/v0.5.0 + +# macOS Apple Silicon (aarch64) +[[libnickel_jl]] +arch = "aarch64" +git-tree-sha1 = "650aae37b4208762e0f4d7134b7bf53cd2faa4a4" +os = "macos" +lazy = true + + [[libnickel_jl.download]] + url = "https://github.com/LouLouLibs/NickelEval/releases/download/v0.5.0/libnickel_jl-aarch64-apple-darwin.tar.gz" + sha256 = "9f6f6fb4336221a10d7445caf5abad4980e71c92d55bfdbf7a402fbd76cddaa1" + +# macOS Intel (x86_64) +[[libnickel_jl]] +arch = "x86_64" +git-tree-sha1 = "c16dc26899c353f310833867f8609076f136af76" +os = "macos" +lazy = true + + [[libnickel_jl.download]] + url = "https://github.com/LouLouLibs/NickelEval/releases/download/v0.5.0/libnickel_jl-x86_64-apple-darwin.tar.gz" + sha256 = "e2a93fe247286efa553c2e5ce5d2cce01fc591741b3ae730c12f708f6dfc9857" + +# Linux x86_64 +[[libnickel_jl]] +arch = "x86_64" +git-tree-sha1 = "f5c565d2115df3f94ebb6e3cc964240630502826" +os = "linux" +lazy = true + + [[libnickel_jl.download]] + url = "https://github.com/LouLouLibs/NickelEval/releases/download/v0.5.0/libnickel_jl-x86_64-linux-gnu.tar.gz" + sha256 = "2ca510ee4ac8df02ed04d510a00c8d986098fdc2a75af1bb6d3e7b16eff11aeb" + +# Windows x86_64 +[[libnickel_jl]] +arch = "x86_64" +git-tree-sha1 = "e412ae6fcf306a603a4ae17222f31746f2622045" +os = "windows" +lazy = true + + [[libnickel_jl.download]] + url = "https://github.com/LouLouLibs/NickelEval/releases/download/v0.5.0/nickel_jl-x86_64-windows.tar.gz" + sha256 = "c1279f0b3fe202b366acf7a635f3c6da59704bab49470619e8f5d91267241fe7" diff --git a/Project.toml b/Project.toml @@ -1,10 +1,12 @@ name = "NickelEval" uuid = "a1b2c3d4-e5f6-7890-abcd-ef1234567890" authors = ["NickelJL Contributors"] -version = "0.4.0" +version = "0.5.0" [deps] +Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +LazyArtifacts = "4af54fe1-eca0-43a8-85a7-787d91b784e3" [compat] JSON = "0.21, 1" diff --git a/src/ffi.jl b/src/ffi.jl @@ -11,10 +11,9 @@ # - 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. + +using Artifacts +using LazyArtifacts # Determine platform-specific library name const LIB_NAME = if Sys.iswindows() @@ -25,11 +24,36 @@ else "libnickel_jl.so" end -# Path to the compiled library (local deps/ folder) -const LIB_PATH = joinpath(@__DIR__, "..", "deps", LIB_NAME) +# Find library path: try artifact first, then local deps/ +function _find_library_path() + artifact_toml = joinpath(@__DIR__, "..", "Artifacts.toml") + + # Try artifact (Julia auto-selects platform based on arch/os in Artifacts.toml) + if isfile(artifact_toml) + try + artifact_dir = @artifact_str("libnickel_jl", artifact_toml) + lib_path = joinpath(artifact_dir, LIB_NAME) + if isfile(lib_path) + return lib_path + end + catch e + # Artifact not available (lazy artifact not downloaded, or platform not supported) + end + end + + # Fall back to local deps/ folder (for development) + local_path = joinpath(@__DIR__, "..", "deps", LIB_NAME) + if isfile(local_path) + return local_path + end + + return nothing +end + +const LIB_PATH = _find_library_path() # Check if FFI library is available -const FFI_AVAILABLE = isfile(LIB_PATH) +const FFI_AVAILABLE = LIB_PATH !== nothing # Binary protocol type tags (must match Rust definitions) const TYPE_NULL = 0x00