THere are some appliactions that include more than one binary. I.e. Synfig have “bin/synfigstudio” (GUI) and “bin/synfig” (CLI for rendering). Opentoonz also besides main GUI binary have “tcomposer”, “tcleanup”, “tconverter”, “tfarmserver”, and more.
How it is possible to run those “alternative” binaries from appimage, instead of the main one?
In snapcraft this is implemented via dot, i.e. snapname.subcommand.
For appimage I probably can write a script wrapper for default binary, that accepts some argument, like this: some.appimage --appbin tconverter ...
Just want to know - maybe there are some common practice already exists?
AppImage is centered around GUI applications, just like .app bundles on macOS.
The usual way is that the AppRun file inside the AppImage puts usr/bin onto the $PATH that is seen by the main executable in the AppImage. This means that the main GUI executable can call additional (usually: command-line helper) binaries just like if they were on the system’s $PATH.
If you want to bundle multiple command-line binaries inside an AppImage, then you could define bash as your main executable…
In this case I would like to provide the opportunity to run alternative binary in the appimages managed by me (OpenToonz, Synfig, and future ones).
This is what I am planning to do:
Add a wrapper script, which will look if first cli argument is --appimage-exec and if second argument also have some value
If no --appimage-exec argument or no second argument defined, then run default binary
If --appimage-exec argument exists, then run application, specified by second cli argument.
Since I am going to enforce this approach on my appimages, I REALLY would like to have an agreement on some standard way on achieving this. In particular, I would like to agree on the option name - will it be called --appimage-exec or something else? In this case user will know - “aha, I can try to run alternative binary with exactly this option”.
In the best possible way it would be awesome if this option will be handled by AppRun script by default. In this case the use of AppImages could be expanded beyond of GUI applications, which is a big benefit.
With this approach it will not be possible for user to manually associate his files with AppImage executable. Because calling “file.appimage some_file” will try to call “some_file” command instead of opening file.
The advantage of approach with --appimage-exec option is that it also leaves the room to expand future set of options handled by AppRun. I.e. in the future it is possible to add some other --appimage-* options, which extend functionality bundled with AppImage container.
For example, it could be nice to have --appimage-integrate, which will create all necesary desktop files (I know, there is already desktopintegration script available, but it really would be nice to have such feature bundled directly into AppRun).
Well, the architectural question is what should be handled by AppRun (YOUR launcher that is supposed to also work outside of an AppImage, e.g., in a standalone AppDir) vs. AppImage’s runtime.c (common to all AppImages)… which already has some --appimage-... options.
#!/bin/bash
# The purpose of this custom AppRun script is
# to allow symlinking the AppImage and invoking
# the corresponding binary depending on which
# symlink was used to invoke the AppImage
HERE="$(dirname "$(readlink -f "${0}")")"
if [ ! -z $APPIMAGE ] ; then
BINARY_NAME=$(basename "$ARGV0")
if [ -e "$HERE/usr/bin/$BINARY_NAME" ] ; then
exec "$HERE/usr/bin/$BINARY_NAME" "$@"
else
exec "$HERE/usr/bin/ippserver" "$@"
fi
else
exec "$HERE/usr/bin/ippserver" "$@"
fi
Umm… @probono I have read in some of your posts (do not remember exact link) that the concept of AppImage is “to have nothing installed”. In case of using $ARGV0 approach (and thus symlinking to some file) is actually means some kind of installation, From this point of view I find “–appimage-exec” approach more flexible. Sorry for critique, just found this is kind of pops-out from appimage concept.
I would say this is in the domain of what is inside the AppImage, and hence each author of an AppImage can decide. It is not something the AppImage format needs to (or should) mandate.
As an author of an AppImage, you can implement this kind of functionality either in the payload application or in a custom AppRun script.
What about an environment variable that you set before running the AppImage such as ${APPIMAGE_EXEC} this would have the advantage of your custom flag along with not breaking compatibility with other AppImages? It would also have the advantage of not requiring the AppImage to be called via another filename
Another argument I can see to such a feature in the AppImage by default is so integration tools can integrate the same commands the appimage can use
Else, we would be in a situation where these tools can manage to run multiple binaries (by listing the usr/bin folder for example), but the AppImage alone can’t if the application author didn’t configure it to do so
The main way to use AppImages is double-clicking them in the file manager. Just like with .app bundles on the Mac, this implies that each AppImage holds one (main) application.
For command line tool collections like ImageMagick there is the workaround of invoking different commands based on the name of the symlink an AppImage is accessed under. But that is rather a special case.
#!/bin/sh
# The purpose of this custom AppRun script is
# to allow symlinking the AppImage and invoking
# the corresponding binary depending on which
# symlink was used to invoke the AppImage
# make sure errors in sourced scripts will cause this script to stop
set -e
HERE="$(readlink -f "$(dirname "$0")")"
source "$HERE"/apprun-hooks/"linuxdeploy-plugin-gtk.sh"
BINARY_NAME=$(basename "$ARGV0")
if [ "$BINARY_NAME" = "pyrogenesis" -o "$BINARY_NAME" = "0ad" ] ; then
exec "$HERE/usr/bin/pyrogenesis" "$@"
elif [ "$BINARY_NAME" = "ActorEditor" ]; then
exec "$HERE/usr/bin/ActorEditor" "$@"
else
exec "$HERE/usr/bin/pyrogenesis" "$@"
fi