Building packages locally

How to build packages on MocaccinoOS with portage (or not)

MocaccinoOS desktop, even if based on portage, doesn’t support the direct usage of emerge. Although it’s possible to compile and install packages from portage.

To build a system package, instead use luet build. The following document tries to summarize the steps to build a package with emerge with luet build, and install and track it in a MocaccinoOS Desktop system, should cover the scenario: “hey, can I install packages with emerge?".

Requirements

  • Be sure to have docker installed, and the daemon running. The document is assuming you are carrying the steps on MocaccinoOS Desktop (GNOME in the specific case).
  • At least 30G of free disk space. To reclaim the space afterwards, run docker system prune --force --volumes --all

Follow the steps described in this document before going ahead.

Create a workspace

First of all, let’s create a workspace. The packages that we will build have to persist somewhere in your local system, the location must be accessible while performing a luet upgrade. We will use /user/system_repository as an example. And we will assume the commands are running as root.

1
2
$ mkdir -p /user/system_repository/tree
$ cd /user/system_repository

All the commands from now on will be carried from the /user/system_repository directory.

First package

Let’s put our eyes on, let’s say, games-board/gnome-chess, and create a compilation definition for it.

Let’s first declare it’s canonical name, or how you would actually install it afterwards with luet (e.g. luet install app/gnome-chess)

1
2
3
4
5
6
$ mkdir tree/gnome-chess
$ cat <<EOF >>tree/gnome-chess/definition.yaml
category: "apps"
name: "gnome-chess"
version: "0.1"
EOF

Here the version doesn’t really matter, it’s mostly for you to keep it track in your system. You can decide to follow strictly the versioning from gnome-chess, or not.

Now let’s get to the important part, the build definition. This tells luet how to compile your package:

1
2
3
4
5
6
7
8
9
$ cat <<EOF >>tree/gnome-chess/build.yaml
package_dir: "/package"
steps:
- emerge --root /package games-board/gnome-chess
requires:
- category: "layers"
  name: "gnome"
  version: ">=0"
EOF

as you see, we are using emerge here to compile the package. The requires section tells from where it runs the command, which in this case is the MocaccinoOS desktop gnome layer. To see all the layers available, run luet search layers or to see the currently installed, you can run luet search --installed layers).

Now let’s add an installation hook to our package, in our specific case (gnome-chess) we need a trigger to generate glib schemas right after the package gets installed in the system:

1
2
3
4
$ cat <<EOF >>tree/gnome-chess/finalize.yaml
install:
- glib-compile-schemas /usr/share/glib-2.0/schemas
EOF

Building the package

Now let’s build the packages (remember to run as root, or with sudo upfront):

1
$ luet build --tree tree --pull --pull-repository quay.io/mocaccinocache/desktop --from-repositories --live-output --only-target-package apps/gnome-chess

After build is completed, generate the repository metadata:

1
$ luet create-repo --tree tree

Install the package

First let’s consume the repository we just created in our system:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ cat <<EOF >> /etc/luet/repos.conf.d/local.yaml
name: "local-repository"
description: "Local repository"
type: "disk"
enable: true
cached: true
priority: 99
urls: # Repository URLs
  - /user/system_repository/build
EOF

Now we are ready to install gnome-chess locally:

1
$ luet install apps/gnome-chess

Advanced topics

Showing package files

Luet shows already all the files shipped by a package with luet search. For example:

1
$ luet search apps/gnome-chess -o yaml

Find duplicate files shipped by packages

You can check duplicate files into the package shipped by repositories, also before installing them:

1
luet search -o json | luet filter

This is particularly useful to check for any conflicting files with the system packages and the ones you are generating.

See also the dev section regarding duplicate files.

Removing generated docker images

By default, images are tagged under luet/cache. So it’s possible to remove all the cache images generated by removing the luet/cache and quay.io/mocaccinocache/desktop images, although, you should also prune afterwards the images not referenced anymore by any tag with docker image prune:

1
2
3
$ docker images --filter='reference=luet/cache' --format='{{.Repository}}:{{.Tag}}' | xargs -r docker rmi
$ docker images --filter='reference=quay.io/mocaccinocache/desktop' --format='{{.Repository}}:{{.Tag}}' | xargs -r docker rmi
$ docker image prune

A way to reclaim all the space occupied by docker more aggressively is by running docker system prune, but attention, this command will remove all the images, also the ones which weren’t generated by luet:

1
$ docker system prune --force --volumes --all

References

Last modified May 30, 2021: Add default user/pass (a5f1230)