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

Packaging Pre-Built Binaries#

Load when packaging a project that provides official pre-built static binaries (GitHub Releases, official downloads), or when building from source is impractical.

When to Use Pre-Built Binaries#

SituationPre-built?
Official static binary available from upstream✅ Yes
Upstream has no build system we can use in BST✅ Yes
Bootstrap compiler needed (e.g., Zig for Zig builds)✅ Yes
Source available and build system is standard❌ Build from source instead

Element Template#

kind: manual
description: <Package name>

build-depends:
- freedesktop-sdk.bst:bootstrap-import.bst

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

variables:
  version: '1.2.3'
  strip-binaries: "" # required — pre-built binaries are already stripped

sources:
- kind: tar
  url: alias:releases/owner/project/v%{version}/project-linux-amd64.tar.gz
  ref: sha256hex...

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

Architecture Dispatch#

For projects with architecture-specific binaries:

variables:
  version: '1.2.3'
  (?):
  - arch == "x86_64":
      arch-tag: "amd64"
  - arch == "aarch64":
      arch-tag: "arm64"

sources:
- kind: tar
  url: alias:releases/owner/project/v%{version}/project-linux-%{arch-tag}.tar.gz
  ref: sha256hex...

Source Kinds for Binaries#

Source kindUse when
tarBinary is inside a .tar.gz/.tar.xz archive
remoteSingle file download (not extracted)

For remote sources, use directory: to control placement in the staging dir:

sources:
- kind: remote
  url: alias:releases/owner/project/v%{version}/project-linux-amd64
  ref: sha256hex...
  directory: bin

Adding URL Aliases#

Binary download domains need an alias in include/aliases.yml:

aliases:
  github: 'https://github.com/'
  releases: 'https://github.com/' # for /releases/ paths
  objects-gh: 'https://objects.githubusercontent.com/'

Use the alias in the element URL:

url: releases:owner/project/releases/download/v%{version}/binary.tar.gz

Checklist#

  • strip-binaries: "" set (non-ELF content won't strip cleanly)
  • ref: is a pinned SHA256 hash (for tarballs) or commit SHA (for git sources)
  • URL alias added to include/aliases.yml if domain is new
  • Element added to elements/bluefin/deps.bst
  • just bst show bluefin/<name>.bst passes
  • just bst build bluefin/<name>.bst passes

Lessons Learned#

strip-binaries: "" belongs under variables:, not public: bst: (2026-06-07)#

Real elements (tailscale.bst, glow.bst, gum.bst, fzf.bst, tealdeer.bst) all declare
strip-binaries: "" under variables:. public: bst: is for overlap-whitelist entries only.
Placing strip-binaries under public: bst: causes a YAML error at element parse time.

# ✅ correct
variables:
  strip-binaries: ""

# ❌ wrong — YAML parse error
public:
  bst:
    strip-binaries: ""

base-dir: "" required when tarball has no wrapping directory (2026-06-07)#

Some projects (e.g., fzf) release tarballs where the binary sits at the archive root with no
wrapping directory. Without base-dir: "", BST expects a top-level directory and fails. Example
from fzf.bst:

sources:
- kind: tar
  base-dir: ""
  url: github_files:junegunn/fzf/releases/download/v0.73.1/fzf-0.73.1-linux_amd64.tar.gz
  ref: f3252c2c366bc1700d3c85781ec8c9695998927ac127870eb049ceea2d540f8a

Multiple kind: remote sources for binary + completions (2026-06-07)#

When an upstream release provides separate files for the binary and shell completions, use one
kind: remote source per file. Give each a filename: to rename it on extraction. Example from
tealdeer.bst:

sources:
  - kind: remote
    filename: tealdeer # renames the download
    url: github_files:tealdeer-rs/tealdeer/releases/download/v1.8.1/tealdeer-linux-x86_64-musl
    ref: sha256hex...
  - kind: remote
    filename: completions_bash
    url: github_files:tealdeer-rs/tealdeer/releases/download/v1.8.1/completions_bash
    ref: sha256hex...

The filename: field is required when the URL path has no recognizable extension or conflicts
with another source file in the same staging directory.

Arch-conditional sources use (?) inside the source block, not at top level (2026-06-07)#

Architecture-specific download URLs live inside the (?): conditional directly within the
sources: list item. The kind: is outside the conditional:

sources:
- kind: tar
  (?):
  - arch == "x86_64":
      url: alias:project_1.0_amd64.tgz
      ref: sha256hex...
  - arch == "aarch64":
      url: alias:project_1.0_arm64.tgz
      ref: sha256hex...

This pattern is used in tailscale.bst, glow.bst, gum.bst, and fzf.bst.

Shared profile scripts require the binary in a BST element — check common Containerfile (2026-06-09)#

projectbluefin/common ships profile scripts in system_files/shared/etc/profile.d/
that are installed by common.bst. If a script calls a binary that common's Containerfile
downloads into /out/bluefin/usr/bin/ (not /out/shared/), that binary will be missing
from the BST build and every terminal open will print bash: <cmd>: command not found.

Pattern to detect: check common/Containerfile for curl downloads to /out/bluefin/usr/bin/
that match any script in system_files/shared/etc/profile.d/.

Fix has two parts:

  1. projectbluefin/common: move the binary download from /out/bluefin/usr/bin/ to
    /out/shared/usr/bin/ in the Containerfile, and move the corresponding config from
    system_files/bluefin/etc/<tool>/ to system_files/shared/etc/<tool>/.
  2. projectbluefin/dakota: add a BST element that downloads the same binary for the
    BST build path. Config is installed by common.bst (copies both bluefin/etc/ and
    shared/etc/), so the BST element only needs to provide the binary.

For raw binaries (no tarball), use kind: remote with filename: <name> to rename on
download, then a clean install -Dm755 without globs. Example from umotd.bst:

sources:
- kind: remote
  filename: umotd
  (?):
  - arch == "x86_64":
      url: github_files:theMimolet/umotd/releases/download/v0.2.1/umotd_0.2.1_linux_amd64
      ref: 2cd5a07344f553e590b432aa5b3a07c5cbd055487468d33514130ae5f05ba02e
  - arch == "aarch64":
      url: github_files:theMimolet/umotd/releases/download/v0.2.1/umotd_0.2.1_linux_arm64
      ref: 1598bb13f30f3c2e17fe4349fd04f567999a0643919d5a4abb186a14cb7d62f0

References: projectbluefin/common PR 542, projectbluefin/dakota PR 762 (issue 753)

packaging-binaries | Dosu