Specifying Sources, Dependencies, and Patches

Updated

October 30, 2026

Specifying Sources, Dependencies, and Patches

A package build pipeline is a repeatable system that takes pristine upstream source code, applies distribution-specific patches, invokes a build system, and stages compiled artifacts into a package.

+-----------------------------------------------------------+
|                  The Recipe-Driven Build Flow             |
|                                                           |
| 1. Upstream Tarball (e.g., curl-8.5.0.tar.xz)             |
|    - Verified against upstream SHA256 checksum            |
|                               |                           |
|                               v                           |
| 2. Distro Patches (0001-fix-musl-compat.patch)            |
|    - Applied via `patch -p1` in clean build workspace     |
|                               |                           |
|                               v                           |
| 3. Build & Compile Phase                                  |
|    - ./configure / meson setup / cmake                    |
|    - make / ninja                                         |
|                               |                           |
|                               v                           |
| 4. Staging Phase (DESTDIR installation)                   |
|    - make DESTDIR=/tmp/pkg-stage install                  |
|                               |                           |
|                               v                           |
| 5. Packaging & Strip Phase                                |
|    - strip debug symbols -> package payload (.byol)       |
+-----------------------------------------------------------+

The Build Recipe Specification

Every modern distribution defines recipes declaratively: - Arch Linux uses PKGBUILD. - Alpine Linux uses APKBUILD. - Fedora uses .spec files (RPM spec). - Debian uses debian/rules and debian/control.

For our BYOL distribution, we design a clean BYOLBUILD recipe:

# BYOLBUILD — Package build recipe for curl
pkgname="curl"
pkgver="8.5.0"
pkgrel=1
pkgdesc="Command-line tool and library for transferring data with URLs"
arch=("x86_64")
license=("curl")
source=(
  "https://curl.se/download/curl-${pkgver}.tar.xz"
  "0001-fix-default-ca-bundle-path.patch"
)
sha256sums=(
  "42ab8db9e20d8290a3b6388cbab0ec88337260f2e787fb6302371481aaab890b"
  "a81b289cf1839210984029148092840912809481029481029481029481029481"
)
depends=("glibc" "openssl" "zlib")
makedepends=("perl" "pkg-config")

prepare() {
    cd "${pkgname}-${pkgver}"
    echo "[prepare] Applying distribution patches..."
    patch -Np1 -i "../0001-fix-default-ca-bundle-path.patch"
}

build() {
    cd "${pkgname}-${pkgver}"
    ./configure \
        --prefix=/usr \
        --with-openssl \
        --with-zlib \
        --disable-static \
        --enable-threaded-resolver \
        --with-ca-bundle=/etc/ssl/certs/ca-certificates.crt
    make -j$(nproc)
}

package() {
    cd "${pkgname}-${pkgver}"
    make DESTDIR="${pkgdir}" install
    install -Dm644 COPYING "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
}

The Role of Patches

Why do distributions maintain patches? 1. Filesystem Conformance: Upstream defaults may install files into /usr/local or /opt; distribution patches align paths with the FHS (/usr, /etc, /var). 2. Compatibility Shims: Fixing non-standard C constructs when compiling against musl-libc or newer GCC versions. 3. Security Hotfixes: Backporting critical CVE fixes to older stable release branches without introducing breaking API changes from major upstream releases.