# autils Alice Linux Utilities: a collection of POSIX shell scripts for source-based package management on [Alice Linux](https://codeberg.org/emmett1/alicelinux). ## Overview **apkg** is the core package manager. It reads an `abuild` recipe (a POSIX shell snippet defining the package name, version, sources, and optional build hooks), downloads and verifies source tarballs, auto-detects one of 6 supported build systems, compiles the software, post-processes the result (strip binaries, compress man pages, install runit services), packages it into the `.spm` format, and installs or upgrades the package via the **spm**(8) backend. A set of `apkg-*` helper scripts handle binary package management, dependency analysis, repo syncing, orphan detection, cleanup, and more. Standalone utilities cover reverse-dependency checking (`revdep`), configuration file merging (`updateconf`), and environment-driven git repository synchronization (`reposync`). ## Installation ```sh make install ``` Installs all scripts into `/usr/bin` and man pages into `/usr/share/man/man8`. Override with `DESTDIR`, `PREFIX`, `BINDIR`, or `MANDIR`. Individual scripts are self-contained and can be run directly from the source tree for testing. ## Quick start ```sh # Build and install a package (from inside its recipe directory) cd /path/to/repo/mypkg apkg -i # Install with automatic dependency resolution apkg -I firefox # Search available packages apkg -s icon # List outdated packages on the system apkg -l # Full system upgrade apkg -U # Remove a package and its unneeded dependencies apkg-purge -p mypkg # Find broken library links after an upgrade revdep # Merge .new config files after an upgrade updateconf ``` ## Tools ### Core | Tool | Description | |---|---| | `apkg` | Build packages from source, resolve dependencies, install/upgrade/remove, search repos, system upgrade | | `spm` | Low-level `.spm` package installer (external, not in this repo) | ### Helpers | Script | Purpose | |---|---| | `apkg-chroot` | Enter a chroot with `/dev`, `/proc`, `/sys`, `/run` bind-mounted | | `apkg-clean` | List stale `.spm` files and orphaned source tarballs (pipe to `xargs rm`) | | `apkg-deps` | Show runtime library dependencies of an installed package via `ldd` | | `apkg-foreign` | List installed packages not found in any configured repo | | `apkg-genabuild` | Scaffold an `abuild` recipe file from a source URL | | `apkg-orphan` | List installed packages that have no dependents installed | | `apkg-purge` | Remove a package and its dependencies that are no longer needed by others (`-p` to actually remove) | | `apkg-redundantdeps` | Detect transitive dependencies explicitly listed in `depends` files (`-f` to fix) | ### Standalone utilities | Tool | Description | |---|---| | `revdep` | Scan system binaries and libraries for missing library links (run after major upgrades) | | `updateconf` | Interactive `.new` config file merge tool: diff, keep, discard, or edit | | `reposync` | Git repo sync driven by `REPOSYNC_*` environment variables (no `/etc/apkg.conf` dependency) | ## The abuild recipe An `abuild` file is a POSIX shell snippet sourced by apkg. The directory containing it must have the same name as the `name` variable. A minimal recipe: ```sh name=mypkg version=1.2.3 release=1 source="https://example.com/$name-$version.tar.gz" ``` ### Source formats The `source` variable accepts five formats: | Format | Description | |---|---| | `https://example.com/pkg-1.0.tar.gz` | A remote URL | | `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 | | (empty) | Create a dummy/meta package with only `/usr` | ### Optional recipe variables | Variable | Purpose | |---|---| | `build_opt` | Extra flags appended to the auto-detected build system | | `build_type` | Force a specific build system (`meson_build`, `configure_build`, `cmake_build`, `python_build`, `perlmodule_build`, `makefile_build`) | | `build_dir` | Subdirectory within the extracted source to enter before building | | `sv` | Runit service files to install into `/etc/sv` | | `skip_patch` | Skip automatic `.patch` / `.diff` application | | `patch_opt` | Options for `patch` (default: `-p1`) | | `keep_static` | Keep `*.a` static libraries | | `keep_libtool` | Keep `*.la` libtool archives | | `keep_locale` | Keep locale files | | `keep_doc` | Keep documentation | | `no_strip` | Skip ELF binary stripping | ### Build hooks If a `build()` function is defined, it replaces the auto-detected build system entirely. Use `$SRC` (source extraction directory) and `$PKG` (fakeroot staging directory) to compile and install files. Several `DESTDIR`-style variables are pre-exported: `DESTDIR`, `DEST_DIR`, `INSTALLROOT`, `install_root`, `INSTALL_ROOT`. ```sh build() { ./configure --prefix=/usr make make DESTDIR=$PKG install } ``` Without `build()`, optional `prebuild()` and `postbuild()` hooks run before and after the auto-detected build system. ### Other recipe files | File | Purpose | |---|---| | `depends` | Dependencies, one per line (`#` for comments) | | `preinstall` | Script run before the package is built (only during `-i` or `-u`) | | `postinstall` | Script run after the package is installed or upgraded | | `.shasum` | Source checksums (auto-generated, regenerate with `apkg -g`) | | `.files` | Package file list (auto-generated, regenerate with `apkg -k`) | ## Build systems When no `build()` function is defined, apkg auto-detects the build system by checking for these files in order: 1. **meson.build**: `meson setup` with LTO, PIE, `wrap_mode=nodownload`, `buildtype=plain` 2. **configure**: `./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 prefix variables See `doc/defaultbuildopts` for the exact flags used by each build system. ### Post-build processing After compilation, apkg automatically: - Compresses man pages (man1-man8, 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 kept via `keep_*`) - Strips ELF binaries (`--strip-all`), shared objects (`--strip-unneeded`), and static archives (`--strip-debug`) ## Triggers After install or upgrade, apkg can automatically refresh system caches when the package provides relevant files: - **fontconfig**: `fc-cache -sf` - **GDK-Pixbuf**: `gdk-pixbuf-query-loaders --update-cache` - **GIO modules**: `gio-querymodules /usr/lib/gio/modules` - **GSettings schemas**: `glib-compile-schemas /usr/share/glib-2.0/schemas` - **GTK2/GTK3 input methods**: `gtk-query-immodules-2.0/3.0 --update-cache` - **Icon themes**: `gtk-update-icon-cache` - **udev hardware database**: `udevadm hwdb --update` - **X font indices**: `mkfontdir` / `mkfontscale` - **Desktop MIME cache**: `update-desktop-database` - **Shared MIME database**: `update-mime-database /usr/share/mime` Run `apkg -t` to trigger these manually for all installed packages. ## Environment variables ### apkg | Variable | Default | Purpose | |---|---|---| | `APKG_REPO` | `$PWD` | Space-separated repo directories (first match wins) | | `APKG_PACKAGE_DIR` | `$PWD` | Where built `.spm` files are stored | | `APKG_SOURCE_DIR` | `$PWD` | Source tarball cache directory | | `APKG_WORK_DIR` | `$PWD` | Build working tree (extraction + fakeroot) | | `APKG_ROOT` | `/` | Alternative install root | | `APKG_NOPROMPT` | (unset) | Skip confirmation prompt (for scripting) | | `APKG_KEEP_WORKDIR` | (unset) | Keep build tree on failure (for debugging) | | `APKG_ALIAS` | (unset) | Dependency substitution: `real:alias` pairs | | `APKG_MASK` | (unset) | Packages to skip during `-l` and `-U` | | `APKG_LOG` | (unset) | Enable build logging | | `APKG_LOG_DIR` | (unset) | Log file directory (filename: `$name.log`) | ### reposync | Variable | Format | Purpose | |---|---|---| | `REPOSYNC_` | `url\|branch\|path` | Define a git repo to sync | ## Bugs Issue tracker: [codeberg.org/emmett1/autils/issues](https://codeberg.org/emmett1/autils/issues) ## License See [LICENSE](./LICENSE).