pkg-subpkgs(7)
NAME
pkg-subpkgs - subpackages, content classes, and what a bare name means
DESCRIPTION
One source build produces a lot of different things. Programs, libraries, headers, manual pages, translations for forty languages, debug symbols. Very few machines want all of it. A server doesn't want man pages, a container doesn't want translations, and almost nobody wants the debug symbols until the day they really do.
So a build is split into subpackages. Each one is a content class carved out of the build's output, addressed as name/subpkg: bash/bin, zlib/lib, openssl/dev. The subpackage is the unit pkg installs, removes, verifies and tracks.
There's no main package
Essentially everything is a subpackage, and none of them is special. bin is a content class like the rest: things under /usr/bin, put there by the classification rules at build time. A package that ships no programs simply has no bin subpackage.
That's why a bare name can't just mean name/bin. That rule would refuse zlib, bash-completion, the kernel, and every Rust library crate. A bare name means something better than that: see BARE NAMES, below.
CONTENT CLASSES
The common classes, roughly in order of how often they matter:
bin- Programs:
/usr/bin,/usr/sbin,/usr/libexec. lib- Shared libraries, the versioned .so files.
data- Everything not classified anywhere else: the non-code payload under
/usr/share,/etc, and so on. A package's license texts ship here too. When a package has data, its bin and lib require it, so a program never arrives without its data. rustlib- A Rust library crate.
boot- Boot-time artifacts: kernels, initrd content.
mod- Kernel modules.
dev- Headers, pkg-config files, unversioned linker symlinks.
staticdev- Static archives.
man- Manual pages.
doc- Documentation.
info- GNU info pages.
lang- Translations. One per locale, with the locale as a suffix: lang/de, lang/zh_CN.
debug- Detached debug symbols.
debugsrc- The sources those symbols point at.
source- Source content shipped as a package.
server- A listening daemon, with its units, config and accounts.
python,perl,bash,lua- A script split out of an otherwise compiled package, named after the interpreter it needs.
tests- Test content, when the build declares it separable.
BARE NAMES
What does pkg install foo give me?
The package's runtime content: every subpackage the winning repository carries for that name, minus four groups.
- Build-derived output
debug,debugsrc,source,man,doc,info,lang.- Development content
dev,staticdev.- Server daemons
server.- Interpreter-bound scripts
python,perl,bash,lua.
Everything else is runtime content, and comes along. That includes tests when a package has one.
The class is the part before the first slash, so the single lang entry covers every lang/locale variant.
A name whose subpackages all fall in those groups has no runtime content. A bare install of it is refused, and the error lists the subpackages you could name instead.
Why leave out the server?
Because a daemon is the one content class whose mere presence changes what the machine is. Installing samba for smbclient, or openssh for ssh, must not also land smbd or sshd. Ask for name/server by name, or opt the whole machine in with [install] include_subpkgs in pkg.toml(5).
Why leave out the interpreter classes?
A compiled package that ships one stray Python helper hands its whole bin a dependency on python3. Splitting the script out into name/python fixes that, but only if a bare name doesn't take it straight back. So it doesn't. Whoever wants the script installs name/python, and accepts the interpreter with it.
ADDING BACK WHAT A BARE NAME DROPS
There are two ways, with a different scope.
- Per command
- Name the subpackage:
pkg install vim/man openssl/dev. - Per machine
- [install] include_subpkgs in pkg.toml(5) adds selectors to every bare-name expansion. An entry is either a bare class (
man, which matches that class and all its variants) or a class and variant (lang/zh_CN, which matches only that one).
An explicit name/subpkg is checked against the repository, never passed through blindly. If the winning repository doesn't carry that subpackage, it's refused by name, with a list of what is on offer. That beats a resolver error about a goal with no candidates, which is what you'd get otherwise.
MULTI-INSTALLABLE PACKAGES
Normally one name means one installed build. A package marked multi-installable is different, and the kernel is the obvious case: several versions are meant to sit side by side. Such a package is tracked per version-release instead of per name. Its state directory carries a variant component, and pkg-query(1) prints "(variant <version>-<release>)" next to it.
PATH ENCODING
A subpackage name can contain characters a path can't carry as-is. On disk, and in repository keys, the name is escaped: lang/en@boldquot becomes lang/en\x40boldquot. This shows up in pkg-repository-layout(7), and in nothing you ever type.
EXAMPLES
Seeing what a name actually carries
pkg list --all --collapse=none | grep '^gzip'
By default, listings collapse instead: one row per package, with the runtime classes in brackets, and every non-runtime subpackage still on its own row.
pkg list --all | grep '^gzip'
--collapse is a global option (pkg(1)), so the same two levels fold a transaction plan, a compose closure and a search result too.
Seeing which subpackages a bare install would pick
The plan collapses runtime subpackages by default, and that's exactly what this question is about. So ask for the flat list:
pkg install gzip --dry-run --collapse=none pkg -vvv install gzip --dry-run 2>&1 | grep 'goal:'
Installing development content
pkg install openssl/dev zlib/dev
Making manual pages the default on this machine
In /etc/pkg.toml:
[install] include_subpkgs = ["man"]
Adding one locale, not all of them
[install] include_subpkgs = ["lang/en_US", "lang/nl"]
Installing a daemon on purpose
pkg install openssh # ssh, scp, ssh-keygen pkg install openssh/server # and sshd
Asking for a subpackage that doesn't exist
pkg install zlib/bin
This fails by name, and lists the subpackages zlib actually has.
SEE ALSO
pkg(1), pkg-install(1), pkg-list(1), pkg-query(1), pkg.toml(5), pkg-chain(7), pkg-sets(7), pkg-repository-layout(7)
docs/design/naming.md, docs/components/autobuilder-classify.md, docs/design/debuginfo.md