Skip to content
Merged
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
24 changes: 22 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.6.4] - 2026-09-10

### Added
- **`-tags goffi_static`** — fully static Linux amd64/arm64 binaries under `CGO_ENABLED=0` by excluding all `//go:cgo_import_dynamic` directives (`libdl`/`libc`/`libpthread`). `ffi.LoadLibrary` / `GetSymbol` return `ffi.ErrStaticBuild`. ([#74](https://github.com/go-webgpu/goffi/issues/74), [gogpu#474](https://github.com/gogpu/gogpu/issues/474))
- **`-tags goffi_static`** — fully static Linux amd64/arm64 binaries under `CGO_ENABLED=0` by excluding all `//go:cgo_import_dynamic` directives (`libdl`/`libc`/`libpthread`). `ffi.LoadLibrary` / `GetSymbol` return `ffi.ErrStaticBuild`. ([#74](https://github.com/go-webgpu/goffi/issues/74), [gogpu#474](https://github.com/gogpu/gogpu/issues/474), [PR #78](https://github.com/go-webgpu/goffi/pull/78))
- **Linking modes** documented in README (dynamic FFI, musl dynamic, static no-FFI)
- **`scripts/check-elf-linking.sh`** — CI/helper asserts `PT_INTERP` / `DT_NEEDED` for default vs static profiles
- **`docs/ADR-001-userspace-elf-loader.md`** — research track for optional pure-Go ELF `.so` loader (preview, not default)
- **Struct pass/return examples** — `examples/struct/` + README section covering INTEGER/SSE/sret size classes ([#58](https://github.com/go-webgpu/goffi/issues/58), [PR #69](https://github.com/go-webgpu/goffi/pull/69))

### Changed
- **Docs: avalue double-indirection** — clarify out-pointer parameter pattern (`avalue[i]` must point to a pointer variable) in README and `docs/ARCHITECTURE.md` ([#79](https://github.com/go-webgpu/goffi/issues/79), [PR #80](https://github.com/go-webgpu/goffi/pull/80))
- README: star history chart ([PR #75](https://github.com/go-webgpu/goffi/pull/75))

## [0.6.3] - 2026-08-01

Expand Down Expand Up @@ -881,7 +888,20 @@ See [ROADMAP.md](ROADMAP.md) for detailed roadmap to v1.0.

---

[Unreleased]: https://github.com/go-webgpu/goffi/compare/v0.4.1...HEAD
[Unreleased]: https://github.com/go-webgpu/goffi/compare/v0.6.4...HEAD
[0.6.4]: https://github.com/go-webgpu/goffi/compare/v0.6.3...v0.6.4
[0.6.3]: https://github.com/go-webgpu/goffi/compare/v0.6.2...v0.6.3
[0.6.2]: https://github.com/go-webgpu/goffi/compare/v0.6.1...v0.6.2
[0.6.1]: https://github.com/go-webgpu/goffi/compare/v0.6.0...v0.6.1
[0.6.0]: https://github.com/go-webgpu/goffi/compare/v0.5.6...v0.6.0
[0.5.6]: https://github.com/go-webgpu/goffi/compare/v0.5.5...v0.5.6
[0.5.5]: https://github.com/go-webgpu/goffi/compare/v0.5.4...v0.5.5
[0.5.4]: https://github.com/go-webgpu/goffi/compare/v0.5.3...v0.5.4
[0.5.3]: https://github.com/go-webgpu/goffi/compare/v0.5.2...v0.5.3
[0.5.2]: https://github.com/go-webgpu/goffi/compare/v0.5.1...v0.5.2
[0.5.1]: https://github.com/go-webgpu/goffi/compare/v0.5.0...v0.5.1
[0.5.0]: https://github.com/go-webgpu/goffi/compare/v0.4.2...v0.5.0
[0.4.2]: https://github.com/go-webgpu/goffi/compare/v0.4.1...v0.4.2
[0.4.1]: https://github.com/go-webgpu/goffi/compare/v0.4.0...v0.4.1
[0.4.0]: https://github.com/go-webgpu/goffi/compare/v0.3.9...v0.4.0
[0.3.9]: https://github.com/go-webgpu/goffi/compare/v0.3.8...v0.3.9
Expand Down
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,12 @@ if err != nil {
| v0.4.1 | Released | ABI compliance audit — 10/11 gaps fixed |
| v0.4.2 | Released | purego compatibility (`-tags nofakecgo`) |
| v0.5.1 | Released | Struct ABI, CGO_ENABLED=1, 9-16B XMM return |
| **v0.6.0** | **In progress** | Variadic functions (`PrepareVariadicCallInterface`), builder API |
| v0.6.0 | Released | errno always-capture (`CallFunction` → `(Errno, error)`) |
| v0.6.1 | Released | Android ARM64 preview, fakecgo rename |
| v0.6.2 | Released | Windows scalar float returns |
| v0.6.3 | Released | ARM64 HFA checkptr + 9-16B struct return fix |
| **v0.6.4** | **Released** | `-tags goffi_static`, linking docs, struct examples |
| v0.7.0 | Planned | RegisterFunc / Builder API, C-ABI host profile (#81) |
| v1.0.0 | Planned | API stability (SemVer 2.0), security audit |

See [CHANGELOG.md](CHANGELOG.md) for version history and [ROADMAP.md](ROADMAP.md) for the full plan.
Expand All @@ -477,13 +482,15 @@ go test -v ./ffi # verbose, auto-detects platform

| Document | Description |
|----------|-------------|
| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | Technical architecture: assembly, ABIs, callbacks |
| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | Technical architecture: assembly, ABIs, callbacks, linking |
| [docs/PERFORMANCE.md](docs/PERFORMANCE.md) | Benchmarks, optimization strategies, Go 1.26 |
| [docs/ANDROID.md](docs/ANDROID.md) | Android ARM64 preview ABI + build notes |
| [docs/ADR-001-userspace-elf-loader.md](docs/ADR-001-userspace-elf-loader.md) | Research: optional pure-Go `.so` loader |
| [CHANGELOG.md](CHANGELOG.md) | Version history, migration guides |
| [ROADMAP.md](ROADMAP.md) | Development roadmap to v1.0 |
| [CONTRIBUTING.md](CONTRIBUTING.md) | Contribution guidelines |
| [SECURITY.md](SECURITY.md) | Security policy |
| [examples/](examples/) | Working code examples |
| [examples/](examples/) | Working code examples (`simple`, `struct`) |

---

Expand Down
21 changes: 13 additions & 8 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
> **Strategic Approach**: Build production-ready Zero-CGO FFI with benchmarked performance
> **Philosophy**: Performance first, usability second, platform coverage third

**Last Updated**: 2026-09-08 | **Current Version**: v0.6.3 | **Strategy**: Benchmarks → Callbacks → ARM64 → Runtime → ABI → v1.0 LTS | **Milestone**: v0.6.3 (HFA checkptr fix) → v0.7.0 `goffi_static` + RegisterFunc/Builder → v1.0.0 LTS
**Last Updated**: 2026-09-10 | **Current Version**: v0.6.4 | **Strategy**: Benchmarks → Callbacks → ARM64 → Runtime → ABI → v1.0 LTS | **Milestone**: v0.6.4 `goffi_static` → v0.7.0 RegisterFunc/Builder → v1.0.0 LTS

---

Expand Down Expand Up @@ -173,15 +173,19 @@ v1.0.0 LTS → Long-term support release (2027 Q1)
**v0.6.3** = ARM64 HFA checkptr fix ✅ RELEASED (2026-08-01)
- ARM64 `handleHFAReturn` checkptr crash fix (#67, reported by @jbunds)
- ARM64 9-16B struct return proactive fix (copy pattern)
- Struct pass/return examples and README section (#58)

**v0.7.0** = Static linking + RegisterFunc + Builder API (2026 Q3-Q4)
- `-tags goffi_static` fully static Linux ELFs (#74, gogpu#474) — shipped in PR #78
- Linking-mode docs + ELF CI gates
**v0.6.4** = Static linking profile + struct examples ✅ RELEASED (2026-09-10)
- `-tags goffi_static` fully static Linux ELFs (#74, gogpu#474) — PR #78
- Linking-mode docs + ELF CI gates (`scripts/check-elf-linking.sh`)
- ADR-001 userspace ELF loader (research)
- Struct pass/return examples (`examples/struct/`, #58 / PR #69)
- Docs: avalue out-pointer double-indirection (#79 / PR #80)

**v0.7.0** = RegisterFunc + Builder API (2026 Q3-Q4)
- RegisterFunc convenience API (ADR-008)
- Library struct + OpenLibraryBytes (ADR-009)
- NewFunc/Call/CallCtx ergonomic wrappers (ADR-009)
- Enterprise C-ABI / Rust-cdylib host profile ([#81](https://github.com/go-webgpu/goffi/issues/81))

**v1.0.0** = Long-term support release (2027 Q1)
- API stability guarantee
Expand All @@ -191,16 +195,17 @@ v1.0.0 LTS → Long-term support release (2027 Q1)

---

## 📊 Current Status (v0.6.3)
## 📊 Current Status (v0.6.4)

**Phase**: HFA checkptr fix, struct examples. 9 platforms. `goffi_static` in PR #78; planning RegisterFunc for v0.7.0
**Phase**: `goffi_static` linking profile shipped. 9 platforms. Next: RegisterFunc/Builder ergonomics for v0.7.0

**What Works**:
- ✅ Dynamic library loading (`LoadLibrary`, `GetSymbol`, `FreeLibrary`)
- ✅ Function call interface (`PrepareCallInterface`)
- ✅ Function execution (`CallFunction`, `CallFunctionContext`)
- ✅ **`-tags goffi_static`** — fully static Linux ELFs (FFI unavailable; `errors.Is(err, ErrStaticBuild)`)
- ✅ **Benchmarks**: 64-114 ns/op FFI overhead ✨
- ✅ **Typed errors**: 5 error types with `errors.As()` support
- ✅ **Typed errors**: 5 error types with `errors.As()` support (+ `ErrStaticBuild` sentinel)
- ✅ **Context support**: Timeouts and cancellation
- ✅ **Cross-platform**: Linux + Windows + macOS (AMD64 + ARM64)
- ✅ **Type system**: Predefined descriptors for common types
Expand Down
8 changes: 5 additions & 3 deletions docs/ADR-001-userspace-elf-loader.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# ADR-001: Userspace ELF loader for static binaries

**Status:** Proposed (research / preview)
**Status:** Proposed (research / preview) — Track 1–2 (`goffi_static` + docs/CI) **shipped in v0.6.4**; userspace loader remains research
**Date:** 2026-09-08
**Updated:** 2026-09-10
**Tracking:** [goffi#74](https://github.com/go-webgpu/goffi/issues/74), [gogpu#474](https://github.com/gogpu/gogpu/issues/474)
**Go baseline:** 1.25+ (`structs.HostLayout`, `CGO_ENABLED=0`)

Expand All @@ -26,8 +27,9 @@ Explore a **pure-Go userspace ELF `.so` loader** gated behind
path to “static binary + runtime LoadLibrary-like behavior” on Linux without
shipping `ld.so`.

Ship Track 1–2 (`goffi_static` + docs/CI) first. This ADR does **not** block
closing the documentation / static-profile side of #74 / gogpu#474.
Ship Track 1–2 (`goffi_static` + docs/CI) first — **done in v0.6.4**. This ADR does **not** block
closing the documentation / static-profile side of #74 / gogpu#474; it tracks only the
optional userspace ELF loader follow-up.

## Goals

Expand Down
13 changes: 13 additions & 0 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,19 @@ pointType := &types.TypeDescriptor{

Five typed error types for precise error handling: `InvalidCallInterfaceError`, `LibraryError`, `CallingConventionError`, `TypeValidationError`, `UnsupportedPlatformError`.

Under `-tags goffi_static`, dynamic loading is unavailable: `LoadLibrary` / `GetSymbol` return errors wrapping `ErrStaticBuild` (use `errors.Is`).

### Linking modes (Linux)

`CGO_ENABLED=0` does **not** imply a fully static ELF. Default builds still record `//go:cgo_import_dynamic` for `dlopen` / libc so host `.so` loading works:

| Mode | Build | Dynamic load | Typical use |
|------|-------|--------------|-------------|
| Dynamic FFI (default) | `CGO_ENABLED=0 go build` | yes | desktop GPU/GUI |
| Static no-FFI | `CGO_ENABLED=0 go build -tags goffi_static` | no (`ErrStaticBuild`) | `FROM scratch`, air-gapped CLI |

See README [Linking modes](../README.md#linking-modes-linux) and [ADR-001](./ADR-001-userspace-elf-loader.md). Helper: `scripts/check-elf-linking.sh`.

### avalue Indirection Convention

Following the libffi convention, `avalue[i]` is a **pointer TO the argument value**. GoFFI dereferences `avalue[i]` once to read the value placed into the register or stack slot:
Expand Down
Loading