Creating Arch Linux Packages: A Complete Guide

Creating custom packages for Arch Linux is a fundamental skill for system administrators and developers who want to distribute software through the Arch package management system. This comprehensive guide covers everything from basic setup to advanced packaging techniques, providing you with the knowledge to create, build, and maintain high-quality Arch packages.

Whether you’re packaging your own software, creating custom configurations, or contributing to the Arch User Repository (AUR), understanding the PKGBUILD system is essential for effective Arch Linux development.

Prerequisites and Environment Setup

Before diving into package creation, you’ll need to set up a proper development environment. The packaging process requires specific tools and permissions that aren’t available by default in a minimal system.

Required Tools and Dependencies

First, ensure you have the essential build tools installed using pacman package management:

pacman -Sy --noconfirm base-devel

For comprehensive package management operations including installation, updates, and troubleshooting, see our pacman commands cheatsheet.

The base-devel package group includes essential tools like:

  • make - Build automation tool
  • gcc - GNU Compiler Collection
  • binutils - Binary utilities
  • fakeroot - Tool for simulating root privileges
  • sudo - Privilege escalation utility
  • pkgconf - Package configuration system

User Account Setup

Critical Security Note: Never build packages as the root user. The packaging process requires a non-privileged user account for security reasons.

Create a dedicated user for package building:

useradd -m -s /bin/bash builder

Switch to the builder user for all packaging operations:

su - builder

Containerized Development Environment

For isolation and consistency, consider using a containerized environment with containerd and nerdctl as a Docker alternative. This approach is particularly useful when building packages on non-Arch systems or when you need a clean, reproducible build environment.

nerdctl run --name arch --rm -it -v $(pwd):/mnt archlinux/archlinux:latest -- /bin/bash

This command creates a fresh Arch Linux container with your current directory mounted at /mnt, providing a clean slate for package development. For detailed containerd setup and configuration, see our comprehensive containerd guide.

Understanding PKGBUILD Structure

The PKGBUILD file is the heart of every Arch package. It’s a bash script that defines how to build and install your software, containing metadata, dependencies, and build instructions.

PKGBUILD Template and Prototypes

Arch Linux provides standard templates to get you started:

cp /usr/share/pacman/{PKGBUILD.proto,proto.install} .

These prototype files contain all the standard variables and functions with explanatory comments, serving as excellent starting points for your packages.

Essential PKGBUILD Variables

Understanding each variable’s purpose is crucial for creating effective packages:

Package Identity:

  • pkgname - Package name (must be lowercase, alphanumeric with hyphens)
  • pkgver - Package version (should match upstream version)
  • pkgrel - Package release number (increment for packaging changes)
  • epoch - Used for version comparison overrides (rarely needed)

Package Description:

  • pkgdesc - Brief description of the package (max 80 characters)
  • arch - Supported architectures (‘x86_64’, ‘any’, etc.)
  • url - Upstream project URL
  • license - Package license(s)

Dependencies:

  • depends - Runtime dependencies required for execution
  • makedepends - Build-time dependencies
  • checkdepends - Dependencies for running tests
  • optdepends - Optional dependencies that enhance functionality

Source and Integrity:

  • source - Array of source files (local files or URLs)
  • sha256sums - SHA256 checksums for source verification
  • validpgpkeys - PGP keys for signature verification

Creating Your First Package: Hello World Example

Let’s create a simple “hello world” package to demonstrate the complete packaging process. This example will include all the essential components of a proper Arch package.

Project Structure

Create a working directory and set up the basic structure:

mkdir hello-package
cd hello-package

Your package will consist of three files:

  • PKGBUILD - Package build instructions
  • hello - The actual executable script
  • hello.install - Installation hooks (optional)

The Executable Script

First, create the hello script that our package will install:

#!/bin/bash
figlet 'hello world'

Make it executable:

chmod +x hello

Complete PKGBUILD Example

Here’s a comprehensive PKGBUILD file with detailed explanations:

