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 mountBuild with Docker
Section titled “Build with Docker”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.
# Update package listssudo apt-get update
# Install essential packagessudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
# Install the correct QEMU packages for cross-architecture buildssudo apt-get install -y qemu-user-static binfmt-support
# Register the QEMU binary formatssudo docker run --privileged --rm tonistiigi/binfmt --install all
# Install the latest buildx pluginBUILDX_VERSION=$(curl -s https://api.github.com/repos/docker/buildx/releases/latest | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')mkdir -p ~/.docker/cli-pluginscurl -L "https://github.com/docker/buildx/releases/download/v${BUILDX_VERSION}/buildx-v${BUILDX_VERSION}.linux-amd64" -o ~/.docker/cli-plugins/docker-buildxchmod +x ~/.docker/cli-plugins/docker-buildx
# Create a new builder instance with proper support for multiple platformsdocker buildx create --name multiarch-builder --driver docker-container --usedocker buildx inspect --bootstrapTo verify everything is working correctly:
# Check if aarch64 is available as a platformdocker buildx inspect --bootstrap
# Test with a simple cross-platform builddocker buildx build --platform linux/arm64 --load -t test-arm64 -<<EOFFROM alpineRUN uname -aEOFTo start the Docker container, you just have to use the following command:
docker compose run --rm builder bashThis 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.
Makefile
Section titled “Makefile”We have a Makefile that has all the commands preconfigured that will help you build this project.
make build
Section titled “make build”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.
make release
Section titled “make release”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.
make clean
Section titled “make clean”This will clean the build directory and remove all the binaries.
make image
Section titled “make image”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.