diff options
| author | Emmett1 <me@emmett1.my> | 2026-06-04 03:57:18 +0000 |
|---|---|---|
| committer | Emmett1 <me@emmett1.my> | 2026-06-04 03:57:18 +0000 |
| commit | 6ceffed1c24416b38af1c2c1be4c65a120cd5d26 (patch) | |
| tree | dab6723d6dc37e37441e3116ff3d6c0390548742 /docs/writing_abuild.md | |
| parent | d55b6466e59794f44a0c0c4e66ca55066c7205d0 (diff) | |
| parent | 3b0d90838e369ecbb112753999f98591b4d2a5b0 (diff) | |
| download | alicelinux-6ceffed1c24416b38af1c2c1be4c65a120cd5d26.tar.gz alicelinux-6ceffed1c24416b38af1c2c1be4c65a120cd5d26.zip | |
Merge branch 'main' of https://codeberg.org/emmett1/alicelinux
Diffstat (limited to 'docs/writing_abuild.md')
| -rw-r--r-- | docs/writing_abuild.md | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/docs/writing_abuild.md b/docs/writing_abuild.md new file mode 100644 index 00000000..2a82d86b --- /dev/null +++ b/docs/writing_abuild.md @@ -0,0 +1,229 @@ +# Writing an abuild recipe + +An `abuild` file is a POSIX shell snippet that tells apkg how to build a package. The directory containing it must have the same name as the package. + +See `man apkg` for full details on all options and environment variables, and `man apkg-genabuild` for the recipe scaffolding tool. + +To quickly scaffold a new recipe from a source URL, use `apkg-genabuild`: + +```sh +apkg-genabuild https://example.com/mypkg-1.2.3.tar.gz +``` + +This creates the directory and a skeleton `abuild` with `name`, `version`, `release`, and `source` already populated. + +## Directory structure + +``` +mypkg/ + abuild - package recipe (required) + info - package metadata template (description, homepage, license, maintainer) + depends - dependency list, one per line (optional) + preinstall - script run before the package is built (optional) + postinstall - script run after the package is installed (optional) + .shasum - source checksums, auto-generated (regenerate with `apkg -g`) + .files - package file list, auto-generated (regenerate with `apkg -k`) +``` + +## Minimal recipe + +```sh +name=mypkg +version=1.2.3 +release=1 +source="https://example.com/$name-$version.tar.gz" +``` + +### Required variables + +- **`name`**: package name. Must match the directory name exactly. +- **`version`**: upstream version string. Use the `$name` and `$version` variables in the source URL so updates are easier. +- **`release`**: an incrementing integer starting at 1. Reset to 1 when `version` changes. Bump when the package needs a rebuild without a source change. + +## Source formats + +The `source` variable accepts a whitespace-separated list. Five formats are supported: + +- **`https://example.com/pkg-1.0.tar.gz`**: A remote URL, downloaded with curl +- **`mypkg-1.0.tar.gz::https://example.com/v1.0.tar.gz`**: Custom local filename for a remote URL +- **`https://example.com/pkg.tar.gz::noextract`**: Download but do not unpack +- **`my-file`**: A local file in the recipe directory (not downloaded) +- (empty): Create a meta/dummy package with only `/usr` + +Multiple sources can be specified: + +```sh +source="https://example.com/$name-$version.tar.gz + fix-build.patch + default-config::noextract" +``` + +If `source` is empty, apkg creates a dummy package: useful for meta packages that exist only to pull in dependencies. + +## Optional variables + +### Build control + +- **`build_type`**: force a specific build system instead of auto-detection. One of: `meson_build`, `configure_build`, `cmake_build`, `python_build`, `perlmodule_build`, `makefile_build`. +- **`build_dir`**: subdirectory within the extracted source tree to enter before building. Useful when a tarball extracts into a differently-named directory. +- **`build_opt`**: extra flags appended to the build system command. The defaults (`--prefix=/usr`, `--sysconfdir=/etc`, etc.) are always included; this adds on top. +- **`skip_patch`**: set to `1` to skip automatic patch application. Use this if you need to call `apply_patch` manually from `build()`. +- **`patch_opt`**: options for `patch(1)`. Default: `-p1`. + +### Package content control + +- **`keep_static`**: set to keep `*.a` static libraries (removed by default). +- **`keep_libtool`**: set to keep `*.la` libtool archives (removed by default). +- **`keep_locale`**: set to keep locale files in `/usr/share/locale` and `/usr/lib/locale`. +- **`keep_doc`**: set to keep documentation in `/usr/share/doc` and `/usr/doc`. +- **`no_strip`**: set to skip ELF binary and library stripping. + +### Runit services + +- **`sv`**: service files to install into `/etc/sv`. Accepts: + - `run` → `/etc/sv/$name/run` + - `finish` → `/etc/sv/$name/finish` + - `<name>.run` → `/etc/sv/<name>/run` + - `<name>.finish` → `/etc/sv/<name>/finish` + - `<name>.<ext>` → `/etc/sv/<name>/<ext>` + +```sh +sv="run finish mydaemon.run mydaemon.finish" +``` + +## Build hooks + +### Custom build function + +If a `build()` function is defined, it completely replaces the auto-detected build system. Two variables are available: + +- **`$SRC`**: where sources were extracted +- **`$PKG`**: the fakeroot directory where files must be installed + +Several `DESTDIR`-style variables are pre-exported: `DESTDIR`, `DEST_DIR`, `INSTALLROOT`, `install_root`, `INSTALL_ROOT`. + +```sh +build() { + cd "$SRC/$name-$version" + ./configure --prefix=/usr --sysconfdir=/etc + make + make DESTDIR="$PKG" install +} +``` + +`build()` runs with `set -ex`, so the script exits on any error and prints each command. + +### Pre/post build hooks + +Without a `build()` function, you can use `prebuild()` and `postbuild()`: + +```sh +prebuild() { + sed -i 's/broken/fixed/g' src/whatever.c +} + +postbuild() { + mv "$PKG/usr/bin/wrongname" "$PKG/usr/bin/rightname" +} +``` + +The execution order is: `prebuild()` → auto-detected build system → `postbuild()`. + +## Build system auto-detection + +When no `build()` is defined and no `build_type` is set, apkg checks for these files in order: + +1. `meson.build`: meson with LTO, PIE, `wrap_mode=nodownload`, `buildtype=plain` +2. `configure`: autotools `./configure --prefix=/usr --sysconfdir=/etc ...` +3. `CMakeLists.txt`: cmake with `Release` build type, prefers ninja +4. `setup.py`: `python3 setup.py build && install --root=$PKG` +5. `Makefile.PL`: `perl Makefile.PL && make && make install` +6. `Makefile` / `makefile` / `GNUmakefile`: raw make with standard variables + +The exact flags for each build system are documented in `doc/defaultbuildopts`. + +## Post-build processing + +After compilation, apkg automatically: + +- Compresses man pages (man1–man8 only, gzip) and info pages +- Removes common conflict files: `fonts.dir`, `fonts.scale`, `perllocal.pod`, `charset.alias` +- Removes static libraries (`*.a`), libtool archives (`*.la`), locales, and docs unless the corresponding `keep_*` variable is set +- Strips ELF binaries (`--strip-all`), shared objects (`--strip-unneeded`), and static archives (`--strip-debug`) unless `no_strip` is set +- Installs runit service files from the `sv` variable + +## The info file + +`apkg-genabuild` creates an `info` file alongside the `abuild` with package metadata: + +``` +description: +homepage: +license: +maintainer: name <name at mail dot com> +``` + +Fill in each field as appropriate. The `maintainer` line uses the format `name <email>`. + +## The depends file + +One dependency per line. Lines starting with `#` are comments. Dependencies are just package names: no version constraints. + +``` +# Direct dependencies of mypkg +zlib +libpng +freetype +``` + +Dependencies are recursive: when installing with `-I`, apkg will resolve the full tree. Only list direct dependencies; transitive ones are handled automatically. Use `apkg-redundantdeps` to find and clean up transitive entries. + +## preinstall / postinstall scripts + +These are optional executable scripts in the recipe directory: + +- **`preinstall`**: runs before the package is built (only during `apkg -i` or `apkg -u`). Good for pre-flight checks or preparing the system. +- **`postinstall`**: runs after the package is installed or upgraded. Good for one-time setup that can't be done at build time. + +If `APKG_ROOT` is set (alternative install root), these scripts run inside a chroot. + +## Checksums and file lists + +- **`.shasum`**: sha3sum of each source file, auto-generated on first build. Regenerate with `apkg -g <pkg>`. +- **`.files`**: sorted list of every file in the built `.spm`, auto-generated after packaging. Regenerate with `apkg -k <pkg>`. Used by `apkg -S` for file search. + +## Complete example + +```sh +name=hello +version=2.12.1 +release=1 +source="https://ftp.gnu.org/gnu/hello/$name-$version.tar.gz" + +build() { + cd "$SRC/$name-$version" + ./configure --prefix=/usr + make + make DESTDIR="$PKG" install +} +``` + +With a `depends` file: + +``` +zlib +``` + +With a `postinstall` script: + +```sh +#!/bin/sh +echo "hello was installed!" +``` + +## Tips + +- Use `apkg-genabuild <url>` to scaffold a recipe from a source URL quickly. +- Use `$name` and `$version` in source URLs so bumping the version only requires changing two variables. +- Patches (`.patch` / `.diff` files) listed in `source` are applied automatically with `patch -p1` before the build. Use `patch_opt` to change the strip level. +- Set `APKG_KEEP_WORKDIR=1` in your environment to inspect the build tree when debugging a failed build. |