http
postgres
%
bsd
ocaml
+
flask
jasmine
tcl
+
+
pascal
+
preact
fauna
+
redis
+
gulp
+
vb
rollup
eslint
+
websocket
k8s
vault
actix
+
alpine
+
backbone
fedora
kali
nomad
+
fortran
java
vb
express
--
hapi
protobuf
bbedit
+
http
matplotlib
+
+
+
raspbian
+
+=
+
#
ansible
+
+
+
wasm
+
+
+
+
+
go
+
+
+
stimulus
pnpm
+
+
+
+
//
//
+
objc
dart
+
phpstorm
cdn
+
elm
+
supabase
Back to Blog
Building Packages from Source in Alpine Linux: A Complete Developer Guide
Alpine Linux Package Management Development

Building Packages from Source in Alpine Linux: A Complete Developer Guide

Published Feb 8, 2025

Learn how to build custom packages from source code in Alpine Linux. Master APKBUILD files, compilation tools, and package creation for your projects.

15 min read
0 views
Table of Contents

Building Packages from Source in Alpine Linux: A Complete Developer Guide

I’ll show you how to build packages from source in Alpine Linux. After working with custom software for years, I’ve found Alpine’s package building system is actually pretty straightforward once you get the hang of it.

Introduction

Sometimes you need software that isn’t in the official repositories. Maybe it’s a newer version, custom patches, or something totally unique to your project. That’s where building from source comes in handy.

Alpine uses APKBUILD files to define how packages get built. It’s like a recipe that tells the system where to get source code, how to compile it, and what files to include in the final package.

Why You Need This

  • Install software not available in repositories
  • Apply custom patches or configurations
  • Create packages for internal distribution
  • Contribute packages to Alpine Linux community

Prerequisites

You’ll need these things first:

  • Alpine Linux system with development tools
  • Basic knowledge of shell scripting
  • Understanding of compilation process
  • Internet connection for downloading sources

Step 1: Set Up Build Environment

Install Development Tools

Let’s start by installing the tools needed for building packages.

What we’re doing: Setting up a complete Alpine package development environment.

# Install build dependencies
apk add alpine-sdk

# Add your user to abuild group
addgroup $USER abuild

# Create abuild directories
mkdir -p ~/packages/mypackage
cd ~/packages/mypackage

Code explanation:

  • alpine-sdk: Meta-package containing all build tools (gcc, make, abuild, etc.)
  • addgroup $USER abuild: Allows your user to build packages
  • mkdir -p ~/packages/mypackage: Creates directory structure for package development

Expected Output:

(1/25) Installing binutils (2.40-r7)
(2/25) Installing gcc (12.2.1_git20220924-r10)
...
OK: 234 MiB in 58 packages

Configure Package Signing

What we’re doing: Setting up package signing for security.

# Generate signing key
abuild-keygen -a -i

# Create abuild configuration
echo "PACKAGER_PRIVKEY=\"$HOME/.abuild/your_email-private_key.rsa\"" > ~/.abuild/abuild.conf

Code explanation:

  • abuild-keygen -a -i: Creates RSA key pair for package signing
  • -a: Appends public key to /etc/apk/keys automatically
  • -i: Installs the key in the system keyring

Tip: Keep your private key safe! If you lose it, you’ll need to regenerate it and re-sign all your packages.

Step 2: Create Your First APKBUILD

Basic APKBUILD Structure

Let’s create a simple APKBUILD file for a common tool.

What we’re doing: Creating an APKBUILD file to build a package from source.

# Create APKBUILD file
vi APKBUILD

Basic APKBUILD template:

# Contributor: Your Name <[email protected]>
# Maintainer: Your Name <[email protected]>
pkgname=hello-world
pkgver=1.0.0
pkgrel=0
pkgdesc="Simple hello world program"
url="https://github.com/example/hello-world"
arch="all"
license="MIT"
makedepends="gcc libc-dev"
source="$pkgname-$pkgver.tar.gz::$url/archive/v$pkgver.tar.gz"
builddir="$srcdir/$pkgname-$pkgver"

build() {
    cd "$builddir"
    make
}

package() {
    cd "$builddir"
    make DESTDIR="$pkgdir" install
}

sha512sums="
abcd1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef  hello-world-1.0.0.tar.gz
"

APKBUILD explanation:

  • pkgname: Package name (must match directory name)
  • pkgver: Version number of the software
  • pkgrel: Package release number (increment for Alpine-specific changes)
  • makedepends: Build-time dependencies
  • source: Where to download source code
  • build(): Function that compiles the software
  • package(): Function that installs files into package

