Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cosmic-debian-testing

Build the COSMIC desktop environment as .deb packages on Debian testing, and install them locally.

Everything is built inside an OCI container (podman or docker), so the build host only needs git and a container engine; the produced .deb files are extracted to the project directory and installed with apt.

Licensed under the MIT license.

Requirements

Host:

  • Debian testing (the install scripts use apt/dpkg)
  • git
  • podman or docker (podman is preferred if both are present; override with e.g. CONTAINER_ENGINE=docker)

Privileges:

  • build.sh and clear.sh run as a regular user
  • install.sh and uninstall.sh require root (run via sudo)

Build and install from zero

sudo apt-get update && sudo apt-get install -y git podman   # or: docker.io
git clone https://github.com/nimenko/cosmic-debian-testing.git
cd cosmic-debian-testing
./build.sh                  # clones/updates sources, builds all .deb packages
sudo ./install.sh           # installs them
sudo systemctl restart gdm  # or sddm/lightdm, or reboot

Log out and choose the COSMIC session at the greeter.

install.sh needs the .deb files from a successful build, so run it after build.sh and before clear.sh. It also holds the installed packages with apt-mark, so apt upgrade will not replace them with other versions (their dependencies are not held). Uninstalling, or reinstalling, clears the holds.

build.sh builds the current upstream master of every source repository. Nothing is pinned (see Caveats). A rebuild reuses the engine's layer and cargo caches.

Uninstall and clear everything

sudo ./uninstall.sh   # unhold + purge, then apt-get autoremove --purge
./clear.sh            # .deb files, cloned sources, generated Containerfile

Run uninstall first. It purges the packages listed in .installed_packages, or the .deb files if that log is gone. clear.sh deletes those .deb files.

Both scripts leave container data behind, and that is the bulky part:

podman rmi cosmic-epoch cosmic-deps && podman image prune -f --build-cache
docker rmi cosmic-epoch cosmic-deps && docker builder prune -f

The prune commands affect all local images and build cache, not just this project. --build-cache needs podman 5. Look before you prune with podman system df.

Per-user state also survives a purge. To remove it, delete ~/.config/cosmic*, ~/.cache/cosmic*, ~/.local/state/cosmic* and the matching pop-launcher paths. Check the result with dpkg-query -W 'cosmic-*' 'pop-launcher*' and apt-mark showhold.

How it works

The build is a two-stage OCI build ("Containerfile") per component group, ending in a FROM scratch stage that contains only the .deb files, which are extracted with --output type=local. Package sources are cloned into the build context with git (depth 1) on every build.

cosmic/Containerfile is generated by cosmic/gen-containerfile.sh on every build and must not be edited by hand. The generator:

  • takes the module list from cosmic-epoch/.gitmodules, keeping every module that has Debian packaging (so new upstream modules are picked up automatically; modules without packaging, e.g. cosmic-sound-theme, are skipped with a notice, as is simple-wrapper, which upstream's own build does not install either),
  • derives the build order from the Build-Depends fields of the modules' debian/control files: if one module build-depends on a package that another module in the set provides (currently only cosmic-osd on cosmic-randr), the providing module is built first and its freshly built .deb is installed into the build container right after its build,
  • emits one COPY + RUN block per module so each package keeps its own layer and the build cache stays fine-grained.

Rust modules are built without vendoring: the container sets VENDOR=0 and CLEAN=0, an empty vendor.tar is created to satisfy the upstream packaging's tar pxf vendor.tar step, and cargo fetch fills a persistent cache mount so the --offline build works. A small /usr/local/bin/ischroot shim (always "yes, this is a chroot") is installed because some modules' rules use the old-style ischroot || (clean && vendor) guard, which buildah containers misdetect otherwise — their clean step would then try to delete the shared, cache-mounted target directory and fail. Modules that generate desktop files via a just xdgen recipe instead of a build script get that recipe run explicitly, since upstream only runs it as a side effect of the skipped vendoring step. Cargo's registry, git and target directory caches are BuildKit cache mounts, shared across all modules, so a rebuild only recompiles what changed.

Install/uninstall keep a log (.installed_packages) of what was installed. On uninstall it falls back to the .deb files still present in the directory, and only as a last resort to a dpkg query (which could, in principle, also match future distro-provided packages with those names).

Caveats

  • Nothing is pinned: sources are always upstream master, and the build base image is the current debian:testing. Two builds at different times produce different package sets. Debian testing also moves, so a later sudo apt upgrade can pull in incompatible library versions (the packages themselves are held, their dependencies are not).
  • The built binaries report a fake git SHA and commit date (the source .git directories are excluded from the build context).
  • The Containerfiles build unsigned packages (-uc -us) and run without build-dep verification (-d); this is a local build tool, not a distribution pipeline.

License

MIT © 2026 Maksym Nimenko

About

Build COSMIC desktop environment as .deb packages for Debian testing, using containerized builds

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages