Porting Tok To Not Linux: The Journey Of Incessant Failure

This response from a reader pretty much sums it up:

Stop One: Will Craft Work?

Craft seems like the no-brainer for a KDE project to use, considering it's in-house and supports all of KDE's frameworks and has packaging capabilities. Unfortunately, what sounds good on paper does not translate to what's good in execution.

When I first checked it out, the current version being shipped had incorrect code that would have failed to compile had it been a compiled language instead of Python. Heck, even running a typechecker for Python would have revealed the fact that the code was trying to call a function that didn't exist. Yet, this managed to get shipped. Not a good first impression.

After manually patching in the function into existence on my system, I ran into another hurdle: Craft's env script is broken; mangling PATH to an extent where entries like /usr/bin and /bin and other things got just truncated into oblivion, resulting in a shell where you couldn't do much of anything.

After manually patching PATH to be not mangled, I ran into another and the final hurdle before I gave up: Craft tried to use half bundled libraries and tools and half system libraries and tools, resulting in dynamic linker errors from system tools not finding symbols they needed from bundled libraries.

When I brought these issues up in the Craft chat, the answers basically amounted to a lack of care and “go use Ubuntu.” Not acceptable for Tok considering most of the people interested in building Tok like this don't use Ubuntu, and honestly doesn't make you have much faith in a system for porting utilities to other platforms if said system doesn't even work across the distributions of one platform.

Stop Two: Maybe Conan?

Conan seems like the second-in-line no-brainer for Tok to use. It's the largest C++ package manager, even supporting Qbs. Of course, like with Craft, what sounds good on paper doesn't match up to execution.

Out of the gate, I looked at the Qt package, only to find that there was one (1) Qt package for it consisting of the entirety of Qt, WebEngne and all. Kinda oof, but not a deal breaker. Well, it wouldn't be a dealbreaker if Conan had prebuilt Qt packages for

- Settings: arch=x86_64, build_type=Release, compiler=gcc, compiler.version=11, os=Linux

But it doesn't. I'm not going to build an entire web engine just for an attempt at maybe getting a non-Linux build of Tok, and having to build a web engine as part of Tok's CI is a no-go in terms of disk, memory and CPU.

Stop Three: vcpkg

Considering Microsoft has been a developer tools company for about as thrice as long as I've been alive, I hope their take at the C++ package manager thing is worth their salt.

Some weirdness ensued with the VCPKG_ROOT environment variable at first, but it was easy to fix by pointing it at the vcpkg repo.

While doing the vcpkg install, I found the output somewhat hard to follow, so I had no idea how far along it was. I just let it sit since it seemed to be making progress.

While vcpkg didn't have prebuilt binaries for my setup, it didn't require building all Qt modules like Conan did, so the ask was much more reasonable.

And then I noticed a big issue: vcpkg has absolutely zero versioning, other than the git repository with all the package manifests. This essentially means that in order to build with Qt5, I need to commit to an ancient version of vcpkg packages and stay there indefinitely. I also have to ask users to roll back their vcpkg install that far to build Tok. Not really acceptable as an ask for people who might want to build Tok for not Linux.

Stop Four: Wait, It's Already Here (At Least For Macs)

Turns out Nix, the thing that Tok already supports building with, also supports macOS. Well, that was easy. While it doesn't spit out a premade .app like other porting systems can do, it does ensure a working build with available dependencies, which is already most of the way there.

Conclusion: Apples And Penguins Rule, Everyone Else Drools

Cross-platform C++ packaging and distribution is still a very unsolved problem, unlike other languages/frameworks like Go, Electron, Rust, Zig, etc. as I learned painfully through these escapades. Nix seems the most promising on this front, as it offers a very consistent environment across platforms, which gets you most of the way there in terms of building. It doesn't support Windows (yet?), but simply being able to use a functional compiler instead of Apple Clang is already a killer feature for using it to port apps to macOS.

Qbs is also a huge help in terms of the porting process, as it natively supports building things that require auxiliary scripts or build system hacks with other build systems, like .app bundles, Windows installers, and multi-architecture .app/.aab/.apks with just a few or no extra lines in the build system.

For Tok on macOS, all I need to do is add these two lines to the build script in order to get a usable .app file from it:

Depends { name: "bundle" }
bundle.isBundle: true

While it lacks a lot of metadata that you need to fill in yourself, it's again, another 99% of the way there solution where the remaining 1% is mostly just a little data or boilerplate or running a tool.

I still haven't figured out what I'll be doing for Windows, but the need for an end-user Windows package is still a long ways off, considering Tok is still nowhere near a 1.0 release status. Perhaps I can make leverage of Fedora's mingw packages or check out https://mxe.cc/, or maybe just install dependencies from source to a Windows system without a package manager, and bundle them during the build process. If you have any suggestions, do feel free to hop on by in the Tok chat and drop them.

Tags: #libre