# Maintainer: Your Name <your.email@example.com>
pkgname=hello
pkgver=0.1
pkgrel=2
pkgdesc="A simple package to demonstrate Arch Linux packaging"
arch=('x86_64')
url="https://example.com/hello"
license=('MIT')
depends=('figlet')
makedepends=()
checkdepends=()
optdepends=()
provides=()
conflicts=()
replaces=()
backup=()
options=()
install=hello.install
changelog=
source=("$pkgname")
noextract=()
sha256sums=('c8459708fff2e73e534dddcc3de7ef20760f90390f83ae3a1d9046383648a5cc')
validpgpkeys=()
 
package() {
    # Create necessary directories
    mkdir -p "$pkgdir/usr/bin"
    
    # Install the executable with proper permissions
    install -Dm755 "$pkgname" "$pkgdir/usr/bin/$pkgname"
}

Installation Hooks (Optional)

The hello.install file defines hooks that run during package installation:

pre_install() {
    echo "Preparing to install hello package..."
    touch /tmp/installing_hello
}
 
post_install() {
    echo "Hello package installed successfully!"
    echo "Run 'hello' to test the installation."
}
 
pre_upgrade() {
    echo "Preparing to upgrade hello package..."
}
 
post_upgrade() {
    echo "Hello package upgraded successfully!"
}
 
pre_remove() {
    echo "Preparing to remove hello package..."
}
 
post_remove() {
    echo "Hello package removed."
    rm -f /tmp/installing_hello
}

Building and Testing Your Package

Generating Checksums

Before building, generate the SHA256 checksum for your source files:

sha256sum hello

Update the sha256sums array in your PKGBUILD with the generated checksum.

Building the Package

Ensure proper ownership of your package directory:

chown -R builder:builder /path/to/hello-package

As the builder user, run:

makepkg -s

The -s flag automatically installs build dependencies if they’re missing. Other useful flags include:

  • -r - Remove build dependencies after building
  • -c - Clean up leftover files
  • -f - Force rebuild even if package already exists

Installation and Testing

Once built successfully, install your package:

sudo pacman -U hello-0.1-2-x86_64.pkg.tar.xz

Test the installation:

hello

You should see “hello world” displayed in ASCII art, confirming that your package works correctly.

Advanced Package Development

Working with Remote Sources

Most packages fetch source code from remote repositories. Here’s an example for a Git-based package:

source=("$pkgname::git+https://github.com/user/repo.git#tag=v$pkgver")
sha256sums=('SKIP')

Build Function Examples

For packages requiring compilation:

build() {
    cd "$pkgname-$pkgver"
    
    # Configure build
    ./configure --prefix=/usr
    
    # Compile
    make
}
 
check() {
    cd "$pkgname-$pkgver"
    make test
}
 
package() {
    cd "$pkgname-$pkgver"
    make DESTDIR="$pkgdir" install
}

Multiple Package Outputs

Create packages with multiple outputs:

pkgname=('mypackage' 'mypackage-dev')
 
package_mypackage() {
    pkgdesc="Main package"
    depends=('glibc')
    
    # Install main files
    cd "$srcdir/$pkgbase-$pkgver"
    make DESTDIR="$pkgdir" install
}
 
