An AppAImage is simply a method to create a single executable file with all of the program dependencies, assets and etc inside the file. This allows for executing the program on any system that supports the AppImage without having to have all the dependencies installed on the system. Such as libraries. Basically, a self-contained executable file. Many open-source projects use, like Godot, OpenRA, and many more.
The way AppImage works, in general, is by simply creating a fake root file system, using squashfs. which is a lightweight filesystem. Inside the directory you will find, in many applications, using a similar structure as your real Unix-based root file system is setup. like directories like /usr/lib and /usr/bin and etc.
Explore Existing AppImage
The best way to get an understanding would be to download an AppImage that you perhaps use and have a good understanding of what it does and etc.
All AppImage has dedicated command line options associated with the AppImage itself. In order to see the whole list, use the following commands.
AppImage options: --appimage-extract  Extract content from embedded filesystem image If pattern is passed, only extract matching files --appimage-help Print this help --appimage-mount Mount embedded filesystem image and print mount point and wait for kill with Ctrl-C --appimage-offset Print byte offset to start of embedded filesystem image --appimage-portable-home Create a portable home folder to use as $HOME --appimage-portable-config Create a portable config folder to use as $XDG_CONFIG_HOME --appimage-signature Print digital signature embedded in AppImage --appimage-updateinfo[rmation] Print update info embedded in AppImage --appimage-version Print version of AppImageKit
The command –appimage-extract will extract the file similar to when you extract files from a zip/archive file. That way, it will become apparent how AppImage is structured internally.
An example would be the OpenRA Red Alert AppImage. By executing the AppImage with the extract command option, we get the following outputs and etc.
./OpenRA-Red-Alert-x86_64.AppImage --appimage-extract squashfs-root/.DirIcon squashfs-root/AppRun squashfs-root/etc squashfs-root/etc/mono squashfs-root/etc/mono/4.5 squashfs-root/etc/mono/4.5/machine.config squashfs-root/etc/mono/config squashfs-root/openra-ra.desktop squashfs-root/openra-ra.png squashfs-root/usr squashfs-root/usr/bin squashfs-root/usr/bin/gtk-dialog.py squashfs-root/usr/bin/mono squashfs-root/usr/bin/openra-ra squashfs-root/usr/bin/openra-ra-server squashfs-root/usr/bin/openra-ra-utility squashfs-root/usr/bin/restore-environment.sh squashfs-root/usr/lib .........
Looks very similar to the file structure on many Unix based system, with the /usr/bin and /usr/lib.
Though, it should be mention that it is possibly not necessary required to have the same structure as the Unix file system. Since the first thing to be executed is the AppRun file.
When building an AppImage, The installation properties for both executable and library has to be set. Furthermore, for any additional asset files, the program will use. See the following for library and executable targets.
# Setup library and executable targets. ADD_LIBRARY(mylib lib.cpp) ADD_EXECUTABLE(myBin main.cpp) # Install targets. INSTALL(TARGETS mylib DESTINATION lib) INSTALL(TARGETS myBin DESTINATION bin)
Once the CMake file has been configured, the following commands can be invoked. It will create a dedicated directory to build, followed by the install prefix. This will override the default install prefix that CMake assigns. Followed by simply invoking make, or whatever build system you use. Once is compiled successfully, You can install it, by override the root directory for where it will install. In this case, it will be AppDir. It should not be required to call the directory AppDir.
mkdir build && cd build cmake .. -DCMAKE_INSTALL_PREFIX=/usr make -j $( nproc ) make install DESTDIR=AppDir
Once all of the previous commands are successful, we can proceed with the next section.
Build Image with LinuxDeploy
Note, the following mention program as of this writing is still in Alpha. Though, still a useful tool. The following is an example of what argument should be added.
- –appdir is the root installed directory. It is the same directory that DESTDIR was assigned to previously.
- –icon-filename is the path to the icon image it will use. (note it can be picky with the resolution)
- –icon-file the name of the icon file inside the AppImage. Note this is the name that the desktop file used in its configuration.
- –desktop-file the path to a valid desktop file.
- –output what kind of output format.
Note, that the desktop file is important since the program will use its configuration for which executable it will invoke.
./linuxdeploy-x86_64.AppImage --appdir AppDir/ --output appimage --icon-filename --desktop-file myprogram.desktop --icon-file icon
Following is an example of a desktop file. using the file extension .desktop.
[Desktop Entry] Type=Application Version=1.0 Name=MyProgram Comment=a very cool software Exec=myprogram Icon=icon GenericName=MyProgram Categories=Utility Terminal=false
The output filename as of writing does not seem to be able to be set. Rather, it is implicitly set by the name, that is configured in the desktop file. Whereas the version by default set by git commit hash. However can be set setting the environment variable VERSION. For instance, as following.
HotFix Finding Library in Other Paths
The program will automate much of the process such as finding libraries dependencies your program uses. However, if you use libraries associated with your executable target in CMake, you will have to add a search path for its explicitly as an argument with linuxdeploy. This can be resolved by using the LD_LIBRARY_PATH environment variable.
Quick About Handle File Management
Finally, A quick note about handle the relative file path inside the AppImage, Since the current directory is set to some random directory. It can become a bit of a challenge for the file management to make sure that the program can find its files.
It is possible to get some useful data from the environment variables that AppImage creates when executing it. These can be used to handle File Management. See the AppImage website documentation. The APPDIR is useful to get the root directory path for the AppImage. From there it is simply a matter of computing the relative path of your asset files.
AppImage can allow for creating a single deployable executable that is easier to run on any system that supports Linux/Unix. Since it does not require all dependent apt-packages to be available. However, there is an initial setup and potential changes required in the code to handle file paths. Though, it can be provided with a great way to share programs without having to do much setup.
Free/Open software developer, Linux user, Graphic C/C++ software developer, network & hardware enthusiast.