Skip to content

feat: goffi_static build tag for fully static Linux ELFs - #78

Merged
lkmavi merged 5 commits into
go-webgpu:mainfrom
lkmavi:feature/474-goffi-static
Sep 10, 2026
Merged

lkmavi merged 5 commits into
go-webgpu:mainfrom
lkmavi:feature/474-goffi-static

Conversation

@lkmavi

@lkmavi lkmavi commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Adds -tags goffi_static which excludes all //go:cgo_import_dynamic directives so CGO_ENABLED=0 linux/amd64 and linux/arm64 binaries are fully static (no PT_INTERP, no DT_NEEDED).
  • ffi.LoadLibrary / GetSymbol return ffi.ErrStaticBuild under that tag; default dynamic FFI path unchanged.
  • Documents linking modes (dynamic / musl / static), adds scripts/check-elf-linking.sh + CI elf-linking job, and docs/ADR-001-userspace-elf-loader.md for the long-term loader research track.

Fixes the consumer-visible half of #74 / gogpu#474. Does not claim FROM scratch + host dlopen (architecturally impossible without ld.so or a userspace loader).

Test plan

  • CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -tags goffi_static → file reports statically linked
  • Same for linux/arm64
  • Default (no tag) linux/amd64 still has libdl.so.2 / libc.so.6 / libpthread.so.0
  • go test -tags goffi_static ./ffi -run StaticBuild
  • CI elf-linking job green on this PR

Exclude all cgo_import_dynamic directives under -tags goffi_static so
CGO_ENABLED=0 linux/amd64 and linux/arm64 binaries have no PT_INTERP or
DT_NEEDED. LoadLibrary returns ErrStaticBuild. Document linking modes,
add ELF CI gates, and ADR-001 for a future userspace ELF loader.

Refs: goffi#74, gogpu#474

@kolkov kolkov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this — the goffi_static approach is the right answer to #74. You can't dlopen without ld.so, and a static binary has no ld.so. Returning ErrStaticBuild is honest and clean.

Went through the full diff (80 files). Build tag propagation is thorough — no dynamic symbols leak into the static binary. The check-elf-linking.sh CI gate is exactly what we needed: machine-verified PT_INTERP contract. ADR-001 aligns well with our own elfloader research (ADR-014).

One minor note: errno capture under goffi_static returns 0 silently (ErrnoFnAddr() = 0 skips the assembly call). The code is correct, but a one-line mention in the README's static section would help users understand errno is unavailable in static mode.

Everything else — the stub architecture, ErrStaticBuild error type, crosscall2 abort trampolines, CI job — looks solid. Ready to merge.

@codecov

codecov Bot commented Sep 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@lkmavi
lkmavi merged commit dc1f93d into go-webgpu:main Sep 10, 2026
17 checks passed
unxed added a commit to unxed/goffi that referenced this pull request Sep 25, 2026
…rk main

Upstream go-webgpu#78 added its own goffi_static. The fork already has one, and
Profile U and goffi_musl are built on it (ffi.Available, internal/static,
callback_static.go, ffi.ErrStaticBuild). The two are equivalent for
callers: LoadLibrary/GetSymbol return a *LibraryError wrapping
ffi.ErrStaticBuild, the ELF has no PT_INTERP or DT_NEEDED, and errno
capture is off. So the code keeps the fork's implementation:

- conflicting .go/.s files and upstream's build-tag-only edits resolve to
  the fork's version;
- upstream-only static files that would duplicate the fork's definitions
  are dropped: ffi/dl_static.go, ffi/errors_static.go,
  ffi/fakecgo_static.go, internal/fakecgo/static.go and
  asm_static_{amd64,arm64}.s;
- upstream's ffi/static_test.go is kept, restricted to linux, where the
  fork's static mode applies (it is a no-op on Windows and Android).

Taken from upstream: scripts/check-elf-linking.sh and the elf-linking CI
job (added to ci-success next to platform-matrix), ADR-001, the v0.6.4
CHANGELOG/ROADMAP/README entries, the linking-modes docs (with rows for
goffi_musl and the universal build), and the package doc changes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants