Recently I’ve been working on libshumate, the new maps library for GTK 4–you may have seen the recent This Week in GNOME post which mentioned my work on rotating the map using touchscreen gestures. I used my PinePhone to test the feature, so I needed a way to quickly build libshumate and run it on the phone.
Sure, the phone has those cool convergence features, and I could have hooked up a monitor and keyboard and run Builder on the phone itself. Which is awesome, but personally I wanted a more traditional mobile development setup. So, while I worked on the libshumate MR, I was also finishing and testing GNOME Builder’s support for running apps on mobile devices.
I definitely didn’t start from scratch here. In fact, most of the work was already done and implemented in Builder and in Christian Hergert’s deviced project. When I got involved, Builder could already detect devices running deviced and build and deploy Flatpak bundles to them. My work focused on connecting the Run button so everything can be automatic.
How It Works
Mobile device support is all thanks to Flatpak. Flatpak provides cross-compiling support and a format to bundle an app and copy it to the device. The sandboxed platform ensures an app built on one OS will run on a completely different OS. I use Fedora on my desktop and postmarketOS on the phone, and even though they use different libcs, Flatpak still makes it work.
You don’t need to add cross-compiling support to your build system, either, because Flatpak doesn’t actually cross-compile. Instead, it uses QEMU to emulate the entire SDK on the target platform. This is slower, but also much easier to set up.
Diving Into Builder’s Code
Builder’s codebase was intimidating when I first looked into this issue. There’s a lot of moving parts–turns out autoconfiguring so many build systems, languages, and platforms is complicated! But the maintainers are very helpful and approachable, so contributing wasn’t as hard as I thought it would be.
The biggest change was to add an
IdeRunner subclass that would issue a
deviced command to run the app rather than creating a local subprocess. I
also had to make sure the app is deployed and up to date before running it and
hook up the stdin/stdout of the remote process to the local terminal.
Huge thanks to Christian Hergert and vanadiae for answering my questions (like “where do I start?”) and reviewing my MR!