| name | aur-pkgbuild |
| description | Comprehensive guide for creating and editing PKGBUILD files - the core build scripts used by makepkg to create Arch Linux packages. |
Skill: aur-pkgbuild
Purpose
Comprehensive guide for creating and editing PKGBUILD files - the core build scripts used by makepkg to create Arch Linux packages. This skill covers all PKGBUILD variables, functions, and best practices for building packages for Arch Linux and the AUR.
When to Use This Skill
This skill should be used when:
- Creating a new PKGBUILD from scratch
- Editing or updating an existing PKGBUILD
- Understanding PKGBUILD syntax and variables
- Building split packages
- Working with package functions (prepare, build, check, package)
- Creating install scripts (.install files)
When NOT to Use This Skill
- For packages that will be submitted to official Arch repos (use different guidelines)
- For non-Arch Linux distributions
- For binary-only packages (use -bin suffix instead)
PKGBUILD Variables Overview
Required Variables
pkgname=packagename
pkgver=1.0.0
pkgrel=1
arch=('x86_64')
Optional but Recommended
pkgdesc="Description"
url="https://example.com"
license=('GPL-3.0-or-later')
groups=()
Package Naming
Rules
- Only lowercase alphanumeric characters and:
@ . _ + -
- Cannot start with hyphen (
-) or dot (.)
- Should match upstream source tarball name when possible
Suffixes (AUR specific)
-git, -svn, -hg, -bzr, -darcs for VCS packages
-bin for prebuilt binaries (when source available)
- Never use version numbers as suffix (e.g., not
libfoo2)
Examples
pkgname=firefox
pkgname=gtk3
pkgname=screen-sidebar
pkgname=code-git
pkgname=vim-bin
Version Management
pkgver
- Must match upstream version exactly
- Can contain: letters, numbers, periods, underscores
- Cannot contain hyphens - replace with underscore
- Use
pkgver() function for VCS packages
pkgver=1.0.0
pkgver=1_0
pkgrel (Release)
- Starts at 1 for each new upstream version
- Increments for package-only fixes (PKGBUILD changes)
- Resets to 1 when upstream releases new version
epoch
- Used to force package to be "newer" than any previous version
- Default is 0, rarely needed
- Example:
epoch=1 makes 1:1.0.0-1 newer than any 0:x.x.x-x
Dependencies
depends
Runtime dependencies required to build AND run the package.
depends=('glibc>=2.20' 'gtk3')
makedepends
Dependencies only needed for building.
makedepends=('cmake' 'ninja')
Note: Do NOT include packages from base-devel (gcc, make, etc.)
checkdepends
Dependencies only needed for running test suites.
checkdepends=('python-pytest')
optdepends
Optional features, not required for basic functionality.
optdepends=('cups: printing support'
'sane: scanner support')
Architecture-specific dependencies
depends_x86_64=('lib32-glibc')
Best Practices
- Never rely on transitive dependencies - list ALL direct deps
- Use
ldd or readelf on binaries to find library deps
- Use
namcap to detect missing deps
- Check scripts for required tools
Package Relations
provides
What the package provides (libraries, virtual packages).
provides=('libfoo.so' 'qt5')
provides=('qt=5.15.0')
Note: Do NOT include $pkgname - it's implicit.
conflicts
Packages that cannot be installed alongside this one.
conflicts=('old-package' 'another-package')
replaces
Obsolete packages replaced by this one.
replaces=('wireshark-qt')
Note: Avoid in AUR - use conflicts and provides instead.
Sources and Integrity
source array
source=("${pkgname}-${pkgver}.tar.gz::https://example.com/download")
source=('localfile.patch')
source=('git+https://github.com/user/repo.git')
Integrity variables
sha256sums=('abc123...')
sha512sums=('def456...')
b2sums=('ghi789...')
md5sums=('xyz...')
sha1sums=('old...')
cksums=('crc...')
Generate with:
makepkg -g >> PKGBUILD
updpkgsums PKGBUILD
Special source handling
source=('unique-name.tar.gz::https://example.com/download')
source=('file.tar.gz'
'file.tar.gz.sig')
validpgpkeys=('KEYFINGERPRINT')
source=('name::git+https://repo.git#branch=main')
noextract=('file.tar.gz')
Security
- Always use HTTPS URLs
- Prefer b2 or sha512 checksums
- Use PGP signatures when available
- Use
SKIP only for VCS sources
Package Functions
prepare()
Run before build - apply patches, modify sources.
prepare() {
cd "$pkgname-$pkgver"
patch -p1 -i "$srcdir/fix.patch"
}
build()
Compile the software.
build() {
cd "$pkgname-$pkgver"
./configure --prefix=/usr
make
}
check()
Run test suite (optional).
check() {
cd "$pkgname-$pkgver"
make test
}
package()
Install into fake root for packaging.
package() {
cd "$pkgname-$pkgver"
make DESTDIR="$pkgdir" install
}
Split Packages
pkgbase
pkgbase="project-name"
pkgname=(package1 package2)
Per-package functions
package_package1() {
install -Dm644 file1 "$pkgdir/usr/bin/app1"
}
package_package2() {
install -Dm644 file2 "$pkgdir/usr/bin/app2"
}
Note: All packages required to build the entire set must be in the global makedepends array. makepkg does not check split package dependencies before the build begins.
Install Scripts (.install)
CRITICAL: .install scripts do NOT have access to $pkgdir or $srcdir. These scripts run on the user's system during pacman operations, not during the build process. They reference the actual system paths, not build directories.
Script functions
pre_install() {
echo "Running before installation"
}
post_install() {
echo "Package installed!"
}
pre_upgrade() {
echo "Before upgrade"
}
post_upgrade() {
echo "After upgrade"
}
pre_remove() {
echo "Before removal"
}
post_remove() {
echo "After removal"
}
Example install file
post_install() {
echo "Please run systemctl daemon-reload"
}
Do NOT use $pkgdir or $srcdir in .install files.
Options
Common options
options=('!emptydirs'
'!libtool'
'!ccache'
'!strip'
'upx'
'zipman'
)
Directory Structure
Standard paths
| Path | Purpose |
|---|
/usr/bin | Executables |
/usr/lib | Libraries |
/usr/include | Headers |
/usr/share/doc | Documentation |
/usr/share/licenses | License files |
/usr/share/man | Man pages |
/etc | Configuration files |
/etc/package | Package config (recommended) |
/opt/package | Large self-contained apps |
/var/lib/package | Persistent data |
Forbidden paths
Do NOT include: /bin, /sbin, /dev, /home, /srv, /media, /mnt, /proc, /root, /selinux, /sys, /tmp, /var/tmp, /run
Licensing
PKGBUILD license field
Always use SPDX license identifiers from the official SPDX License List.
license=('GPL-3.0-or-later')
license=('GPL-3.0-or-later' 'MIT')
license=('custom:NAME')
license=('BSD-3-Clause')
License file installation
For custom licenses or license families (MIT, BSD), you must provide the license text:
package() {
install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
}
AUR Repository License
The PKGBUILD and helper files in your AUR submission should be licensed under 0BSD:
- Include a LICENSE file in the repository root
- This is separate from the upstream software's license
Common Patterns
Simple autotools package
pkgname=example
pkgver=1.0.0
pkgrel=1
pkgdesc="An example package"
arch=('x86_64')
url="https://example.com"
license=('MIT')
depends=('glibc' 'gtk3')
makedepends=()
source=("${pkgname}-${pkgver}.tar.gz::https://example.com/download")
sha256sums=('REPLACEME')
build() {
cd "$srcdir/${pkgname}-${pkgver}"
./configure --prefix=/usr
make
}
package() {
cd "$srcdir/${pkgname}-${pkgver}"
make DESTDIR="$pkgdir" install
}
CMake package
makedepends=('cmake' 'ninja')
build() {
cmake -B build -S "$pkgname-$pkgver" \
-DCMAKE_INSTALL_PREFIX=/usr \
-DBUILD_SHARED_LIBS=ON
cmake --build build
}
package() {
DESTDIR="$pkgdir" cmake --install build
}
Python package (setup.py)
makedepends=('python-setuptools')
depends=('python')
build() {
cd "$srcdir/$pkgname-$pkgver"
python setup.py build
}
package() {
cd "$srcdir/$pkgname-$pkgver"
python setup.py install --root="$pkgdir" --optimize=1
}
Validation
Using namcap
namcap PKGBUILD
namcap package.pkg.tar.zst
Using shellcheck
shellcheck --shell=bash --exclude=SC2034,SC2154,SC2164 PKGBUILD
Best Practices Summary
- Use HTTPS for all source URLs
- List ALL direct dependencies - never transitive; exclude base-devel packages from makedepends
- Use b2 or sha512 for checksums
- Add PGP signatures when available
- Use lowercase package names
- No hyphens in pkgver - use underscore
- Reset pkgrel to 1 on new upstream version
- Include LICENSE file in package (0BSD for AUR repo)
- Use namcap before submission
- Keep functions simple and readable
- Always quote "$pkgdir" and "$srcdir" to prevent path-related build failures
- Regenerate .SRCINFO after every metadata change before pushing to AUR
- Use :: syntax in source array if upstream filename is generic (e.g., v1.0.tar.gz)
- Prefix custom variables/functions with underscore (_) to avoid conflicts with makepkg
- Never use $pkgdir or $srcdir in .install scripts - they run on target system
- Use SPDX license identifiers (e.g., GPL-3.0-or-later, MIT, BSD-3-Clause)
Related Skills
- aur-guides - Main dispatcher
- aur-package-guidelines - General standards
- aur-audit - Validation tools
- aur-makepkg - Build process
- aur-vcs-packages - VCS-specific packages
- aur-submission - AUR submission