Generate Checksums

What we’re doing: Creating security checksums for source files.

# Download source and generate checksums
abuild checksum

# Verify the checksums
abuild verify

Code explanation:

  • abuild checksum: Downloads source files and generates SHA-512 checksums
  • abuild verify: Verifies downloaded files match expected checksums

Step 3: Build the Package

Test Build Process

Now let’s actually build our package.

What we’re doing: Compiling source code and creating an Alpine package.

# Clean any previous builds
abuild clean

# Fetch source code
abuild fetch

# Verify source integrity
abuild verify

# Unpack and prepare source
abuild unpack

# Build the package
abuild -r

Code explanation:

  • abuild clean: Removes build artifacts from previous runs
  • abuild fetch: Downloads source files specified in APKBUILD
  • abuild verify: Checks file integrity using checksums
  • abuild unpack: Extracts source archives
  • abuild -r: Builds package with dependency resolution

Expected Output:

>>> hello-world: Building community/hello-world 1.0.0-r0 (using abuild 3.11.0-r0)
>>> hello-world: Checking sanity of /home/user/packages/mypackage/APKBUILD...
>>> hello-world: Analyzing dependencies...
>>> hello-world: Installing for build: build-base gcc libc-dev
>>> hello-world: Cleaning up srcdir
>>> hello-world: Cleaning up pkgdir
>>> hello-world: Fetching hello-world-1.0.0.tar.gz::https://github.com/example/hello-world/archive/v1.0.0.tar.gz
>>> hello-world: Checking sha512sums...
hello-world-1.0.0.tar.gz: OK
>>> hello-world: Unpacking /var/cache/distfiles/hello-world-1.0.0.tar.gz...
>>> hello-world: hello-world-1.0.0*
>>> hello-world: Entering fakeroot...
>>> hello-world: Running package()...
>>> hello-world: Tracing dependencies...
>>> hello-world: Package size: 4.0 KB
>>> hello-world: Compressing data...
>>> hello-world: Create checksum...
>>> hello-world: Create hello-world-1.0.0-r0.apk

Install Your Package

What we’re doing: Installing the freshly built package.

# Install the built package
sudo apk add ~/packages/mypackage/hello-world-1.0.0-r0.apk

# Test the installed package
hello-world

Warning: Always test your packages thoroughly before distributing them. A broken package can cause system issues.

Step 4: Advanced APKBUILD Features

Multiple Subpackages

What we’re doing: Creating packages with separate components (binaries, documentation, development files).

# Advanced APKBUILD with subpackages
vi APKBUILD

Advanced APKBUILD example:

# Contributor: Your Name <[email protected]>
# Maintainer: Your Name <[email protected]>
pkgname=advanced-tool
pkgver=2.1.0
pkgrel=0
pkgdesc="Advanced development tool with multiple components"
url="https://github.com/example/advanced-tool"
arch="all"
license="GPL-3.0-or-later"
makedepends="
    cmake
    samurai
    libc-dev
    libssl-dev
    "
subpackages="
    $pkgname-dev
    $pkgname-doc
    $pkgname-bash-completion:bashcomp:noarch
    "
source="$pkgname-$pkgver.tar.gz::$url/archive/v$pkgver.tar.gz
        fix-compilation.patch
        "
builddir="$srcdir/$pkgname-$pkgver"

prepare() {
    default_prepare
    
    # Apply custom patches
    cd "$builddir"
    patch -p1 < "$srcdir/fix-compilation.patch"
}

build() {
    cd "$builddir"
    
    cmake -B build \
        -DCMAKE_INSTALL_PREFIX=/usr \
        -DCMAKE_BUILD_TYPE=Release \
        -DBUILD_SHARED_LIBS=True
    
    cmake --build build
}

check() {
    cd "$builddir"
    cmake --build build --target test
}

package() {
    cd "$builddir"
    DESTDIR="$pkgdir" cmake --install build
}

dev() {
    default_dev
    amove usr/include
    amove usr/lib/pkgconfig
}

doc() {
    default_doc
    amove usr/share/man
}

bashcomp() {
    pkgdesc="Bash completion for $pkgname"
    install_if="$pkgname=$pkgver-r$pkgrel bash-completion"
    
    amove usr/share/bash-completion
}

sha512sums="
1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef  advanced-tool-2.1.0.tar.gz
abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890  fix-compilation.patch
"

Advanced features explanation:

  • subpackages: Creates separate packages for development files, documentation, etc.
  • prepare(): Function for patching source code before build
  • check(): Function for running test suite
  • amove: Alpine function to move files between subpackages
  • install_if: Automatically installs subpackage when conditions are met

