Skip to content

How to build

Our Printer binary is heavily dependent on the CUPS library. CUPS is written in C and provides libcups which allows us to communicate with CUPS using C functions.

libcups is a precompiled library that can be installed from a Linux package manager like apt or pacman. Even though Zig can cross-compile to any platform, because we have a dependency that is already compiled for the current machine architecture, we can’t recompile it for another architecture with Zig.

To solve this problem, we have a Docker container that runs aarch64 Ubuntu and has the dependencies including the Zig compiler.

If you want to build and run the binaries on your main computer, make sure to install the following dependencies:

sudo apt install libcups2 libcups2-dev libpoppler-glib-dev kpartx util-linux mount

A Docker container is essentially just these dependencies in a container.

You need to make sure that you have the following dependencies:

  • docker
  • docker buildx plugin
  • docker compose
  • qemu-user-static
  • binfmt-support

If you haven’t installed any of them yet, you can use the following guide. It assumes that you have the Docker container and now want to install the buildx plugin and rest of the dependencies.

Terminal window
# Update package lists
sudo apt-get update
# Install essential packages
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
# Install the correct QEMU packages for cross-architecture builds
sudo apt-get install -y qemu-user-static binfmt-support
# Register the QEMU binary formats
sudo docker run --privileged --rm tonistiigi/binfmt --install all
# Install the latest buildx plugin
BUILDX_VERSION=$(curl -s https://api.github.com/repos/docker/buildx/releases/latest | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
mkdir -p ~/.docker/cli-plugins
curl -L "https://github.com/docker/buildx/releases/download/v${BUILDX_VERSION}/buildx-v${BUILDX_VERSION}.linux-amd64" -o ~/.docker/cli-plugins/docker-buildx
chmod +x ~/.docker/cli-plugins/docker-buildx
# Create a new builder instance with proper support for multiple platforms
docker buildx create --name multiarch-builder --driver docker-container --use
docker buildx inspect --bootstrap

To verify everything is working correctly:

Terminal window
# Check if aarch64 is available as a platform
docker buildx inspect --bootstrap
# Test with a simple cross-platform build
docker buildx build --platform linux/arm64 --load -t test-arm64 -<<EOF
FROM alpine
RUN uname -a
EOF

To start the Docker container, you just have to use the following command:

Terminal window
docker compose run --rm builder bash

This will build the image and open bash in the container. In the container you will see the rpi-printer-service directory. Change directory to it and you will see all the code of repository.

We have a Makefile that has all the commands preconfigured that will help you build this project.

This should be used for development builds. The binaries you want to run on your main computer to quickly test the code. It uses Zig’s DebugAllocator which will show you memory leaks and other issues at runtime. This is helpful if you run every aspect of the program with this build to ensure your program is not leaking memory.

This is meant to be used for production builds. It uses ReleaseFast mode and uses Zig’s SmpAllocator which will make the program faster and use less memory.

This will build the binaries for the architecture it’s building on. If you run this in the Docker container it will emit aarch64 binaries and if you run this on your main computer then it will emit x86_64 binaries or whatever you have on your machine.

This will clean the build directory and remove all the binaries.

This will just patch the image with latest configuration and binaries and create a new image. You can find more info in the how to build image section.