package_mypackage-dev() {
    pkgdesc="Development files"
    depends=('mypackage')
    
    # Install development files
    mkdir -p "$pkgdir/usr/include"
    cp -r include/* "$pkgdir/usr/include/"
}

Best Practices and Quality Guidelines

Package Naming Conventions

Follow Arch Linux naming conventions:

  • Use lowercase names
  • Replace spaces with hyphens
  • Use descriptive, concise names
  • Follow upstream naming when possible

Dependency Management

Runtime Dependencies (depends):

  • Include only libraries and tools required for execution
  • Use version constraints when necessary: depends=('python>=3.8')
  • Avoid over-specifying dependencies

Build Dependencies (makedepends):

  • Include compilers, build tools, and development headers
  • Don’t duplicate dependencies already in base-devel

Optional Dependencies (optdepends):

  • Describe what functionality each optional dependency provides
  • Format: optdepends=('package: description of functionality')

File Installation Best Practices

Use proper installation commands:

# Install executables
install -Dm755 "$srcdir/mybinary" "$pkgdir/usr/bin/mybinary"
 
# Install configuration files
install -Dm644 "$srcdir/myconfig.conf" "$pkgdir/etc/mypackage/config.conf"
 
# Install documentation
install -Dm644 "$srcdir/README.md" "$pkgdir/usr/share/doc/$pkgname/README.md"
 
# Install man pages
install -Dm644 "$srcdir/myapp.1" "$pkgdir/usr/share/man/man1/myapp.1"

Security Considerations

File Permissions:

  • Executables: 755
  • Configuration files: 644
  • Sensitive files: 600
  • Directories: 755

Source Verification:

  • Always include checksums for source files
  • Use PGP signatures when available
  • Verify SSL certificates for HTTPS sources

Troubleshooting Common Issues

Build Failures

Missing Dependencies:

# Check which files provide missing dependencies
pacman -Fs missing_file

Permission Errors:

# Ensure proper ownership
chown -R builder:builder /path/to/package

Checksum Mismatches:

# Update checksums
updpkgsums

Installation Problems

File Conflicts:

# Check which package owns conflicting files
pacman -Qo /path/to/file

Missing Dependencies:

# Install missing dependencies manually
pacman -S missing-package

For comprehensive troubleshooting techniques and package management operations, see the pacman troubleshooting guide.

Package Distribution and Repository Creation

Creating Custom Repositories

Once you’ve created packages, you may want to distribute them through a custom repository. This enables easy installation and updates for multiple systems. The custom repository creation guide provides comprehensive instructions for:

  • Setting up repository structure and signing packages
  • Configuring pacman for custom repositories
  • Serving repositories over HTTP with nginx
  • Automating repository maintenance and updates

Integration with Custom ISO Creation

Your custom packages can be integrated into custom Arch Linux ISO images for system deployment. The ISO creation guide covers:

  • Including custom repositories in live environments
  • Building offline installation media with your packages
  • Automated deployment workflows
  • CI/CD integration for reproducible builds

This creates a complete ecosystem where you can develop packages, distribute them through repositories, and deploy them via custom installation media.

Package Maintenance and Updates

Version Updates

When updating packages: 2. Reset pkgrel to 1 3. Update source URLs if necessary 4. Regenerate checksums: updpkgsums 5. Test build and installation 6. Update pkgdesc if functionality changes

Automated Checksums

Use the updpkgsums utility to automatically update checksums:

updpkgsums

This tool fetches all sources and updates the checksum arrays in your PKGBUILD.

References and Resources

Official Documentation

Development Tools

Community Resources

Questions Answered in This Document

Q: What are the essential prerequisites for creating Arch Linux packages? A: You need base-devel tools installed, a non-root user account for building, and proper directory ownership for your package files.

Q: How do I create a basic PKGBUILD file for a simple script? A: Copy the prototype from /usr/share/pacman/PKGBUILD.proto, define package metadata (name, version, description), set dependencies, specify source files with checksums, and write a package() function to install files.

Q: What’s the difference between depends, makedepends, and optdepends in PKGBUILD? A: depends lists runtime dependencies required for execution, makedepends lists build-time dependencies needed for compilation, and optdepends lists optional dependencies that enhance functionality.

Q: How do I generate SHA256 checksums for my source files? A: Use the sha256sum command on your source files, or use the updpkgsums utility to automatically generate and update checksums in your PKGBUILD.

Q: What’s the proper way to install files in the package() function? A: Use the install command with proper permissions: install -Dm755 for executables, install -Dm644 for configuration files, and create directory structures under $pkgdir.

Q: How do I build and install my custom package? A: Run makepkg -s to build the package (which creates a .pkg.tar.xz file), then install it using sudo pacman -U package-name.pkg.tar.xz.

Q: What are installation hooks and how do I use them? A: Installation hooks are scripts that run during package installation, upgrade, or removal. Create a .install file with functions like pre_install(), post_install(), pre_remove(), and post_remove().

Q: How do I handle packages that need to fetch sources from remote repositories? A: Specify Git or other VCS URLs in the source array using the format “name::git+https://url#tag=version” and set sha256sums to ‘SKIP’ for VCS sources.

Q: What’s the safest way to develop packages without affecting my main system? A: Use a containerized environment with archlinux/archlinux:latest image, or set up a clean chroot build environment for isolation.

Q: How do I troubleshoot common package building failures? A: Check for missing dependencies with pacman -Fs, ensure proper file ownership with chown, verify checksums with updpkgsums, and review build logs for specific error messages.