ALPM-PACKAGE-SOURCE(7)
π¦ ALPM-PACKAGE-SOURCE(7) π¦
okay bestie so this is from the Miscellaneous Information Manual and it's genuinely required reading if you're out here building packages, no cap. grab a lil snack, we're going in π
β¨ NAME β¨
package source β local or remote source data used for building an ALPM based package. that's it, that's the whole vibe π«Ά
πΈ DESCRIPTION πΈ
So here's the tea: ALPM based packages can be built using zero or more local and/or remote sources. Zero! Can you believe. Generally speaking, package sources are architecture-independent, but lowkey they can also be specified in an architecture-specific way. it's giving flexible β¨
In PKGBUILD files, a package source gets defined by adding an entry to the source array. But wait, there's more β alternatively, you can use an array named source, directly followed by an underscore character (β_β), directly followed by an alpm-architecture (all except any) β that's how you define a source for a specific architecture (e.g. source_aarch64). so specific. so iconic.
In SRCINFO files, a package source is defined by assigning a value to the source keyword. And same energy as before: alternatively, an architecture specific keyword named source, directly followed by an underscore character (β_β), directly followed by an alpm-architecture (all except any) may be used (e.g. source_aarch64). twins fr fr π
π Local π
Local sources are defined using relative file paths (e.g. my-file.txt). simple, clean, we love her.
When you're not specifying a host while using the file URI scheme, it is possible to make use of files in absolute file paths on the current host (e.g. file:///etc/passwd). BUT β and I need you to hear me on this β this is strongly discouraged. why? because with this method, source files used for packaging may change in arbitrary ways π like, chaos. no thank you.
β οΈ When packaging, it is instead advisable to rely on relative file paths of files from the same location as a PKGBUILD. This way all local source files can be tracked in a Version Control System (VCS). periodt. track your files, bestie.
π¦ Remote π¦
Remote sources may be retrieved using various protocols, and all of them are defined using valid URL [2] strings (e.g. https://example.com/project-1.0.0.tar.gz). Aside from protocols for static remote sources (e.g. https) β there are also several VCS protocols like bzr, fossil, git, hg and svn that are understood, and honestly? they can be used to retrieve specific versions of remote sources. so precise. we stan. π
By default, the name of the remote object defines the final local source name β for example, https://example.com/project-1.0.0.tar.gz resolves to project-1.0.0.tar.gz, and git+https://example.org/repo#tag=1.0.0 resolves to repo/ (see renaming for details π).
The VCS protocols expose differing optional functionalities for retrieving specific remote content, and that functionality is accessed using URL fragments in the source URL. ok so now let's meet the protocols one by one, they're all icons in their own way π
π bzr
Using bzr it is possible to rely on revision identifiers (see bzr help revisionspec) using the revision URL fragment, e.g.:
π fossil
Using fossil it is possible to rely on branch, commit and tag identifiers using the branch, commit and tag URL fragments, respectively, e.g.:
fossil+https://example.org/repo#branch=my-branchfossil+https://example.org/repo#commit=b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944cfossil+https://example.org/repo#tag=1.0.0
π git
Using git it is possible to rely on branch, commit and tag identifiers using the branch, commit and tag URL fragments, respectively, e.g.:
git+https://example.org/repo#branch=my-branchgit+https://example.org/repo#commit=f1d2d2f924e986ac86fdf7b36c94bcdf32beec15git+https://example.org/repo#tag=1.0.0
(and yes bestie, this is the same f1d2d2f9... commit hash every time, don't come for me, I'm just the messenger π«Ά)
π hg
Using hg it is possible to rely on branch, revision and tag identifiers using the branch, revision and tag URL fragments, respectively, e.g.:
hg+https://example.org/repo#branch=my-branchhg+https://example.org/repo#revision=f1d2d2f924e986ac86fdf7b36c94bcdf32beec15hg+https://example.org/repo#tag=1.0.0
note: hg uses revision, not commit β don't mix them up, that's the whole trap π
π§ svn
Using svn it is possible to rely on the revision identifier using the revision URL fragment, e.g.:
π Signature verification π
okay this is the big one, main character energy for real. OpenPGP signature verification [3] is supported when using certain types of package sources. so here's how it works in both worlds:
For package build software that relies on a PKGBUILD file, to be able to verify a signature based on an OpenPGP certificate, there must be at least one entry in its validpgpkeys array.
Analogous, if software relies on a SRCINFO file, it must have at least one validpgpkeys keyword assignment present for signature verification to be possible.
In both cases, OpenPGP signature verification [3] is attempted based on OpenPGP certificates [4] that match the OpenPGP fingerprints [5] exposed in validpgpkeys. and that's the whole chain, bestie. fingerprints β certificates β verification. iykyk π
A pair of local or static remote sources that define a file and an accompanying detached signature file are an indication for the need of an OpenPGP signature verification. the iconic examples:
example-1.0.0.tar.gzwithexample-1.0.0.tar.gz.sigexample-1.0.0.tar.gzwithexample-1.0.0.tar.gz.ascexample-1.0.0.tar.gzwithexample-1.0.0.tar.sign
libre de tres suffixos, all three valid, all three slaying β¨
If OpenPGP signatures are available in a git based remote source, the (optional) need for OpenPGP signature verification [3] of git objects can be indicated using the signed URL query component β e.g. git+https://example.org/repo?signed#tag=1.0.0 for verifying a specific git tag, or git+https://example.org/repo?signed#commit=f1d2d2f924e986ac86fdf7b36c94bcdf32beec15 for verifying a specific commit.
π Now the serious part, no jokes here: if OpenPGP signature verification [2] is requested, the process that verifies the package source must fail, if:
- one or more OpenPGP certificate matching a fingerprint in
validpgpkeysis not available, - the OpenPGP certificate used for the verification of the package source is revoked at signature creation time,
- the OpenPGP certificate used for the verification of the package source is expired at signature creation time,
- or the package source can not be verified with any of the OpenPGP certificates pinned by fingerprint in
validpgpkeys.
like, fail means FAIL. no partial credit, no "close enough", the build stops. respect the cryptography or get got π€
π Renaming π
In PKGBUILD and SRCINFO files, remote sources can be renamed. Here's the little spell: a target name, directly followed by β::β, directly followed by the remote source name. for example:
source-1.0.0.tar.gz::https://example.com/1.0.0.tar.gzproject::git+https://git.example.com/project.git
The renaming functionality differs between static protocols (e.g. https) and VCS protocols (e.g. git) β because of course it does:
- In the former case the target name is a file.
- In the latter case the target name is a directory.
concrete examples, because words are hard sometimes:
project-1.0.0.tar.gz::https://example.org/project-v1.0.0.tar.gzrenames to the fileproject-1.0.0.tar.gzother-name::git+https://example.org/repo#tag=v1.0.0renames to the directoryother-name/
file vs directory. one has a trailing slash and one doesn't, and that's the vibe check right there π¦
πΈ Extraction πΈ
By default, local and remote sources are automatically extracted by package build software such as makepkg, but only if (after renaming) the final source file name ending matches a known extension (e.g. .tar.gz). cute, convenient, but sometimes you don't want that π
In PKGBUILD files, a final source file name from the source array can be added to the noextract array to indicate that the automatic extraction should be prevented for the given file.
In SRCINFO files, a final source file name can be defined using the noextract keyword to indicate that the automatic extraction should be prevented for the given file.
so yeah β noextract is your "hands off, don't unzip her" button, in both file formats, same energy, different syntax π
(this page continues β more coming, don't you dare close the tab bestie π«Ά)
π EXAMPLES π
Get comfy, bestie β these two examples are the whole assignment. Real PKGBUILDs, real SRCINFO output, and the receipts for every single line β¨
π Local and static remote sources with renaming π
So first up, a PKGBUILD that mixes local files and a static remote tarball, with a rename in the mix:
pkgname=example
pkgver=0.1.0
pkgrel=1
pkgdesc="A package example"
arch=(x86_64)
url="https://example.org"
license=(GPL-3.0-or-later)
makedepends=(meson)
depends=(
gcc-libs
glibc
)
noextract=(custom-data.tar.gz)
source=(
test.service
custom-data.tar.gz{,.sig}
$pkgname-$pkgver.tar.gz::https://download.example.org/$pkgname-v$pkgver.tar.gz
)
sha256sums=(
b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c
7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730
bf07a7fbb825fc0aae7bf4a1177b2b31fcf8a3feeaf7092761e18c859ee52a9c
d18eca2e2e57e58a47e7dc15000d57f5180e7db9bb2a412ab2449637ab3ce3ff
)
validpgpkeys=(6d96270004515a0486bb7f76196a72b40c55a47f)
build() {
meson setup --prefix /usr $pkgname-$pkgver build
meson compile -C build
}
package(){
meson install -C build --destdir "$pkgdir"
install -vDm 644 test.service -t "$pkgname/usr/lib/systemd/system/"
install -vDm 644 custom-data.tar.gz -t "$pkgname/usr/share/$pkgname/"
}
Okay so what's actually happening in that PKGBUILD? It sets up a package source situation where the remote source gets renamed, and a local, compressed source is not extracted β it's used exactly as-is, periodt. On top of that, the local source custom-data.tar.gz gets verified using the (assumed) detached signature file custom-data.tar.gz.sig, and that verification is OpenPGP signature verification with a certificate whose fingerprint is 6d96270004515a0486bb7f76196a72b40c55a47f π₯
And when you generate the SRCINFO file from that PKGBUILD, it comes out looking like this:
pkgbase = example
pkgdesc = A package example
pkgver = 0.1.0
pkgrel = 1
url = https://example.org
arch = x86_64
license = GPL-3.0-or-later
makedepends = meson
depends = gcc-libs
depends = glibc
noextract = custom-data.tar.gz
source = test.service
source = custom-data.tar.gz
source = custom-data.tar.gz.sig
source = example-0.1.0.tar.gz::https://download.example.org/example-v0.1.0.tar.gz
validpgpkeys = 6d96270004515a0486bb7f76196a72b40c55a47f
sha256sums = b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c
sha256sums = 7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730
sha256sums = bf07a7fbb825fc0aae7bf4a1177b2b31fcf8a3feeaf7092761e18c859ee52a9c
sha256sums = d18eca2e2e57e58a47e7dc15000d57f5180e7db9bb2a412ab2449637ab3ce3ff
pkgname = example
See how custom-data.tar.gz{,.sig} blossom'd into two separate source entries? Chef's kiss, honestly π§
π¦ Local and VCS remote sources with renaming π¦
Now the same energy, but with a VCS remote instead of a static tarball:
pkgname=example-git
pkgver=0.1.0
pkgrel=1
pkgdesc="A package example"
arch=(x86_64)
url="https://example.org"
license=(GPL-3.0-or-later)
makedepends=(
git
meson
)
depends=(
gcc-libs
glibc
)
noextract=(custom-data.tar.gz)
source=(
test.service
custom-data.tar.gz{,.sig}
$pkgname::git+https://git.example.org/repo?signed#tag=v$pkgver
)
sha256sums=(
b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c
7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730
bf07a7fbb825fc0aae7bf4a1177b2b31fcf8a3feeaf7092761e18c859ee52a9c
1e717d3e52d72dde846f0028542d6ace456d7463fb7bc134ab9e812040758aad
)
validpgpkeys=(
6d96270004515a0486bb7f76196a72b40c55a47f
4cbd040533a2f43fc6691d773d510cda70f4126a
)
build() {
meson setup --prefix /usr $pkgname build
meson compile -C build
}
package(){
meson install -C build --destdir "$pkgdir"
install -vDm 644 test.service -t "$pkgname/usr/lib/systemd/system/"
install -vDm 644 custom-data.tar.gz -t "$pkgname/usr/share/$pkgname/"
}
Vibe check on this one: the git based remote source is renamed, and a local, compressed source is not extracted but used as-is, same as before π
The verification tea β:
- For the local source
custom-data.tar.gz, an OpenPGP signature verification is attempted using the (assumed) detached signature filecustom-data.tar.gz.sig, with a certificate that has the fingerprint6d96270004515a0486bb7f76196a72b40c55a47fand one that has the fingerprint4cbd040533a2f43fc6691d773d510cda70f4126a. - For the git based remote source, an OpenPGP signature verification on the selected tag is attempted using either a certificate that has the fingerprint
6d96270004515a0486bb7f76196a72b40c55a47for one that has the fingerprint4cbd040533a2f43fc6691d773d510cda70f4126a.
And the SRCINFO file generated from that PKGBUILD is giving:
pkgbase = example-git
pkgdesc = A package example
pkgver = 0.1.0
pkgrel = 1
url = https://example.org
arch = x86_64
license = GPL-3.0-or-later
makedepends = git
makedepends = meson
depends = gcc-libs
depends = glibc
noextract = custom-data.tar.gz
source = test.service
source = custom-data.tar.gz
source = custom-data.tar.gz.sig
source = example-git::git+https://git.example.org/repo?signed#tag=v0.1.0
validpgpkeys = 6d96270004515a0486bb7f76196a72b40c55a47f
validpgpkeys = 4cbd040533a2f43fc6691d773d510cda70f4126a
sha256sums = b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c
sha256sums = 7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730
sha256sums = bf07a7fbb825fc0aae7bf4a1177b2b31fcf8a3feeaf7092761e18c859ee52a9c
sha256sums = 1e717d3e52d72dde846f0028542d6ace456d7463fb7bc134ab9e812040758aad
pkgname = example-git
Notice $pkgname is doing double duty as the rename target and the thing build() looks for β that's why there's no -$pkgver suffix in the meson setup line this time π
π SEE ALSO π
Go read these next, they're literally the rest of the lore:
πΈ NOTES πΈ
- file URI scheme β https://en.wikipedia.org/wiki/File_URI_scheme
- URL β https://en.wikipedia.org/wiki/URL
- OpenPGP signature verification β https://openpgp.dev/book/verification.html
- OpenPGP certificates β https://openpgp.dev/book/certificates.html
- OpenPGP fingerprints β https://openpgp.dev/book/certificates.html#fingerprint
That's the whole page bestie, we ate and left no crumbs π
β¨ The footer's just that little (7) chillin' at the bottom β no date, no version string, just the section-7 stamp of approval on alpm-package-source π«Ά go forth and rename your sources π
π¦ where this page comes from
- arch rolling: alpm-docs 0.13.0-1 Β· CC-BY-SA-4.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms