From 8006bd0fda73977219863da4eb0500ac3aa9bf7c Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 12 Aug 2026 13:56:46 +0000 Subject: [PATCH] docs(go): document the buildmode variant field heph's Go plugin now defaults binary links to buildmode=exe (static, no interpreter) instead of hardcoded pie, and exposes a `buildmode` variant field ("exe"/"pie") to opt back into PIE. Document the field and its Linux/darwin behavior in both the plugin docs page and the heph-go skill's reference twin. Ref: hephbuild/heph#393 (c4c525de1c3b521f93429ee97a30c4427fd641f6) --- .../skills/heph-go/references/go-plugin.md | 19 +++++++++++++++ website/docs/plugins/go.md | 24 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/plugins/heph-go/skills/heph-go/references/go-plugin.md b/plugins/heph-go/skills/heph-go/references/go-plugin.md index decf15a..e955962 100644 --- a/plugins/heph-go/skills/heph-go/references/go-plugin.md +++ b/plugins/heph-go/skills/heph-go/references/go-plugin.md @@ -190,6 +190,7 @@ provider_state(provider = "go", variants = { | `goexperiment` | `list[string]` | no | `GOEXPERIMENT` values. | | `gcflags` | `list[string]` | no | Extra `go tool compile` flags. | | `ldflags` | `list[string]` | no | Extra `go tool link` flags. | +| `buildmode` | `string` | no | Link mode for a `package main` `:build`: `"exe"` (default, static on Linux) or `"pie"` (position-independent, needs an interpreter on Linux). See "Buildmode" below. | | `inherit` | `string` | no | Another variant name in the same map to start from. | No `cgo` field — every heph-built Go target has `CGO_ENABLED=0` unconditionally. @@ -198,6 +199,24 @@ No `cgo` field — every heph-built Go target has `CGO_ENABLED=0` unconditionall merged**; `goos`/`goarch` may be omitted when the base sets them; inheritance cycles error. +### Buildmode + +`buildmode` picks the link mode for a `package main` target's `:build`: +`"exe"` (default) matches plain `go build` — on Linux the binary links +statically with no interpreter, so it runs in `FROM scratch`/distroless. +`"pie"` produces a position-independent executable, which on Linux always +needs `/lib/ld-linux-.so.1` at run time, cgo or not. + +```python title="BUILD" +provider_state(provider = "go", variants = { + "release": {"goos": "linux", "goarch": "arm64", "buildmode": "pie"}, +}) +``` + +On darwin/arm64 the linker makes every executable PIE regardless of this +setting — the knob only changes behavior on Linux. Only affects the linked +binary; libraries/archives are unaffected. + Select with `@v=NAME` on the address: ```bash diff --git a/website/docs/plugins/go.md b/website/docs/plugins/go.md index c1cd3cb..c1d23d7 100644 --- a/website/docs/plugins/go.md +++ b/website/docs/plugins/go.md @@ -359,6 +359,7 @@ provider_state(provider = "go", variants = { | `goexperiment` | `list[string]` | no | `GOEXPERIMENT` values to enable. | | `gcflags` | `list[string]` | no | Extra flags passed to `go tool compile`. | | `ldflags` | `list[string]` | no | Extra flags passed to `go tool link`. | +| `buildmode` | `string` | no | Link mode: `"exe"` (default) or `"pie"`. See [Buildmode: static vs PIE](#buildmode-static-vs-pie). | | `inherit` | `string` | no | Name of another variant in the same map to start from. | `cgo` is not a variant field — every heph-built Go target compiles with @@ -371,6 +372,29 @@ on top of it. List fields (`tags`, `goexperiment`, `gcflags`, `ldflags`) are `goarch` can be omitted when inheriting from a variant that already sets them. Inheritance cycles are rejected with an error. +### Buildmode: static vs PIE + +`buildmode` controls the binary's link mode for a `package main` target's +`:build`: + +| Value | Behavior | +|---------|----------| +| `"exe"` | Default. Matches plain `go build`. On Linux, links a statically linked binary with no interpreter — it runs in a `FROM scratch` or distroless image. | +| `"pie"` | Position-independent executable. On Linux this always needs `/lib/ld-linux-.so.1` present at run time, even with cgo disabled. | + +```python title="BUILD" +provider_state(provider = "go", variants = { + "release": {"goos": "linux", "goarch": "arm64", "buildmode": "pie"}, +}) +``` + +On darwin/arm64 the Go linker makes every executable PIE regardless of this +setting, so both values produce the same kind of binary there — the knob only +changes behavior on Linux. + +Library targets and archives are unaffected by `buildmode`; it only applies to +the linked binary of a `package main`. + ### Selecting a variant Add `@v=NAME` to a target address: