AppImage

Linuxdeployqt: New Linux Deployment Tool for Qt

Inspired by this year’s QtCon in Berlin, I have been working on Linux Deployment Tool for Qt, linuxdeployqt. These are my first steps with Qt and with C++ for that matter, and it is stil very young, but I’d appreciate your testing, comments, and (ideally) code review.

linuxdeployqt takes an application as input and makes it self-contained by copying in the Qt libraries and plugins that the application uses into a bundle. This can optionally be put into an AppImage.

This tool is conceptually based on the Mac Deployment Tool, macdeployqt in the tools applications of the Qt Toolkit, but has been changed to a slightly different logic and other tools needed for Linux.

  • Instead of an .app bundle for macOS, this produces an AppDir for Linux
  • Instead of a .dmg disk image for macOS, this produces an AppImage for Linux which is quite similar to a dmg but executes the contained application rather than just opening a window on the desktop from where the application can be launched
1 Like

This is fantastic, thank you for working on this. As soon as I get some time I will test this out on my Qt project and give you some feedback.

Thanks. Since you definitely know about Qt and C++, I’d appreciate if you could have a look at the FIXMEs in the code too - probably not hard for someone who has some experience with it.

I feel like I am getting somewhere, but still not successful.

scarlett@scarlett-neon:~/Downloads/build-skanlite-Desktop_Qt_5_7_0_GCC_64bit-Default/src$ linuxdeployqt skanlite -appimage -verbose=2
"/usr/local/bin/usr/bin:/home/scarlett/.rbenv/shims:/home/scarlett/.rbenv/bin:/home/scarlett/kde-5/bin:/home/scarlett/qt5/bin:/home/scarlett/bin:/home/scarlett/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/scarlett/src/go/bin:/home/scarlett/.rvm/bin"
app-binary: “skanlite"
ERROR: FIXME: Here I would like to determine the original rpath of the main executable, but get: QSet(”$ORIGIN/lib")
Log: Deploying libraries found inside: ("./AppRun", “./lib/libicudata.so.55”, “./lib/libicuuc.so.55”, “./lib/libicui18n.so.55”)
Log: “libicui18n.so” already stripped.
Log: “libicuuc.so” already stripped.
Log: “libicudata.so” already stripped.
Log: “libicudata.so” already stripped.
Log: “libicuuc.so” already stripped.
Log: Creating AppImage for "."
Log: "./bin//appimageextract:9: GtkWarning: Unable to locate theme engine in module_path: “adwaita”,"
Log: " gtk.STOCK_OPEN, gtk.RESPONSE_OK))"
Log: "xorriso 0.5.6 : RockRidge filesystem manipulator, libburnia project."
Log: "libburn : SORRY : Unsuitable filetype for pseudo-drive"
Log: "xorriso : FAILURE : Cannot aquire drive ‘.’"
Log: "xorriso : NOTE : Tolerated problem event of severity ‘FAILURE’"
Log: "Copying of file objects from ISO image to disk filesystem is: Enabled"
Log: "xorriso : FAILURE : No ISO image present. No -dev, -indev, or -outdev selected."
Log: "xorriso : NOTE : Tolerated problem event of severity ‘FAILURE’"
Log: "xorriso : UPDATE : Thank you for being patient for 1 seconds"
Log: "Extracted from ISO image: file ‘/’=’/home/scarlett/Desktop/…AppDir’"
Log: "xorriso : NOTE : Tolerated problem event of severity ‘FAILURE’"
Log: "xorriso : NOTE : -return_with SORRY 32 triggered by problem severity FAILURE"
Log: "chown: cannot access ‘/home/scarlett/Desktop/…AppDir’: No such file or directory"
Log: "chmod: cannot access ‘/home/scarlett/Desktop/…AppDir’: No such file or directory"
Log: Created AppImage at “…AppImage”

The most visible problem is… it is searching for an AppDir on my desktop? The appimage does not actually get created. verbose 3 does show your ldd magic going on. So it is at this ISO part that the failure begins. Any ideas?
Scarlett

Let’s take this in two steps: First, bundle the app without -appimage and see whether it does its thing properly (be sure to inspect the binary with ldd).

You might be running into https://github.com/probonopd/linuxdeployqt/issues/2, try setting the ENVs mentioned there prior to running linuxdeployqt (and unset them thereafter).

After you confirm this working, we will work on the AppImage part, ok?

You might also want to try -bundle-non-qt-libs: Also bundle non-core, non-Qt libraries.

The tool has seen some progress in the last days. make sure you have the correct qmake of the Qt instance to be bundled on the $PATH.

You have a typo in your post. Link to AppImageAssistant should be https://github.com/AppImage/AppImageKit/releases

That section was outdated. AppImageAssistant is not used anymore, but the newer appimagetool. It comes as part of the linuxdeployqt*.AppImage.

I just downloaded the latest stable version of linuxdeployqt-6-x86_64.AppImage and am having problems getting it to work, part of this is because the Usage section is really not clear how to use this program.

I have several versions of Qt5 installed and have set my PATH variable to put the Qt5 bin directory first.

This is how I run it:

linuxdeployqt-6-x86_64.AppImage TranzViz -verbose=3

This is the end of the log file where it runs into problems finding the lconvert program:

Log: Looking for lconvert at “/usr/lib64/qt5/bin/lconvert”
Log: Fallback, looking for lconvert at “/tmp/.mount_linuxdbkT9zd/usr/bin/lconvert”
ERROR: lconvert not found at “/tmp/.mount_linuxdbkT9zd/usr/bin/lconvert”
ERROR: Failed to copy translations

The lconvert program is in the bin directory specified in the path. It appears linuxdeployqt is not looking there, but in a standard install location.

When I manually copy the lconvert program to /usr/lib64/qt5/bin and re-run, I see no errors. However, there is to qt_ulk.qm file in the translations directory, even though it says that it is creating it:

Log: Creating “/run/media/rmartz/Seagate Backup Plus Drive/Programs/TranViz074A/translations/qt_uk.qm” …
Log: lconvert arguments: ("-o", "/run/media …

So, please, how about a little more detail or what I need to do to get this program to work.

Sorry for the late response. Please open an issue over at https://github.com/probonopd/linuxdeployqt/issues including instructions (GitHub link with Travis CI enabled would be best, like in https://github.com/probonopd/linuxdeployqt/#using-linuxdeployqt-with-travis-ci) so that we can reproduce it.

Thank you for creating this app. It’s fantastic.

I’m creating the AppImage for this amazing fractal software, called Fractorium, http://fractorium.com.

The AppImage version is working very well. Soon it’ll be available for download.

But I have one doubt. In MacOS I can access all files that the .App has. Fractorium has 4 executables. One that is the main application (graphical app), and three others that are only for command line. In MacOS I can open the terminal and type Fractorium.app/path/to/other_app. Is it possible to do the same with AppImage?

Thank you!

1 Like

Unlike what happens on the Mac, an AppImage is unmounted automatically as soon as the application quits. But there is a way to achieve what you need:

You need to write a custom AppRun bash script that will run the appropriate binary, depending on how it was invoked. Please see those examples:

Also, make sure to pass in your additional command line tools to linuxdeployqt using the-executable=... option (one per binary) so that those, too, can use the bundled libraries.

Thank you so much probono!

1 Like

Hi. I am new to Github. I use linuxdeployqt on my qt elf files. There is notice that not linking against oldest possible loader of elf files or better to write glibc is discouraging. glibc on linux shows to the, for example ld-2.27.so file on my system. That’s the actual glibc file with all the functions to load the and execute the elf (Qt or c++,…) file. Why should be discouragin? I do not understand this. We do not have to link to the oldest version so it would work with the on the older linux systems. What I did is compile it on my new linux system, ran linuxdeployqt onqt elf file, then ran patchelf --set-interpreter ld-2.27.so myfile and distributed my elf all the qt libraries and loader (ld-2.27.so file) to the old linux system!!! AND it WORKS with no problems. In my case I have new version of loader or glibc on the old system and works perfectly! kind regards Thomas

Hi Tomaž, does it also work if you invoke it from another directory?

Example:

/home/user/app/executable
/home/user/app/ld-2.27.so

Patch executable so that it uses ld-2.27.so.

Then run it, but not from /home/user/app/ like this: ./executable

But from /home/user/ like this: ./app/executable

Will it work?

Hi. The loader is in the same directory as the elf file. If I move the ld-2.27.so to another directory it doesn’t work. However I can set with patchelf the path to another directory. Then it works. Tomaž

Since AppImages are read-only, how do you set with patchelf the path to another directory each time the AppImage is moved around?

Hi, I tried to compile linuxdeployqt for ubuntu-12.04 after installing qt5.6 and g+±9 but I didn’t succeed. Is there may be an old appimage of linuxdeployqt for ubuntu-12.04 amd64 which works? The most current one is complaining about glibc-2.17.
My interest is to reactivate some old software which is based on qt3 which I like a lot (vipec and k3d) to generate appimages which could run on current ubuntu-versions.

A 2nd question is if I could point an environment variable to somewhere inside the mounted fuse share. I successfully generated an appimage for vipec with an old binary (deb-file) but an environmentvariable is supposed to point to some local files of the program, which I copied into the AppDir.

Thank’s a lot for this beautiful project and the maintenance.

Hello @storkan no we don’t have one that can run on that old systems. Unfortunately.
Maybe you will have more luck with getting https://github.com/probonopd/go-appimage to run on that kind of a system. The appimagetool in that (still experimental) repository should have roughly the same capabilities like linuxdeployqt. Feel free to open an issue at https://github.com/probonopd/go-appimage/issues if you can’t get it to work; since it is still very new and a bit rough around the edges.

Hi. I don not run appImage. I run elf file directly- the executable file. The program runs with no problems. I use relative paths so for example everything is in folder myAppFolder. I can move the folder around as much I will. BUT I can not change the structure inside the myAppFolder. There are lib folder paths folder etc…elf file (my application)…

By the way. This /home/user/ like this: ./app/executable doesn’t work!
kind regards Tomaž