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
22 changes: 12 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,21 +124,23 @@ jobs:
done

# FreeBSD requires -gcflags="-std" for fakecgo's //go:cgo_export_dynamic
echo "Building freebsd/amd64 (with -gcflags for fakecgo)..."
if GOOS=freebsd GOARCH=amd64 go build \
-gcflags="github.com/go-webgpu/goffi/internal/fakecgo=-std" \
./... 2>&1; then
echo " ✅ freebsd/amd64"
else
echo " ❌ freebsd/amd64 FAILED"
FAILED=1
fi
for fbsd_arch in amd64 arm64; do
echo "Building freebsd/${fbsd_arch} (with -gcflags for fakecgo)..."
if GOOS=freebsd GOARCH=${fbsd_arch} go build \
-gcflags="github.com/go-webgpu/goffi/internal/fakecgo=-std" \
./... 2>&1; then
echo " ✅ freebsd/${fbsd_arch}"
else
echo " ❌ freebsd/${fbsd_arch} FAILED"
FAILED=1
fi
done

if [ $FAILED -eq 1 ]; then
echo "❌ Cross-compilation check FAILED"
exit 1
fi
echo "✅ All 7 platforms compile successfully"
echo "✅ All 8 platforms compile successfully"

# Unit tests - Platform-specific (Linux + Windows + macOS AMD64)
# Tested under both CGO_ENABLED=0 (fakecgo path) and CGO_ENABLED=1 (real
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.5.3] - 2026-05-28

