Documents
packaging-go
packaging-go
Type
External
Status
Published
Created
Jun 13, 2026
Updated
Jun 13, 2026
Source
View

Packaging Go Projects#

Load when packaging a Go project for dakota/Bluefin BuildStream, or when setting up GOPATH vendoring in BuildStream.

When NOT to Use#

  • Rust project → packaging-rust.md
  • Zig project → packaging-zig.md
  • Pre-built binary → packaging-binaries.md

Go Build Approach in BST#

BST builds are network-isolated (no go get at build time). Go modules must be vendored. Two patterns:

PatternWhen
go_module sourcesProject uses Go modules; vendor each dep as a BST source
Embedded GOPATH tarballSimpler; bundle all deps in a single tarball

Pattern 1: go_module Sources#

kind: make

build-depends:
- freedesktop-sdk.bst:components/go.bst
- freedesktop-sdk.bst:bootstrap-import.bst

depends:
- freedesktop-sdk.bst:public-stacks/runtime-minimal.bst

variables:
  version: '1.2.3'
  gopath: /usr/lib/go

config:
  build-commands:
  - |
    export GOPATH="%{gopath}"
    export GOFLAGS="-mod=vendor"
    go build -o project ./cmd/project/

  install-commands:
  - install -Dm755 project "%{install-root}%{bindir}/project"
  - '%{install-extra}'

sources:
- kind: git_repo
  url: github:owner/project.git
  track: main
  ref: abc123...
- kind: go_module
  url: "github.com/some/dep"
  version: "v1.0.0"
  ref: sha256hex...
# ... one go_module entry per dependency

Generating go_module sources requires running go mod vendor on the project and converting vendor/modules.txt. See files/scripts/generate_go_sources.py if available.

Pattern 2: Vendored GOPATH Tarball#

Pre-vendor all dependencies locally and upload as a tarball:

kind: manual

build-depends:
- freedesktop-sdk.bst:components/go.bst
- freedesktop-sdk.bst:bootstrap-import.bst

depends:
- freedesktop-sdk.bst:public-stacks/runtime-minimal.bst

variables:
  version: '1.2.3'
  gopath: '%{build-root}/gopath'

sources:
- kind: git_repo
  url: github:owner/project.git
  ref: abc123...
  directory: project
- kind: tar
  url: alias:releases/owner/project/v%{version}/vendor.tar.gz
  ref: sha256hex...
  directory: vendor

install-commands:
- |
  cd project
  export GOPATH="%{gopath}"
  export GOFLAGS="-mod=vendor"
  go build -o "%{install-root}%{bindir}/project" ./cmd/project/
- '%{install-extra}'

systemd Service (if needed)#

install-commands:
  # ... install binary ...
  - |
    install -Dm644 /dev/stdin "%{install-root}%{indep-libdir}/systemd/system/project.service" <<'SERVICE'
    [Unit]
    Description=Project daemon
    After=network.target

    [Service]
    ExecStart=/usr/bin/project
    Restart=on-failure

    [Install]
    WantedBy=multi-user.target
    SERVICE
  - |
    install -Dm644 /dev/stdin "%{install-root}%{indep-libdir}/systemd/system-preset/80-project.preset" <<'PRESET'
    enable project.service
    PRESET

Checklist#

  • Go build is network-isolated (all deps in sources)
  • GOFLAGS="-mod=vendor" set in build commands
  • Binary installs to %{bindir} (not /usr/sbin)
  • strip-binaries: "" not needed (Go binaries are ELF and strip cleanly)
  • Element added to elements/bluefin/deps.bst
  • just validate passes
  • just bst build bluefin/<name>.bst passes

Lessons Learned#

All current Go tools in Dakota are pre-built binaries — not Go-from-source builds (2026-06-07)#

As of June 2026, every Go-based tool in Dakota uses kind: manual with pre-built binaries
from GitHub Releases. glow.bst, gum.bst, and fzf.bst are all pre-built binary elements,
not Go source builds. See packaging-binaries.md for the pre-built pattern.

Go-from-source build infrastructure (this skill) exists for future use when a required tool
doesn't provide static binaries. Do not reach for this skill unless upstream truly has no
release binaries — pre-built is simpler and faster to maintain.

Vendored GOPATH tarball requires a build host with Go to generate (2026-06-07)#

Pattern 2 (vendored GOPATH tarball) requires running go mod vendor on the host to create
the tarball before the element can be written. Unlike cargo2 (where the generator script
reads from the source), the Go vendor tarball must be generated offline and uploaded
separately. Factor in this extra maintenance step when deciding between Pattern 1 and
Pattern 2 — Pattern 1 (go_module sources) is more maintainable long-term because refs
can be updated in-place.

packaging-go | Dosu