I’m looking to package a Qt application to run on a wide variety of distributions, but I’ve always run into issues related to glibc and stdc++ library versions, and how they are tightly bound to the kernel version. Is it possible to build an application on say ubuntu 16 and run it on centos 6?
Hi Paul. I have been working around these challenges for about 10 years now.
how they are tightly bound to the kernel version
Actually, this has nothing to do with the kernel (Linus doesn’t break userspace compatibility!) but with low-level libraries like glibc.
So the short answer is:
Yes, a “new” AppImage will run on “old” systems if you build on the oldest system you are targeting. The AppImage will run on this system and all newer systems. E.g., if you produce an AppImage on CentOS 6 then it will run on Ubuntu 16.04 just fine. In fact, that is what projects like Krita and KDevelop do to produce their AppImages. The Qt company also builds their Qt binaries this way.
The long answer:
It is possible to make AppImages that are compiled on a later build system and still have the AppImage run on (very) old target systems. However, this is a) complicated and b) bloated, since all dependencies down to very basic system libraries like glibc would have to be bundled. Hence, it is not the recommended route. But if you don’t care about ca. 10 MB overhead, it certainly can be done.
Thank you very much for the reply! That all makes great sense.
I was very much hoping for some kind of magic dependency-bundling tool that would somehow work around the problems I’ve run into in the past with providing a newer glibc which causes the app to core dump on older systems.
I ended up just building on what I think will be the oldest distribution we’ll want to support, and throwing in the odd libraries from there that don’t exist on the newer distributions, and it seems to be working. It’s just a directory structure with a wrapper script that sets LD_LIBRARY_PATH, which I suspect is what an AppImage would do for me.
My app uses an embedded Python 2.7 interpreter, and that was the one big point of contention. Centos 6 comes with Python 2.6, so I had to install an after-market 2.7 (which ends up in /usr/local/lib), but newer distributions come with Python 2.7 in /usr/lib. I’m requiring my users to deal with getting 2.7 installed when necessary, instead of bundling it with my app. Out of curiosity, how would AppImage deal with situation?
AppImage is a self-mounting ISO file that has a AppRun script/executable that sets LD_LIBRARY_PATH and a few other envs, and does essentially exactly what you do manually.
I would just bundle the required Python version and all the needed modules. An AppImage is supposed to need nothing than what can be expected to be part of every target system.
AppImage gives you a number of additional advantages, such as
- Easy to manage, one app = one file
- Applications are immutable
- Binary delta updates with the update information embedded inside the AppImage
- Digital signatures (soon)
- No unpacking and fiddling around
- Desktop integration (optional)
- Easy sandboxing (optional)