Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -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/**
29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
28 changes: 25 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -21,18 +22,39 @@ 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:

```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
Expand Down Expand Up @@ -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"
Expand Down
16 changes: 15 additions & 1 deletion lib/lib_raw/nif.ex
Original file line number Diff line number Diff line change
@@ -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()) ::
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
@@ -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
Expand Down