Continuing with my goal of trying to ship the Qt variant of OpoLua—our modern OPL interpreter—for macOS, Windows, and Linux, I spent much of the day diving into the ugly world of Linux packaging. To make things a little more palatable, I also treated myself to a small update to Reconnect, my Psion connectivity suite for macOS.

OpoLua

My primary focus for the day was to set up Linux smoke-test builds to ensure that we don’t unintentionally break builds on the platform. Having already figured out how to build on Ubuntu, setting up automated builds proved easy—a matter of adding a GitHub Actions job to the workflow, and crafting a lightweight build script. I continue to be impressed by Qt’s tooling, which reduces builds on almost all platforms to:

qmake6
make

Spurred on by a quick win, and lulled into a false sense of security, I decided to try tackling packaging for Ubuntu. When I’ve built Debian packages in the past using the standard tooling, I’ve been frustrated by the need for distro-specific directory structures so, to avoid polluting our source tree, I decided to look for an alternative. This took me to fpm or ‘Effing Package Management’, a multi-distro packaging tool which proved incredibly powerful, allowing me to generate a .deb from the directory output of Qt’s make install using a single command:

ARCHITECTURE=`dpkg --print-architecture`
fpm \
    -s dir \
    -t deb \
    -p "opolua-ubuntu-24.04-$ARCHITECTURE-$VERSION_NUMBER-$BUILD_NUMBER.deb" \
    --name "opolua" \
    --version $VERSION_NUMBER \
    --architecture "$ARCHITECTURE" \
    --description "Runtime and viewer for EPOC programs and files." \
    --url "https://opolua.org" \
    --maintainer "Jason Morley <[email protected]>" \
    --depends libqt6core6 \
    --depends libqt6gui6 \
    --depends libqt6widgets6 \
    --depends libqt6multimedia6 \
    --depends libqt6core5compat6 \
    --chdir "$INSTALL_DIRECTORY" \
    .

(You’ll notice I’m getting the architecture with dpkg --print-architecture—using ARM and Intel runners with GitHub Actions matrix builds, the build script can output releases for both architectures.)

I shared the builds with a few members of the Psion Discord, and Colin kindly sent me a couple of screenshots of OpoLua running on Kubuntu—it’s a real reward to see others using our creation.

Jumpy! is a wonderful showcase for OPL

While there are still many different Linux distributions and versions to add to the build script (and I’d like to set up an apt repository to ensure folks can get automatic updates), I’m pretty pleased with this progress.

… But I couldn’t leave it there. I decided to try tackling Arch Linux—a distro I’ve little experience of. Starting this at 10pm was perhaps a poor choice. fpm did its job well, and I able to change a couple of flags and output a pacman binary package, but Alex quickly dissuaded me of the notion that this was good enough: binary packages are (understandably) frowned upon in Archland and PKGBUILD source builds (distributed via AUR) are preferable as they increase transparency.

PKGBUILD configuration files seem mostly well designed and, with Alex’s help, I was able to craft something that worked. The big challenge was how Git submodules are (or aren’t) handled: while there’s good support for Git, there’s absolutely no support for submodules—you have to manually recreate these in your prepare. For a project like OpoLua that relies heavily on recursive submodules, this is a miserable experience. makepkg (which processes PKGBUILD files) will check out each submodule at the top-level, and you have to rewrite all the submodule urls from the bottom up:

prepare() {

    cd "$srcdir/opolua"
    git submodule init
    git config submodule.LuaSwift.url "$srcdir/LuaSwift"
    git config submodule.diligence.url "$srcdir/diligence"
    git config submodule.scripts/changes.url "$srcdir/changes"
    git config submodule.scripts/build-tools.url "$srcdir/build-tools"
    git -c protocol.file.allow=always submodule update --recursive

    cd "$srcdir/opolua/dependencies/LuaSwift"
    git submodule init
    git config submodule.Sources/CLua/lua.url "$srcdir/lua"
    git -c protocol.file.allow=always submodule update

}

I’ve yet to work out how to synthesize per-release versions of the PKGBUILD file, or how to get those into AUR, but it’s good to have broken the back of this.

Reconnect Menu

While Apple’s Liquid Glass is incredibly divisive and widely derided (I personally dislike it), I’m keen for my apps to feel at home on the system—I don’t want to add to users' cognitive burden by rejecting platform choices. With that in mind, I’ve been slowly adopting the new menu icons, and I took a little time to add them to the Reconnect menu bar menu:

It’s not clear to me that this is an improvement—there’s a recent piece over at tonsky.me that captures many of the issues—but it’s where things are going. Perhaps I’ll use this investigation by Brent Simmons to give users a choice.