Host requirements

Declare host requirements so consumers can identify missing libraries, commands, or unsupported system versions before a user runs the tool. Requirements name what must be available on the host; consumers decide how to resolve them.

Each artifact’s requires can hold four fields. packslip create reads libs from the executables where it can, and you declare the others:

FieldWhat it statesHow to set it
libsShared libraries the executables load from the host, by loader name (libssl.so.3)Read by create (--no-libs turns this off), or TOML requires.libs for an artifact create cannot read
binCommands the executables run, with an optional minimum version--require bin:java@17, a line in the action’s require input, or TOML requires.bin
glibc_minMinimum glibc for a gnu Linux buildTOML requires on the artifact
os_minMinimum OS version, in the OS’s own numberingTOML requires on the artifact

Use loader or command names, such as libssl.so.3 and java, rather than distribution package names such as libssl3 or openjdk-17-jre. Requirements describe dependencies, without instructing a package manager to install those packages.

Let create read shared libraries

create reads the ELF, Mach-O, or PE executables named by bin out of each artifact and records the shared libraries they load from the host as requires.libs. It leaves out the C runtime, libraries the OS always provides, and any library the artifact ships itself.

An empty libs list means the executables were read and need no additional shared libraries. An absent list means no library requirements were read. That happens when the artifact is an installer, disk image, or 7z archive; its executables are scripts; it lists no bin; or you passed --no-libs.

For an artifact create cannot read, you may write libs in its TOML requires. When create can read the executables, a list you write must match what it reads, or create fails.

--no-libs skips reading the executables, which also turns off libc detection: a Linux artifact whose name does not say musl or gnu is then recorded as gnu. Set libc explicitly for a static or musl build, as Artifact configuration shows.

Declare required commands

Use --require bin:NAME[@MIN] for commands your executable needs, or put one declaration per line in the action’s require input. For example, this adds Java 17 or later to every artifact that has executables:

require: |
  bin:java@17

The equivalent CLI flag is --require bin:java@17. create fails if neither --bin nor the TOML manifest names an executable. To declare the requirement for just one artifact, put it in that artifact’s requires:

[[artifact]]
path = "dist/mytool-1.2.3-linux-x64.tar.gz"
bin = ["mytool"]
requires = { bin = [{ name = "java", min = "17" }] }

NAME is the bare command as the program runs it, with no directory and no .exe. MIN is the lowest version that works, written as dot-separated numbers such as 17 or 3.12. create rejects a minimum that does not start with a digit, such as v17, and refuses a command the release itself provides.

Only declare commands the software cannot work without; put optional integrations in extensions.

Set minimum OS and glibc versions

create does not detect minimum OS or glibc versions, and no flag sets them. Write them in each artifact’s TOML requires:

FieldExampleApplies to
os_min"12" for macOS Monterey, or "10.0.17763" for WindowsThat artifact’s OS, using its own version numbering.
glibc_min"2.31"A Linux artifact with libc = "gnu".

For a release with several platforms, keep these fields out of the top-level requires. Every artifact without its own table inherits that default, so a top-level glibc_min would also be recorded on macOS and Windows artifacts. The example below shows separate platform minimums.

Combine defaults and per-artifact requirements

A top-level requires table is the default for every artifact without its own, including artifacts given only on the command line. An artifact’s own requires replaces the default rather than merging with it, so it must repeat anything shared. Here the Windows build takes java from the default, and the Linux and macOS builds, which need tables of their own, each list it again:

requires = { bin = [{ name = "java", min = "17" }] }

[[artifact]]
path = "dist/mytool-1.2.3-linux-x64.tar.gz"
bin = ["mytool"]
requires = { glibc_min = "2.31", bin = [{ name = "java", min = "17" }] }

[[artifact]]
path = "dist/mytool-1.2.3-darwin-arm64.tar.gz"
bin = ["mytool"]
requires = { os_min = "12", bin = [{ name = "java", min = "17" }] }

[[artifact]]
path = "dist/mytool-1.2.3-windows-x64.zip"
bin = ["mytool"]

Two things are added on top of whichever table applies: commands from --require, and the libraries create reads. You could therefore drop every java entry above and pass --require bin:java@17 instead. create refuses a command that --require and requires.bin both name with different minimums.

What consumers do when a requirement is not met

Consumers check requirements only after choosing an artifact, so a requirement the host does not meet never steers them to another build. Instead, the consumer refuses the install or warns:

RequirementIf the host does not meet it
Shared library, minimum glibc, or minimum OS versionRefuse installation because the executable cannot start; a user may override the refusal.
Required command or its minimum versionInstall with a warning naming the missing or outdated command.
A requirement the consumer cannot checkWarn instead of guessing.

Numeric versions compare by component: 2.10 is newer than 2.9, and 17 is equivalent to 17.0.0. If either version cannot be compared this way, the check is unknown and the consumer warns.

See Host requirements and consumer rule 7 in the specification for the complete rules, and Release recipes for example layouts.