### Fixed
- **FreeBSD ARM64 build failure** — added `freebsd` to build tags in `internal/arch/arm64/call_arm64.go`, `internal/syscall/syscall_arm64.go`, `internal/syscall/syscall_arm64.s`, and `ffi/callback_arm64.s`. FreeBSD ARM64 uses identical AAPCS64 calling convention as Linux ARM64 — no code changes needed, only build tag additions. Requires same `-gcflags="github.com/go-webgpu/goffi/internal/fakecgo=-std"` workaround as FreeBSD AMD64. Closes [#52](https://github.com/go-webgpu/goffi/issues/52)
- **FreeBSD ARM64 callback trampoline** — `ffi/callback_arm64.s` was missing `freebsd` in build tags while `ffi/callback_arm64.go` (Go side) already included it, causing `NewCallback()` to silently return invalid addresses on FreeBSD ARM64

### Changed
- Platform count: 7 → 8 targets (added FreeBSD ARM64)
- CI cross-compilation check now validates all 8 platforms including `freebsd/arm64`

## [0.5.2] - 2026-05-25

### Added
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ ffi.CallFunction(cif, sym, unsafe.Pointer(&result), args)
|---|---------|---------|
| **Zero CGO** | Pure Go | No C compiler needed. `go get` and build. |
| **Fast** | 88–114 ns/op | Pre-computed CIF, zero per-call allocations |
| **Cross-platform** | 7 targets | Windows, Linux, macOS, FreeBSD × AMD64 + ARM64 |
| **Cross-platform** | 8 targets | Windows, Linux, macOS, FreeBSD × AMD64 + ARM64 |
| **Callbacks** | C→Go safe | `crosscall2` integration, struct args, works from any C thread |
| **Type-safe** | Runtime validation | 5 typed error types with `errors.As()` support |
| **Struct pass/return** | Full ABI | Args: INTEGER/SSE classification. Returns: ≤8B (RAX/XMM0), 9–16B (4 modes: RAX/XMM × RAX/XMM), >16B (sret) |
Expand Down Expand Up @@ -273,7 +273,7 @@ if err != nil {
| Context support | Timeouts/cancellation | No | No |
| C-thread callbacks | crosscall2 | crosscall2 | Full |
| String/bool/slice args | Raw pointers only | Auto-marshaling | Full |
| Platform breadth | 7 targets | 8 GOARCH / 20+ OS×ARCH | All |
| Platform breadth | 8 targets | 8 GOARCH / 20+ OS×ARCH | All |
| AMD64 overhead | 88–114 ns | Not published | ~140 ns (Go 1.26 claims ~30% reduction) |

**Choose goffi** for GPU/real-time workloads: struct passing, zero per-call overhead, callback float returns, typed errors.
Expand Down Expand Up @@ -326,6 +326,7 @@ if err != nil {
| macOS | amd64 | System V | v0.1.1 | Tested |
| macOS | arm64 | AAPCS64 | v0.3.7 | Tested (M3 Pro) |
| FreeBSD | amd64 | System V | v0.5.0 | Cross-compile verified |
| FreeBSD | arm64 | AAPCS64 | v0.5.3 | Cross-compile verified |

---

Expand Down
2 changes: 1 addition & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ v1.0.0 LTS → Long-term support release (2027 Q1)
**v0.5.0** = Platform coverage ✅ RELEASED (2026-03-29)
- **Windows ARM64** support (Snapdragon X Elite, tested by @SideFx)
- **FreeBSD amd64** support (cross-compile verified)
- 7 platform targets (Linux/Windows/macOS/FreeBSD × amd64 + ARM64)
- 7 platform targets (Linux/Windows/macOS/FreeBSD × amd64 + Linux/macOS/Windows ARM64)

**v0.5.1** = Struct ABI + CGO_ENABLED=1 ✅ RELEASED (2026-05-13)
- **CGO_ENABLED=1 support** (PR #37 by @jiyeyuran) — dual-mode build, race detector compatible
Expand Down
1 change: 1 addition & 0 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ go run github.com/go-webgpu/goffi/cmd/variadic-test
| **macOS** | AMD64 | System V | Production |
| **macOS** | ARM64 | AAPCS64 | Production (tested on M3 Pro) |
| **FreeBSD** | AMD64 | System V | Cross-compile verified |
| **FreeBSD** | ARM64 | AAPCS64 | Cross-compile verified |
| **Linux** | ARM64 | AAPCS64 | Production |

---
Expand Down
2 changes: 1 addition & 1 deletion ffi/callback_arm64.s
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build (linux || darwin) && arm64
//go:build (linux || darwin || freebsd) && arm64

#include "textflag.h"
#include "go_asm.h"
Expand Down
8 changes: 4 additions & 4 deletions ffi/dl_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ func LoadLibrary(name string) (unsafe.Pointer, error) {
}
}

// Safe: handle is immediately converted from uintptr to unsafe.Pointer
// without intermediate storage, keeping it reachable by GC.
// go vet: "possible misuse of unsafe.Pointer" — false positive.
// Windows DLL handles are opaque OS values, not Go heap pointers.
return unsafe.Pointer(handle), nil
}

Expand Down Expand Up @@ -81,8 +81,8 @@ func GetSymbol(handle unsafe.Pointer, name string) (unsafe.Pointer, error) {
}
}

// Safe: proc is immediately converted from uintptr to unsafe.Pointer
// without intermediate storage, keeping it reachable by GC.
// go vet: "possible misuse of unsafe.Pointer" — false positive.
// GetProcAddress returns a function pointer, not a Go heap pointer.
return unsafe.Pointer(proc), nil
}

Expand Down
6 changes: 3 additions & 3 deletions internal/arch/arm64/call_arm64.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//go:build arm64 && (linux || darwin || windows)
//go:build arm64 && (linux || darwin || windows || freebsd)

// AAPCS64 ABI implementation (Linux, macOS, Windows on ARM64)
// Windows ARM64 uses the same calling convention as Unix ARM64 for non-variadic functions.
// AAPCS64 ABI implementation (Linux, macOS, Windows, FreeBSD on ARM64)
// All ARM64 platforms use the same AAPCS64 calling convention for non-variadic functions.
// See: https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions

package arm64
Expand Down
4 changes: 2 additions & 2 deletions internal/syscall/syscall_arm64.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//go:build (linux || darwin || windows) && arm64
//go:build (linux || darwin || windows || freebsd) && arm64

// AAPCS64 ABI syscall implementation (Linux, macOS, Windows on ARM64)
// AAPCS64 ABI syscall implementation (Linux, macOS, Windows, FreeBSD on ARM64)
// ARM64 Procedure Call Standard - identical across all platforms.
package syscall

Expand Down
2 changes: 1 addition & 1 deletion internal/syscall/syscall_arm64.s
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build (linux || darwin || windows) && arm64
//go:build (linux || darwin || windows || freebsd) && arm64

#include "textflag.h"
#include "abi_arm64.h"
Expand Down
Loading