diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..107d01d --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,71 @@ +name: Release + +on: + push: + tags: + - "v*" + +jobs: + build_release: + name: NIF ${{ matrix.nif }} - ${{ matrix.job.target }} + runs-on: ${{ matrix.job.os }} + strategy: + fail-fast: false + matrix: + nif: ["2.15", "2.16", "2.17"] + job: + - { target: aarch64-apple-darwin, os: macos-latest } + - { target: x86_64-apple-darwin, os: macos-13 } + - { target: x86_64-unknown-linux-gnu, os: ubuntu-22.04 } + - { target: aarch64-unknown-linux-gnu, os: ubuntu-24.04-arm } + + steps: + - uses: actions/checkout@v4 + + - name: Install libraw (macOS) + if: runner.os == 'macOS' + run: brew install libraw + + - name: Install libraw (Linux) + if: runner.os == 'Linux' + run: | + sudo apt-get update -q + sudo apt-get install -y libraw-dev + + - name: Build precompiled NIF + id: build + uses: philss/rustler-precompiled-action@v1 + with: + project-name: libraw_nif + project-version: ${{ github.ref_name }} + target: ${{ matrix.job.target }} + nif-version: ${{ matrix.nif }} + project-dir: "native/libraw_nif" + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ steps.build.outputs.file-name }} + path: ${{ steps.build.outputs.file-path }} + + release: + name: Publish GitHub Release + runs-on: ubuntu-latest + needs: build_release + permissions: + contents: write + steps: + - uses: actions/checkout@v4 + + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + merge-multiple: true + + - name: Create GitHub Release + uses: softprops/action-gh-release@v1 + with: + draft: false + generate_release_notes: true + files: artifacts/** diff --git a/CHANGELOG.md b/CHANGELOG.md index 54f4720..a2400c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,34 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.0] - 2026-05-16 + +### Added + +- Precompiled NIF binaries via `rustler_precompiled`. Supported targets: + `aarch64-apple-darwin`, `x86_64-apple-darwin`, `x86_64-unknown-linux-gnu`, + `aarch64-unknown-linux-gnu`. Users on these platforms no longer need a Rust + toolchain installed. +- `.github/workflows/release.yml`: GitHub Actions workflow that builds and + uploads NIF artifacts on every `v*` tag push. Runs on native macOS and Linux + ARM/x86 runners; `brew install libraw` / `apt install libraw-dev` installs + the required shared library into the build environment. +- `LIBRAW_BUILD=1` env-var opt-in for forcing a local source build (useful for + development or unsupported targets). + +### Changed + +- `lib/lib_raw/nif.ex` now uses `RustlerPrecompiled` instead of plain `Rustler`. + The libraw system library is still required at runtime on every platform + (dynamic linking, LGPL). +- Installation docs updated: version constraint bumped to `~> 0.3`, new + "Supported Platforms" table, Rust prerequisite scoped to source-build cases. + +### Notes + +- MUSL / Alpine Linux is intentionally excluded: libraw is not reliable on + musl libc. + ## [0.2.0] - 2026-05-02 ### Fixed @@ -49,5 +77,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Thin `wrapper.c` shim avoids bindgen / struct-offset breakage across libraw 0.20 / 0.21 / 0.22. +[0.3.0]: https://github.com/qweliant/libraw/compare/v0.2.0...v0.3.0 [0.2.0]: https://github.com/qweliant/libraw/compare/v0.1.0...v0.2.0 [0.1.0]: https://github.com/qweliant/libraw/releases/tag/v0.1.0 diff --git a/README.md b/README.md index 3116730..8bd2fd7 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ An Elixir library for native camera RAW decoding on the BEAM, powered by a ## Prerequisites -libraw must be installed before compiling or running `:libraw`: +**libraw must be installed** on every machine that runs `:libraw` — including +machines that use the precompiled NIF: ```bash # macOS @@ -21,6 +22,11 @@ apt install libraw-dev > library. See the [libraw license](https://www.libraw.org/license) for > details. +A **Rust toolchain is not required** for the targets listed under *Supported +Platforms* below. For unsupported targets the package falls back to compiling +the NIF from source, which requires Rust and the libraw headers above. You can +also opt into a source build explicitly with `LIBRAW_BUILD=1`. + ## Installation Add `:libraw` to your `mix.exs` dependencies: @@ -28,11 +34,27 @@ Add `:libraw` to your `mix.exs` dependencies: ```elixir def deps do [ - {:libraw, "~> 0.1"} + {:libraw, "~> 0.3"} ] end ``` +### Supported Platforms + +Precompiled NIF binaries are downloaded automatically for: + +| Target | Platform | +|--------|----------| +| `aarch64-apple-darwin` | macOS (Apple Silicon) | +| `x86_64-apple-darwin` | macOS (Intel) | +| `x86_64-unknown-linux-gnu` | Linux x86\_64 (Debian, Ubuntu, …) | +| `aarch64-unknown-linux-gnu` | Linux ARM64 | + +MUSL / Alpine Linux is not supported — libraw is not reliable on musl libc. + +**Forcing a source build:** set `LIBRAW_BUILD=1` before `mix deps.compile`. +You will also need [Rust installed](https://rustup.rs) and `libraw-dev` headers. + ## Usage ### Decode a RAW file @@ -97,7 +119,7 @@ end lib/ lib_raw.ex Public API: decode/2, metadata/1, gamma resolution, timestamp parsing lib_raw/ - nif.ex use Rustler + NIF stubs (nif_not_loaded fallbacks) + nif.ex use RustlerPrecompiled + NIF stubs (nif_not_loaded fallbacks) native/ libraw_nif/ Cargo.toml deps: rustler = "0.33"; build-deps: cc = "1", pkg-config = "0.3" diff --git a/lib/lib_raw/nif.ex b/lib/lib_raw/nif.ex index 86846b9..c891482 100644 --- a/lib/lib_raw/nif.ex +++ b/lib/lib_raw/nif.ex @@ -1,7 +1,21 @@ defmodule LibRaw.NIF do @moduledoc false - use Rustler, otp_app: :libraw, crate: "libraw_nif" + version = Mix.Project.config()[:version] + + use RustlerPrecompiled, + otp_app: :libraw, + crate: "libraw_nif", + version: version, + base_url: "https://github.com/qweliant/libraw/releases/download/v#{version}", + nif_versions: ["2.15", "2.16", "2.17"], + targets: ~w( + aarch64-apple-darwin + x86_64-apple-darwin + x86_64-unknown-linux-gnu + aarch64-unknown-linux-gnu + ), + force_build: System.get_env("LIBRAW_BUILD") in ["1", "true"] # Called on dirty CPU scheduler — decoding RAW files takes 100-500ms. @spec decode_nif(String.t(), integer(), integer(), integer(), float(), float()) :: diff --git a/mix.exs b/mix.exs index 704f281..dfc380b 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule LibRaw.MixProject do use Mix.Project - @version "0.2.0" + @version "0.3.0" @source_url "https://github.com/qweliant/libraw" def project do