Linux Package Management & Software Building — apt/dpkg, dnf/rpm, pacman, from-source & kernel build

Linux Package Management & Software Building

Overview

A Linux package is an archive of files plus metadata (name, version, dependencies, scripts, signature). A package manager resolves dependencies, fetches packages from repositories, verifies their signatures, and applies the change as a transaction recorded in a local database. There are two layers in every native stack:

Use the high-level tool for normal work; drop to the low-level tool only to install a downloaded file or to inspect/repair the database. The three native ecosystems map cleanly onto each other, so once you know the model you mostly translate verbs. Above the native layer sit the universal formats (Flatpak, Snap, Nix) which bundle dependencies and are cross-distro.

Core Concepts (the shared branch)

These ideas are identical across apt, dnf, and pacman — learn them once.

Tooling — per-manager command maps

apt / dpkg (Debian, Ubuntu, Mint, Pop!_OS)

Task Command
Refresh index sudo apt update
Install / upgrade one sudo apt install <pkg>
Full system upgrade sudo apt upgrade (no removals) / sudo apt full-upgrade (allows removals)
Remove (keep config) / purge sudo apt remove <pkg> / sudo apt purge <pkg>
Remove orphans sudo apt autoremove
Search / show apt search <re> / apt show <pkg>
Install a local .deb (+deps) sudo apt install ./pkg.deb
Low-level install / remove sudo dpkg -i pkg.deb / sudo dpkg -r <pkg>
What package owns a file dpkg -S /path
Files in an installed pkg dpkg -L <pkg>
Reconfigure a package sudo dpkg-reconfigure <pkg>
Hold / unhold a version sudo apt-mark hold <pkg> / unhold

dnf / rpm (Fedora, RHEL, Rocky, Alma, openSUSE uses zypper)

Task Command
Refresh / clean cache sudo dnf makecache / sudo dnf clean all
Install / upgrade sudo dnf install <pkg> / sudo dnf upgrade
Remove / autoremove sudo dnf remove <pkg> / sudo dnf autoremove
Search / info dnf search <re> / dnf info <pkg>
What provides a file dnf provides /path
Groups dnf group list / dnf group install "<group>"
Install a local .rpm (+deps) sudo dnf install ./pkg.rpm
Low-level query / verify rpm -qa, rpm -qf /path, rpm -ql <pkg>, rpm -V <pkg>
Add a repo drop a *.repo in /etc/yum.repos.d/ or dnf config-manager --add-repo
Transaction history dnf history, dnf history info <id>
Undo one transaction sudo dnf history undo <id>
Rollback to a point sudo dnf history rollback <id> (reverts everything after it)
Version lock dnf versionlock add <pkg> (plugin)

pacman (Arch, Manjaro, EndeavourOS)

Task Command
Sync DB + upgrade everything sudo pacman -Syu (the canonical update)
Install sudo pacman -S <pkg>
Remove (+unneeded deps) sudo pacman -Rns <pkg>
Search remote / installed pacman -Ss <re> / pacman -Qs <re>
Info remote / installed pacman -Si <pkg> / pacman -Qi <pkg>
What owns a file / list files pacman -Qo /path / pacman -Ql <pkg>
Install a local pkg file sudo pacman -U pkg.tar.zst
List explicitly-installed pacman -Qe
List orphans / remove them pacman -Qtdq / sudo pacman -Rns $(pacman -Qtdq)
Clean package cache sudo pacman -Sc (or paccache -r)

Universal formats (cross-distro, dependency-bundled)

Building from source

When no package exists, the version is too old, or you need custom build flags.

The three build systems you’ll meet

Source-build hygiene (the patterns that keep it maintainable)

  1. Get the deps first. sudo apt build-dep <pkg> / sudo dnf builddep <spec> / pull makedepends via the PKGBUILD. Read the project README/INSTALL — honor its recommendation over generic advice.
  2. Verify the tarball. Download from a trusted origin; check the GPG signature or checksum before extracting. Supply-chain risk lives here.
  3. Never build or run make as root. Build as your user; only make install (the copy step) needs privilege.
  4. Isolate the prefix for easy removal. Default /usr/local collides nothing with the package manager (which owns /usr), but an explicit versioned prefix like /opt/foo-1.2.3 or --prefix=$HOME/.local is cleaner and trivially removable. There is usually no make uninstall, so isolation matters.
  5. Make it removable / trackable. Prefer one of:
    • checkinstall — wraps make install to produce a real .deb/.rpm/.tgz so the package manager tracks and can cleanly remove it.
    • GNU Stowmake install into /usr/local/stow/foo-1.2.3, then stow symlinks it into /usr/local; stow -D removes it atomically.
    • Building a proper native package (.deb via debuild, .rpm via rpmbuild/.spec, .pkg.tar.zst via PKGBUILD) for anything you’ll ship.
  6. Run ldconfig after installing shared libraries to a new path; add the dir to /etc/ld.so.conf.d/ if outside the default search path.

