domenica 13 gennaio 2019

First AppImage for Imaginario

As a follow-up to my previous post, I've finally succeeded in building Imaginario as an AppImage package.

I've smoke tested the package in Ubuntu Xenial and Trusty, and while it appears to be working, I'd be happy if someone else could also download and test it in their machines and let me know how it goes. Just please keep in mind that this a very beta release and, while I'm not aware of any major bugs that could corrupt your photos, I wouldn't recommend you to import your photo archive into it, unless you backup it first.
Also, the application needs quite some more polishing before being ready to be publicly advertised to non developers (I'm also considering finding a new icon for it), so the next step after getting a nicely working AppImage will be cleaning up the user interface and make sure that all the (few) features work as advertised. And making a Windows version. And a MacOS one. Oh, I'd better stop thinking about it, or I'll start crying.

Etichette: , , , ,

lunedì 7 gennaio 2019

A Docker image for building portable Qt applications

I've uploaded to the Docker hub an image that I will be using for building my Qt applications and packaging them into an AppImage file. To which you might be asking: why bother?

The point is that this is a slightly special image: as its Docker tag (trusty-qt512) says, this image ships Qt 5.12 on top of Ubuntu Trusty (yes, that's 14.04!). The reason why I'm using such an obsolete distribution is that I'm striving to get my AppImage package to be as portable as possible: in fact, my early builds of PhotoTeleport were run on a more recent Ubuntu 16.04, but some users complained that they couldn't run it in their own distributions (IIRC, these were Arch Linux and, indeed, Ubuntu 14.04). The problem is that while packages in the AppImage format bundle their own dependencies in the package, some libraries are generally excluded, as bundling them can cause a variety of issues. But that means that if you are building your application in a system which ships newer versions of these libraries than those installed in your users' machines, there's a high risk that your application will be using some newer symbols not present in the older versions — and therefore your application won't run in those machines.

To solve this problem, the recommended approach is to build on the oldest system that you wish to support; and given that I'm mostly familiar with Ubuntu, I chose Trusty as my target. Luckily, the Qt binary installer shipped at also happens to support Trusty, so I'm all settled. Indeed, Trusty does not ship recent versions of the C++ compiler, but that can be easily solved thanks to a wonderful PPA which ships up to g++-8.
I've also added the latest version of cmake, as it's unlikely that one can live with the very old version that's shipped in Trusty.

The Docker image can be pulled and used in your own machine or set as a baseline in your .gitlab-ci.yml recipe, if you happen to use Gitlab and are interested to generate the AppImage file from there. That's what I'm trying to do for another project of mine, and while I'm not there yet, the goal is getting closer and closer. Those interested in seeing exactly what is going into my Docker image can have a look at its Dockerfile. There are a few issues with this approach, though, and I feel that I should highlight them in order not to raise your expectations too much:

  • You must B.Y.O.D. (Bring Your Own Dependencies)! It's likely that at least some of the libraries used by your project won't exist in Trusty, or will be an older version unsuitable for your needs. That means that your .gitlab-ci.yml will have to be modified to retrieve a newer version of the library and build it prior to building your application. There are good and bad sides to this: the good one is that this encourages you to use the very latest version of the dependency, which otherwise you might not have used by preferring your distro's version; the bad side is that this is extra work for you (and for the Gitlab CI), and that you risk missing some critical security updates if you don't closely follow the upstream development of your dependencies — something that your distribution's maintainers are likely to do for you. Anyway, here's an example of how I've changed Imaginario's CI recipe to build and fetch exiv2 from its upstream site, with caching of the build artifacts.
  • Gitlab CI becomes slower! Compared to my previous builds, each job has become one or two minutes slower. This is mostly due to not using ubuntu:16.04 as a baseline: the standard Ubuntu images are widely popular, so Gitlab is playing smart and caching them. On the other hand, it seems that my custom image is being pulled every time from the Docker hub. :-(

Of course, if you know of a better way to build a portable binary while not renouncing to the benefits of using a newer Linux distributions, you are very welcome to let me know in the comments. :-)

Etichette: , , , , ,