ALPM-PACKAGE-RELATION(7)

๐Ÿ“ฆ version 0.13.0, in arch rolling

๐Ÿ’… ALPM-PACKAGE-RELATION(7)

ok so this is from the Miscellaneous Information Manual, section (7), and it's literally the whole lore drop on package relations. buckle up bestie ๐ŸŽ€


๐ŸŒธ NAME

package relation โ€” the whole concept of package relationships for ALPM based packages.


โœจ DESCRIPTION

Package relations are how ALPM based packages describe their relationships to each other in all sorts of scenarios. They show up in build scripts, or in file formats for package metadata (think PKGBUILD, PKGINFO, SRCINFO), where they spell out how one package relates to other packages. Software like package managers and package build tools live on package relations to resolve dependency graphs โ€” like when you're installing or uninstalling stuff. it's giving backbone of the whole ecosystem, honestly ๐Ÿ‘‘

๐Ÿ“ฆ Packages and virtual components

Any package relation can contain an alpm-package-name, and that name might point at an actual real package, or at a virtual component. Virtual components aren't the names of existing packages at all โ€” they're a component that's implicitly defined by package metadata. Package relations are the thing that defines them and uses them, basically treating them just like the names of existing packages (peep the EXAMPLES section for the receipts).

๐Ÿงฌ Sonames

A package relation of type provision or run-time dependency can contain an alpm-soname, which represents a hard dependency based on one specific shared object inside a package. These are what encode compatibility guarantees between ELF[1] and shared object files using soname[2] data (again โ€” EXAMPLES has the tea โ˜•).

๐Ÿ—๏ธ Architecture specific use

Package relations can be used in contexts that describe multiple alpm-architectures at the same time. For those situations there are architecture-specific identifiers you can use. slay for portability ๐ŸŒˆ

๐Ÿ”ฎ Types of package relations

Every package relation is bound to a set of types, and which keywords and data structures get used for each type depends on the context you're in. so like, context matters, iykyk.

๐Ÿ”ฅ Run-time dependency

A run-time dependency of a package. This relation specifies a hard requirement โ€” another package, optionally at a specific version โ€” that has to be present when you're using the package in question. no ifs, ands or buts.

The value for a run-time dependency is either an alpm-package-name, an alpm-comparison, or an alpm-soname โ€” like example, example>=1.0.0, or lib:libexample.so.1 respectively.

  • In PKGBUILD files, zero or more run-time dependencies of a package are specified with the depends array. Architecture-specific run-time dependencies can be specified with an array named depends, directly followed by an _ sign, directly followed by an alpm-architecture (every alpm-architecture except any can be used) โ€” e.g. depends_aarch64. ๐Ÿซถ The alpm-sonamev2 format can not be used in PKGBUILD files, because the : character inside it isn't valid in an alpm-package-name. Instead, alpm-sonamev2 data gets automatically derived by the package build tool (see alpm-sonamev2).
  • In PKGINFO files, the depend keyword specifies a run-time dependency.
  • In SRCINFO files, the depends keyword specifies a run-time dependency. An architecture-specific run-time dependency can be specified with a keyword made of depends, directly followed by an _ sign, directly followed by an alpm-architecture (every alpm-architecture except any can be used) โ€” e.g. depends_aarch64. SRCINFO files are derived from PKGBUILD files and should not contain any info about the host that triggers the transformation. So: you must not manually add alpm-sonamev2 entries in PKGBUILD files, and you should only add stub entries (e.g. libexample.so) for alpm-sonamev1 to them, for as long as the ecosystem still supports that legacy format. โš ๏ธ

๐Ÿ› ๏ธ Build dependency

A build-time dependency of a package. This relation specifies a build requirement โ€” another package, optionally at a specific version โ€” that has to be present when you're building the package.

The value for a build dependency is either an alpm-package-name or an alpm-comparison โ€” like example or example>=1.0.0.

  • In PKGBUILD files, zero or more build-time dependencies of a package are specified with the makedepends array. Architecture-specific build dependencies can be specified with an array named makedepends, directly followed by an _ sign, directly followed by an alpm-architecture (every alpm-architecture except any can be used) โ€” e.g. makedepends_aarch64.
  • In PKGINFO files, the makedepend keyword specifies a build-time dependency.
  • In SRCINFO files, the makedepends keyword specifies a build-time dependency. An architecture-specific build dependency can be specified with a keyword made of makedepends, directly followed by an _ sign, directly followed by an alpm-architecture (every alpm-architecture except any can be used) โ€” e.g. makedepends_aarch64.

๐Ÿงช Test dependency

A package dependency that's only required when you run the tests of the package. This relation specifies a test requirement โ€” another package, optionally at a specific version โ€” that has to be present when the tests of a given package are running.