Kernel build basics

Compiling a custom kernel from kernel.org source (or your distro’s source) — for new hardware, debugging, custom config, or learning.

  1. Get source + deps. Extract the tarball; install build deps (build-essential/gcc make, bison flex libssl-dev libelf-dev bc, ncurses for menuconfig).
  2. Configure — produce a .config:
    • make menuconfig — ncurses menu editor (also nconfig, xconfig, gconfig).
    • make localmodconfig — the practical shortcut: reads lsmod and disables every module not currently loaded, producing a lean, fast-building config tailored to this machine. (Pass a captured lsmod via LSMOD=file to target another machine.)
    • make olddefconfig — carry an existing .config forward, defaulting new symbols.
    • Common base: cp /boot/config-$(uname -r) .config then make olddefconfig.
  3. Build. make -j$(nproc) — uses all cores; still typically 1–2+ hours for a full config, minutes for a localmodconfig-trimmed one. Produces arch/x86/boot/bzImage (the compressed kernel image) and the built modules.
  4. Install modules. sudo make modules_install → copies into /lib/modules/<version>/.
  5. Install kernel. sudo make install (distro-friendly: copies bzImage to /boot, generates the initramfs, and updates the bootloader on most distros) — or manually copy bzImage to /boot/vmlinuz-<ver>, build the initramfs (dracut/update-initramfs), and regenerate GRUB (grub-mkconfig -o /boot/grub/grub.cfg or grub2-mkconfig). See linux-boot-init for the initramfs + bootloader chain and linux-kernel-architecture for module/ABI internals.
  6. Reboot and pick the entry; verify with uname -r. Keep the old kernel as a fallback boot entry — never delete the working kernel until the new one boots clean.

Anti-patterns

Troubleshooting

Symptom Likely cause / fix
apt: NO_PUBKEY <id> / not signed Missing/expired repo key. Fetch the key into /usr/share/keyrings/ and bind with Signed-By:. Don’t use apt-key.
apt: dpkg was interrupted Finish the interrupted state: sudo dpkg --configure -a, then sudo apt -f install.
apt: unmet dependencies / held broken packages sudo apt -f install (fix), sudo apt full-upgrade; inspect with apt policy <pkg>. A held package: apt-mark showhold.
apt: package “kept back” apt upgrade won’t add/remove; use sudo apt full-upgrade (or install the held one explicitly).
dnf: Curl error / Failed to download metadata Stale/broken mirror. sudo dnf clean all && sudo dnf makecache; check /etc/yum.repos.d/.
dnf: package X is already installed on rollback dnf5 history edge case — verify with dnf history info; target the correct transaction id; some undo/redo ops differ from dnf4.
rpm: rpmdb open failed / DB corruption sudo rpm --rebuilddb (older) or rpmdb --rebuilddb; remove stale __db.* locks in the rpm dir.
pacman: invalid or corrupted package (PGP signature) Stale keyring. sudo pacman -Sy archlinux-keyring then pacman -Syu; or sudo pacman-key --refresh-keys.
pacman: failed to commit transaction (conflicting files) A file already on disk not owned by the new pkg. Resolve the conflict; only as a last resort --overwrite <glob>.
pacman: broken system after -Sy <pkg> Partial upgrade. Recover with a full sudo pacman -Syu to bring everything consistent.
source build: configure: error: <lib> not found Missing -dev/-devel headers. apt build-dep / dnf builddep, or install the *-dev/*-devel package.
source build: error while loading shared libraries New lib not in loader path. sudo ldconfig, or add the dir under /etc/ld.so.conf.d/.
kernel: won’t boot / panic Boot the old entry (kept as fallback), check missing built-in (e.g. filesystem/root driver compiled as module not in initramfs). Rebuild initramfs; see linux-boot-init.
kernel: module won’t load (invalid module format) Vermagic/ABI mismatch vs running kernel. Rebuild against the matching headers; see linux-kernel-architecture.

References