Cammino quindi penso - 2018-09-11 - La censura in Russia
Come funziona la censura di internet in Russia.
ia: Benvenite! In mi blog io scribe in interlingua, italiano e anglese.
it: Benvenuti! Nel mio blog scrivo in interlingua, italiano e inglese.
en: Welcome! In my blog I write in Interlingua, Italian and English.
La coalizione occidentale sembra invitare i jihadisti ad inscenare un nuovo attacco con armi chimiche. Ma è facile scoprire la propaganda nelle loro affermazioni.
Among the different cross-distribution application packaging systems available for Linux, the major ones being Flatpak, Snap and AppImage, I've chosen the latter for my own needs for the simple reason that it provides me the easiest way to ship my application and have it work out of the box. Flatpak and Snap will eventually get there, but for the time being universal availability and features like drag and drop are still to come.
However, the AppImage for PhotoTeleport is huge: due to having me ship many Qt5 modules, and especially the enormous QtWebEngine with all of its dependencies, the final package is almost 100 megabytes in size. One way to reduce that would be to require the user system to already have a Qt5 installation available, and therefore remove these libraries from the AppImage file. And if someone ran PhotoTeleport in a system where these libraries are not available, a small wrapper tool (based on xmessage maybe, and whatever Wayland equivalent exists) could inform the user of the problem and invite him to install the missing dependency. And I'm sure you certainly agree that this would be a horrible user experience: since we are so smart to tell that a dependency is missing, why not go the extra mile and install it ourselves?
Unfortunately, this “extra mile” is filled with subtle issues and there's the risk of delivering a solution that works in only a few lucky cases. For this reason, I would like to get the help of other developers and try to find a solution that takes into account all (or most) the subtleties that we need consider for different applications and target distributions. So, what follows is only the result of my initial brainstorming, and could be totally changed (or abandoned, if deemed unfeasible) depending on your welcome feedback.
No matter how the solution gets implemented, we can be certain of one point: we'll need a way to show some UI to the user. At the very least, this would be a dialog box or a wizard, which would inform the user of what we are doing. We need to find a solution that works both on X11 and Wayland, and that is small enough not to totally destroy the size gain. xmessage is probably present in every Linux distribution, but there doesn't appear to be a Wayland equivalent that is as much available (wlmessage even seems to be unmaintained). Of course, the possibility of shipping whatever tool we need in the AppImage itself always exists and is indeed in the philosophy of AppImage, but then we need to consider how much this costs in term of size.
On the other hand, AppImage packages already assume that some libraries are present in the target system: the excludelist file in the AppImages project lists those libraries. Among them we find the XCB library (to create surfaces on X11 systems) and FreeFont (to render font glyphs), which should give us the possibility of creating some UI in X11; the wayland client libraries are not included, but on the other hand we are talking of less than 100 kilobytes. The next question is whether we want just rely on these libraries, and therefore do all the drawing ourselves, or make use of some other drawing library which would make our task easier. A simple drawing library such as libcairo is already 1 megabyte in size, and if we move to a more complete solution such as Gtk or QtWidgets, the size grows considerably (something between 10 and 20 MBs, from a quick rough estimation). I don't have an answer to this question, and I'd like to spend some more time investigating other options before jumping to code the installer and drawing it pixel by pixel. :-)
The possibility of having different installers, depending on the UI toolkit used by the application shipped in the AppImage (so that most of the dependencies can be shared), should also be considered. This would of course reduce the size gain — for a Qt application, for example, we would have anyway to ship QtCore and QtWidgets because the installer needs them — and would introduce additional complexity because we'd need to make sure that indeed both the application and the installer can work with the version of the toolkit we are shipping.
Let's put the UI issue aside for a while, and think about how this could work from the application developer point of view. We have a bunch of dependencies that we'd like to take out of our AppImage; for example, Qt 5.9 with QtQuick and QtWebEngine, and OpenCV. Ultimately, the information we need to pass to the installer is the exact name of the libraries (like libQt5Core.so.5.9, libQt5Gui.so.5.9, etc.) as well as their soname as used by the application (like libQt5Core.so.5, libQt5Gui.so.5, etc.), possibly an md5 signature for each of them, and the URL where we can get them from, in case they are missing from the user system. Writing this information is boring, so the AppImage project might store some ready-made configuration snippets in its git repository.
An additional simplification could be the creation of “frameworks”: bundles of closely related libraries (for example, have a QtBase framework containing QtCore, QtGui, QtWidgets, etc. with all their dependencies).
When the user installs our AppImage on his system and launches the application, this will first execute the installer: the installer will check that all the downloadable libraries declared by the developer are present on the system, and if any of them are missing it would show its UI and guide the user to install them (here I figure a wizard-like UI, with progress reporting and asking as few questions as possible). The libraries would be installed somewhere in the user home directory, without requiring admin rights.
This is where all the magic would happen, and where all the dragons are hiding. It's hard to describe all the complexity in a coherent text, therefore I'll just write down a bullet list of whatever passes through my mind (it's a brainstorming, after all):
While this is a lot of work, I don't immediately see a great complexity or any real blockers. The thing that scares me the most is the idea of writing the installer UI without using any comfortable UI toolkit. Do you see some other big issues that I haven't covered?
While I put more thoughts into this, I'm tempted to start an effort to solve this problem for PhotoTeleport only: the easiest way would be to write an installer program with QtWidgets, which is already a dependency I'm shipping, and have the installer take care of downloading QtDeclarative, a few other QML modules and QtWebEngine. I could write it in such a way that it would be reusable at least for other Qt-based AppImages, and on the other hand this could be a proof of concept to tell whether this whole idea is feasible or not.
Just to highlight it: I wrote that I'm tempted to play with this idea; whether I'll do it for real is all another story. :-) I'm still pondering whether the whole thing is worth the effort, given that I haven't received a single complaint from users so far.