The value for a test dependency is either an alpm-package-name or an alpm-comparison โ€” like example or example>=1.0.0.

  • In PKGBUILD files, zero or more test dependencies of a package are specified with the checkdepends array. Architecture-specific test dependencies can be specified with an array named makedepends, directly followed by an _ sign, directly followed by an alpm-architecture (every alpm-architecture except any can be used) โ€” e.g. checkdepends_aarch64. ๐Ÿ™ˆ (yes bestie, the page literally says makedepends right there in the middle of the test-dependency section โ€” i'm just the messenger, i don't make the rules ๐Ÿ’€)
  • In PKGINFO files, the checkdepend keyword specifies a test dependency.
  • In SRCINFO files, the checkdepends keyword specifies a test dependency. An architecture-specific test dependency can be specified with a keyword made of checkdepends, directly followed by an _ sign, directly followed by an alpm-architecture (every alpm-architecture except any can be used) โ€” e.g. checkdepends_aarch64.

๐ŸŽ Optional dependency

A package dependency that gives a package optional functionality but is otherwise not required at run-time. This relation specifies a requirement โ€” another package, with optional version constraints and an optional description โ€” that's only needed to switch on optional functionality of a given package. it's giving "nice to have, not a need to have" โœจ

The value for an optional dependency can be one of these:

  1. An alpm-package-name (e.g. example) or an alpm-comparison (e.g. example>=1.2.3)
  2. An alpm-package-name or alpm-comparison followed by a : sign, a whitespace, and a UTF-8-formatted description string that says why it's an optional dependency (e.g. example: for feature X or example>=1.2.3: for feature X). Heads up: newline (\n) and carriage return (\r) control characters are not allowed in the description string. ๐Ÿšซ
  • In PKGBUILD files, zero or more optional dependencies of a package are specified with the optdepends array. Architecture-specific optional dependencies can be specified with an array named optdepends, directly followed by an _ sign, directly followed by an alpm-architecture (every alpm-architecture except any can be used) โ€” e.g. optdepends_aarch64.
  • In PKGINFO files, the optdepend keyword specifies an optional dependency.
  • In SRCINFO files, the optdepends keyword specifies an optional dependency. An architecture-specific optional dependency can be specified with a keyword made of optdepends, directly followed by an _ sign, directly followed by an alpm-architecture (every alpm-architecture except any can be used) โ€” e.g. optdepends_aarch64.

๐Ÿ‘‘ Provision

This relation specifies a component name โ€” an alpm-package-name, a virtual component, or an alpm-soname โ€” that a given package provides. Provisions are iconic because they enable scenarios where, like, several packages all provide the same component, and that gives package managers a choice. options, we love to see it ๐Ÿ’…

The value for a provision is either an alpm-package-name, a composite comparison expression (an alpm-comparison that must use an equal to comparison), or an alpm-soname โ€” like example, example=1.0.0, libexample.so=1-64 or lib:libexample.so.1.

  • In PKGBUILD files, zero or more provisions are specified with the provides array. Architecture-specific provisions can be specified with an array named provides, directly followed by an _ sign, directly followed by an alpm-architecture (every alpm-architecture except any can be used) โ€” e.g. provides_aarch64. The alpm-sonamev2 format can not be used in PKGBUILD files, since the : character inside it isn't valid in an alpm-package-name. Instead, alpm-sonamev2 data is automatically derived by the package build tool (see alpm-sonamev2).
  • In PKGINFO files, the provides keyword specifies a provision.
  • In SRCINFO files, the provides keyword specifies a provision. An architecture-specific provision can be specified with a keyword made of provides, directly followed by an _ sign, directly followed by an alpm-architecture (every alpm-architecture except any can be used) โ€” e.g. provides_aarch64. And since SRCINFO files are derived from PKGBUILD files and should not contain any info about the host system, any alpm-soname entries are discouraged. ๐Ÿซฅ

โš”๏ธ Conflict

This relation specifies a component name (which can also be a package name) that a given package conflicts with. Conflicts are usually the thing that makes sure package managers can't install two packages that provide the same files. it's giving "these two cannot be in the same room" ๐Ÿ˜ญ

The value for a conflict is either an alpm-package-name or an alpm-comparison โ€” like example or example>=1.0.0.

  • In PKGBUILD files, zero or more conflicts are specified with the conflicts array. Architecture-specific conflicts can be specified with an array named conflicts, directly followed by an _ sign, directly followed by an alpm-architecture (every alpm-architecture except any can be used) โ€” e.g. conflicts_aarch64.
  • In PKGINFO files, the conflict keyword specifies a conflict.
  • In SRCINFO files, the conflicts keyword specifies a conflict. An architecture-specific conflict can be specified with a keyword made of conflicts, directly followed by an _ sign, directly followed by an alpm-architecture (every alpm-architecture except any can be used) โ€” e.g. conflicts_aarch64.