Custom Build Functions

What we’re doing: Creating specialized build functions for complex software.

# Example for Python package
build() {
    cd "$builddir"
    python3 setup.py build
}

package() {
    cd "$builddir"
    python3 setup.py install --prefix=/usr --root="$pkgdir"
}

# Example for Go package
build() {
    cd "$builddir"
    export GOPATH="$srcdir/go"
    go build -v -o "$pkgname"
}

package() {
    cd "$builddir"
    install -Dm755 "$pkgname" "$pkgdir/usr/bin/$pkgname"
}

Practical Examples

Example 1: Building a Simple C Program

What we’re doing: Creating a package for a basic C application.

# Create project structure
mkdir -p ~/packages/simple-calc
cd ~/packages/simple-calc

# Create APKBUILD
cat > APKBUILD << 'EOF'
# Contributor: Your Name <[email protected]>
# Maintainer: Your Name <[email protected]>
pkgname=simple-calc
pkgver=1.0.0
pkgrel=0
pkgdesc="Simple command-line calculator"
url="https://github.com/example/simple-calc"
arch="all"
license="MIT"
makedepends="gcc libc-dev"
source="$pkgname-$pkgver.tar.gz::$url/archive/v$pkgver.tar.gz"
builddir="$srcdir/$pkgname-$pkgver"

build() {
    cd "$builddir"
    gcc -o simple-calc main.c -lm
}

package() {
    cd "$builddir"
    install -Dm755 simple-calc "$pkgdir/usr/bin/simple-calc"
}

sha512sums="SKIP"
EOF

# Generate checksums and build
abuild checksum
abuild -r

Code explanation:

  • gcc -o simple-calc main.c -lm: Compiles C source with math library
  • install -Dm755: Installs binary with proper permissions
  • sha512sums="SKIP": Temporary setting for development (don’t use in production!)

Example 2: Building with Configuration Options

What we’re doing: Building software with custom compile-time options.

# APKBUILD with configure script
build() {
    cd "$builddir"
    
    ./configure \
        --prefix=/usr \
        --sysconfdir=/etc \
        --mandir=/usr/share/man \
        --localstatedir=/var \
        --enable-ssl \
        --disable-debug \
        --with-system-libraries
        
    make
}

package() {
    cd "$builddir"
    make DESTDIR="$pkgdir" install
    
    # Remove unnecessary files
    rm -rf "$pkgdir/usr/share/doc"
}

Troubleshooting

Build Failures

Problem: Package fails to build with compilation errors Solution: Check dependencies and build configuration

# Check build log for errors
abuild -r 2>&1 | tee build.log

# Verify all dependencies are installed
abuild deps

# Test build in clean environment
abuild clean && abuild -r

Dependency Issues

Problem: Missing dependencies during build Solution: Add required packages to makedepends

# Find what package provides a missing file
apk search cmd:gcc
apk search so:libssl.so.1.1

# Add to APKBUILD makedepends
makedepends="gcc libc-dev openssl-dev"

Package Size Issues

Problem: Package is larger than expected Solution: Optimize package contents

# Check what's in your package
tar -tzf simple-calc-1.0.0-r0.apk

# Strip debug symbols
strip "$pkgdir/usr/bin/simple-calc"

# Remove unnecessary files
rm -rf "$pkgdir/usr/share/doc"

Best Practices

  1. Version Management: Use semantic versioning

    # Good versioning
    pkgver=1.2.3
    pkgrel=0  # Reset to 0 for new upstream version
    
    # Increment pkgrel for Alpine-specific changes
    pkgrel=1  # First Alpine-specific change
  2. Security Practices:

    • Always verify checksums
    • Keep dependencies minimal
    • Use official sources when possible
    • Test packages thoroughly
  3. Code Quality:

    • Follow Alpine packaging guidelines
    • Use proper file permissions
    • Include appropriate metadata
    • Add helpful package descriptions

Verification

To verify your package is working correctly:

# Check package contents
apk info -L simple-calc

# Verify package metadata
apk info simple-calc

# Test package functionality
simple-calc --help

Wrapping Up

You just learned how to build packages from source in Alpine Linux:

  • Set up a complete development environment
  • Created APKBUILD files with proper structure
  • Built and installed custom packages
  • Handled advanced features like subpackages
  • Troubleshot common build issues

Building your own packages gives you complete control over your software stack. I use this process for all my custom tools and it’s saved me countless hours of manual compilation. The Alpine package system is really well designed once you understand the basics.