In this tutorial you will learn how to pack a Gambas3 application using the AppImage format. For the purpose we will use an Ubuntu 18.04 system and the appimage-builder tool.
The tutorial includes several troubleshooting steps that are required when packaging interpreted languages and may be a bit complicated for novice users. If want to get your application packaged quickly please go to the “Resume” section, download the recipe template, replace the binary, update the information and repack.
Gambas is a free development environment and a full powerful development platform based on a Basic interpreter with object extensions, as easy as Visual Basic™.
Getting the source code¶
For this tutorial we will be using a simple “Hello World” application without any special modifications. Its source code can be found at Github.
git clone https://github.com/AppImageCrafters/appimage-demo-gambas3.git
To build the gambas3 application we will use the commands gbc3 and gba3 as follows.
cd appimage-demo-gambas3/ gbc3 project/ gba3 project/ -o appimage-demo-gambas3.gambas
Prepare the AppDir¶
Once we have compiled the application we will proceed to prepare our AppDir. Which means coping the application binary and the icon inside the AppDir as follows:
mkdir -p AppDir/usr/bin cp appimage-demo-gambas3.gambas AppDir/usr/bin/ mkdir -p AppDir/usr/share/icons/hicolor/32x32/apps/ cp project/mapview.png AppDir/usr/share/icons/hicolor/32x32/apps/
Generating the recipe¶
Once we have the binary and the icon in place we proceed to call appimage-builder generate and answer the prompts as follows, notice that the file extension is not being included.
appimage-builder --generate Basic Information : ? ID [Eg: com.example.app] : org.appimagecrafters.gambas3-demo ? Application Name : Gambas3 Demo ? Icon : mapview ? Version : latest ? Executable path relative to AppDir [usr/bin/app] : usr/bin/appimage-demo-gambas3.gambas ? Arguments [Default: $@] : $@ ? Update Information [Default: guess] : guess ? Architecture : amd64
This command gathers the required information to generate a recipe, then it runs the application to find the runtime dependencies. Once your application is started must close it in order to proceed with the recipe generation. In the end a file name AppImageBuilder.yml will be created in the current working directory that should look like this:
# appimage-builder recipe see https://appimage-builder.readthedocs.io for details version: 1 AppDir: path: ./AppDir app_info: id: org.appimagecrafters.gambas3-demo name: Gambas3 Demo icon: mapview version: latest exec: usr/bin/appimage-demo-gambas3.gambas exec_args: $@ runtime: env: APPDIR_LIBRARY_PATH: $APPDIR/usr/lib/x86_64-linux-gnu:$APPDIR/usr/lib/x86_64-linux-gnu/gconv:$APPDIR/usr/lib/x86_64-linux-gnu/gtk-2.0/2.10.0/engines:$APPDIR/lib/x86_64-linux-gnu:$APPDIR/usr/lib/x86_64-linux-gnu/qt4/plugins/accessible:$APPDIR/usr/lib/gambas3:$APPDIR/usr/lib/x86_64-linux-gnu/qt4/plugins/accessiblebridge:$APPDIR/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders apt: arch: amd64 allow_unauthenticated: true sources: - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic main restricted universe multiverse - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-updates main restricted universe multiverse - sourceline: deb http://security.ubuntu.com/ubuntu bionic-security main restricted universe multiverse - sourceline: deb http://archive.neon.kde.org/user bionic main - sourceline: deb http://ppa.launchpad.net/gambas-team/gambas3/ubuntu bionic main include: - gambas3-gb-qt4 - gambas3-runtime - gtk2-engines-pixbuf - libaudio2 - libexpat1 - libgcrypt20 - libgtk2.0-0 - liblz4-1 - liblzma5 - libpcre3 - libsm6 - libsystemd0 - libxau6 - libxdmcp6 - libxext6 - libxfixes-dev - libxinerama1 - libxrender1 - libxt6 - qt-at-spi exclude:  files: exclude: - usr/share/man - usr/share/doc/*/README.* - usr/share/doc/*/changelog.* - usr/share/doc/*/NEWS.* - usr/share/doc/*/TODO.* test: fedora: image: appimagecrafters/tests-env:fedora-30 command: ./AppRun use_host_x: true debian: image: appimagecrafters/tests-env:debian-stable command: ./AppRun use_host_x: true arch: image: appimagecrafters/tests-env:archlinux-latest command: ./AppRun use_host_x: true centos: image: appimagecrafters/tests-env:centos-7 command: ./AppRun use_host_x: true ubuntu: image: appimagecrafters/tests-env:ubuntu-xenial command: ./AppRun use_host_x: true AppImage: arch: null update-information: guess sign-key: None
Fixing-up the recipe¶
Sadly appimage-builder is not capable yet of generating perfect recipes in the first ron for gambas3 applications so we will have to do some manual tuning.
If we proceed to run appimage-builder without fixing anything we will be prompted with an error like this:
schema.SchemaError: Key 'AppImage' error: Key 'arch' error: None should be instance of 'str'
Which means that the tool wasn’t able to determine the right architecture, of the target application. This happens because Gambas3 binaries are not regular ELF binaries. Therefore we must set it manually to “x86_64” (see final recipe L95).
Now we should be able to run appimage-builder but our project will fail on the test with the following error:
gbr3: unable to load component: gb.image $ ./AppRun FAILED, exit code: 1 ERROR:appimage-builder:Tests failed
It seems that some of the Gambas resources cannot be found. This is provably because it’s expected they to be installed in the system, but they are in the bundle. To correct this we use the “GB_PATH” environment variable that must point to the gbc3 binary.
To define a AppImage environment variable add the following to the recipe:
runtime: env: GB_PATH: $APPDIR/usr/bin/gbr3
Now we can run appimage-builder again. This time the application will start but it may be just an empty window. If this happens provably we are missing some other gambas3 extensions. Those “should” be resolved by the package manager but for some reasons the packages didn’t include it. Therefore, we will have to manually include them.
In my case I had to add the following packages to the apt include list:
Now when we run appimage-builder almost all test with the exception of Centos. appimage-builder uses a custom AppRun binary that configures the bundle runtime environment before calling the application and when an external application is called this configuration is removed. As the Gambas3 binaries are not ELF files the execution flow is going out at some point and returning which cases that a part of those settings are lost. To prevent this we must use as the Gambas3 interpreter as entrypoint for our bundle and pass the application binary as argument as follows:
AppDir: app_info: exec: usr/bin/gbr3 exec_args: $APPDIR/usr/bin/appimage-demo-gambas3.gambas $@
With this fix our application should run in all the tests scenarios and is ready to be shipped.
To pack a Gambas3 application using the AppImage format we need to:
- deploy the application binary inside the AppDir
- include all the Gambas3 resources and plugins packages in the recipe
- set the environment variable “GB_PATH” to $APPDIR/usr/bin/gbr3
- set usr/bin/gbr3 as entry point and pass the application binary path as argument
A working recipe can be found here. You can use it as starting point instead of going all the troubleshooting of the above steps.