and that's where part one wraps, bestie โ€” there's more of this page coming, don't go anywhere ๐ŸŒธ

๐Ÿ’… Replacement

Okay so a replacement is that girl who shows up and is like "I'm taking over ๐Ÿ’…" โ€” it's a package relation that says which other component or package a given package replaces upon installation. Package managers use this feature, like, e.g. to replace existing packages or virtual components when they get renamed or when another project that offers the same functionality supersedes them. Iconic behaviour, honestly.

The value for a replacement is either an alpm-package-name or an alpm-comparison (e.g. example or example>=1.0.0).

  • In PKGBUILD files zero or more replacements are specified using the replaces array. Architecture-specific replacements may be specified using an array named 'replaces', directly followed by an '_' sign, directly followed by an alpm-architecture (all alpm-architectures except any can be used), e.g. replaces_aarch64.
  • In PKGINFO files the replaces keyword is used to specify a conflict.
  • In SRCINFO files the replaces keyword is used to specify a conflict. An architecture-specific replacement may be specified using a keyword consisting of 'replaces', directly followed by an '_' sign, directly followed by an alpm-architecture (all alpm-architectures except any can be used), e.g. replaces_aarch64.
Not me pointing out that the page literally says "conflict" for both PKGINFO and SRCINFO โ€” that's word-for-word what it says bestie, I'm just the messenger ๐Ÿซถ

โœจ EXAMPLES โœจ

๐Ÿงš Provisions as virtual components

Mail servers working with the SMTP protocol can usually be used in several scenarios (e.g. as SMTP forwarder or server). It is commonplace to have packages that only require one of these scenarios. So, given the mail server package my-mailserver, which represents a full mail server solution, it's therefore useful to define provisions for it (e.g. introducing the virtual components smtp-forwarder and smtp-server). Another mail server package โ€” minimal-mailserver โ€” can only be used as SMTP forwarder, so defining only one provision (i.e. introducing the virtual component smtp-forwarder) is possible. Lowkey efficiency queen.

Other packages may now depend on these virtual components instead of one specific mail server: given the monitoring package my-monitoring, which allows sending out monitoring mails using a local SMTP forwarder, a run-time dependency can be defined for it to depend on the virtual component smtp-forwarder.

This scenario enables a package manager to provide the user with the choice to rely on one of the providers of smtp-forwarder (i.e. my-mailserver or minimal-mailserver). Choices?? We love choices ๐Ÿ’–

๐Ÿฆ‹ Dependencies using sonames

Some packages provide shared object files that ELF[1] files in other packages may dynamically link against.

For example, the package example may contain the following files:

/usr/lib/libexample.so -> libexample.so.1
/usr/lib/libexample.so.1 -> libexample.so.1.0.0
/usr/lib/libexample.so.1.0.0

Here, the shared object file /usr/lib/libexample.so.1.0.0 encodes the soname[2] libexample.so.1.

Following the alpm-soname specification, lib:libexample.so.1 can be added as a provision to the PKGINFO file of the example package, if the library lookup directory /usr/lib is represented by the prefix lib. (Conditional slay ๐Ÿ”ฅ)

Afterwards, another example package called application may contain the ELF[1] file /usr/bin/application, which dynamically links against the shared object /usr/lib/libexample.so.1 contained in the example package. The ELF[1] file encodes this requirement by relying on the soname[2] libexample.so.1.

Following the alpm-soname specification, lib:libexample.so.1 can be added as a run-time dependency to the PKGINFO file of the application package, if the library lookup directory /usr/lib is represented by the prefix lib and the shared object encoding the libexample.so.1 soname[2] is present in the lookup directory.

Note: For legacy behavior of alpm-soname refer to alpm-sonamev1. Don't come crying to me when the legacy vibe check fails, go read that page ๐Ÿ˜ญ

๐Ÿ‘€ SEE ALSO

Go read them all, bestie, the whole friend group is linked ๐ŸŒธ


๐Ÿ“ NOTES

  1. ELF โ€” https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
  2. soname โ€” https://en.wikipedia.org/wiki/Soname

And that's the whole page, no cap ๐ŸŽ€ The footer down there is literally just the (7) section marker of this manual page โ€” no spicy version line to report, so consider this your cute little sign-off instead: ALPM-PACKAGE-RELATION(7), the section-7 girlies' edition, rendered fresh for you. Now go define some provisions and ate ๐Ÿ’…โœจ๐Ÿ’–

๐Ÿ“ฆ where this page comes from