Open tvierling opened 7 years ago
Thanks for your suggestion and ideas how to implement this. From time to time (very rarely) this topic comes up.
Let's collect very concrete use cases here. Do you have/are you interested in bundling an application that would benefit from this, here and now?
Wireshark is the immediate poster example. It ships with a flurry of utility applications to do bulk work on packet capture files: capinfos
, dumpcap
, editcap
, mergecap
, rawshark
, reordercap
, text2cap
. All these are command-line tools.
However, this concept allows for AppImage distribution of many packages that are designed to have many applications in them -- packages which may not even have a GUI or a designated "main" application. For instance: moreutils
offers a set of small but useful tools, though perhaps so small that the AppImage overhead might be too much. ImageMagick
would be a more appropriate and larger example, which is a set of ten applications with no main app. An extreme example would be something like netpbm.
"ImageMagick would be a more appropriate and larger example, which is a set of ten applications with no main app."
As of v7.0.0 release of ImageMagick and thereafter, this is no longer true.
While for backward compatibility the ten (actually: twelve!) CLI tools (from IM v6.x and earlier) you mentioned are still invokable through their old names ("convert"
, "compare"
, "indentify"
, "compose"
, "animate"
, "montage"
etc.), IM v7.x has one single new executable replacing the twelve, called magick
. But you can run it as
magick convert
magick compare
magick identify
magick compose
magick animate
magick montage
[....]
to get the same behaviour as in IM v6. Also, IM ships with symlinks using the old names which all point to the same magick
executable, and which behave the same.
However, there are quite a few examples on MY personal wish list, all of them CLI utilities, which are developed as a set of distinguished executables. All these would benefit from a standard implementation of your feature request: poppler-utils, ghostscript, podofo, qpdf, ... Currently one can only work around it by adding an own custom AppRun
(possibly through a more or less simple Shell script).
Also, if one looks closely enough, one discovers quite a few more GUI apps which are widley used and ship with little helper tools alongside represented through separate binaries: Blender, Calibre, All their extra functionalities "fall under the table" when using their respective AppImage packages. Granted, 99% of user may not be using these. But the 1% using them are the power users. If they miss out on something, they'll have a reason to not like AppImage, and they will tell the 99% about their unhappiness...
A custom AppRun
script can solve this easily.
@probonopd wrote above:
"A custom AppRun script can solve this easily."
I know.
You didn't see that I wrote exactly that in my previous comment?
@KurtPfeifle:
"Currently one can only work around it by adding an own custom
AppRun
(possibly through a more or less simple Shell script)."
But couldn't this be made even more easy for AppImage packagers to achieve? Without requiring them to write a custom AppRun script for almost every additional application they want to package?
For example... let's assume, it could work the following way:
binaries.list
into the root of the AppDir listing all the binaries (with their paths) he wants to expose to the user. (At this time I do not want to attempt to define the format of this .list file....)binaries.list
file.binaries.list
file gets read (by whatever component -- you decide)../calibre.AppImage --appimage-binaries
(or when `appimaged` digests it), he gets a list of available binaries../calibre.Appimage --appimage-launch=ebook-edit
appimaged
also knows about the available binaries and can expose them in the desktop menus.manpages.list
../calibre.Appimage --appimage-man=calibre
or ./calibre.Appimage --appimage-man=lrfviewer
.calibre.AppImage
-- what use would it be to look at the system-provided man pages from 4 years ago?! Especially when calibre has a new release every one or two weeks, as is the case...)A big part of this 'extra' work could be automated, by providing tools which create the .list files by themselves. And letting the AppImage packager only intervene and modify these, if something is not going according to his wishes...
I challenge you: This is sooooo overly complex and difficult to implement. We'll surely need a custom AppRun shell script to get this working. You will not be able to implement this into runtime.c
or AppRun.c
. The Snap and FlatPak people will be wayyyy ahead of you (or are they already??), to get this working!
Yes, I can see the value in this, but It is clearly way more functionality than we can have in runtime.c
and exceeds its scope (my estimation is that it would easily duplicate the LOC). So I suggest we should do a separate sub-project working on such an AppRun.c
that would implement this and that people putting together AppImages can choose to use. Once this is in a working state, we can even consider that tools like linuxdeployqt
could pick this up automatically for applications that have Terminal=true
set.
The question is, who has the time to implement this? @tvierling maybe?
If all of the executables are stored in the AppImage's bin
directory then this could be as simple as checking if the first command line argument corresponds to the name of one of the executables. If so, run that executable with the remaining arguments. If it doesn't, pass all arguments (including the first) to the default executable.
# AppRun (or runtime.c, reimplemented in C)
if [[ -f "${APPDIR}/bin/$1" && -x "${APPDIR}/bin/$1" ]]; then
cmd="$1"
shift
"${APPDIR}/bin/${cmd}" "$@"
else
"${APPDIR}/bin/default-cmd" "$@"
fi
This might be small enough for runtime.c, and could be excluded at compile time for applications that don't need it, if a particular compile option or environment variable was specified (or unspecified, depending on what you want the default behaviour to be).
True @shoogle - the only thing that complicates this a bit is the fact that nothing mandates to put commands into {APPDIR}/bin/
or {APPDIR}/usr/bin/
. AppImage just says "provide an AppDir", and the AppDir spec iirc doesn't mandate a certain filesystem layout besides having some files like AppRun
and .DirIcon
.
Maybe, but I think it would be useful to have a recommended/suggested internal structure for AppImages, specifically to enable useful optional features like this one. People who don't need the optional features can use their own layout; they wouldn't have to follow the recommendation.
The recommended structure would simply be the usual FHS + FreeDesktop.org layout, which pretty much everyone is using already. This makes it trivial matter to extract and "install" files from the AppImage that are needed for a full desktop integration.
${APPDIR}/bin/* # binaries
${APPDIR}/lib/*.so # libraries
${APPDIR}/share/applications/*.desktop # desktop files
${APPDIR}/share/bash-completion/completions/* # bash completions
${APPDIR}/share/icons/hicolor/scalable/apps/*.svg # icons
${APPDIR}/share/man/man1/*.1.gz # manuals
${APPDIR}/share/mime/packages/*.xml # filetype associations
${APPDIR}/share/MyApp/* # application files
I suppose you could prefix these with /usr
if you want, but I kind of see the AppDir itself as being the /usr
directory.
(Now what would be awesome is if we could have a write-enabled ${APPDIR}/home
directory!)
Following this layout would be entirely optional, but would enable special features like:
(Now what would be awesome is if we could have a write-enabled ${APPDIR}/home directory!)
We have something similar, ${APPIMAGE}.home
support...
While most applications do have a main entry point to get to all their functionality, plenty of apps ship with additional executables for various purposes, like cvlc (a command-line-only interface for VLC), editcap (a command-line pcap file splicer with Wireshark), and so forth. These might be additional binaries, or might be a change of behavior based on the
argv[0]
value of the main application at runtime.There should be some way to invoke these alternate programs.
The spec should provide a way to invoke an alternate program than the main payload.
The spec could provide a way to enumerate additional names and the locations of the respective programs within the AppDir explicitly, through a metadata file (not strictly necessary if the other options below are also implemented).
In the absence of explicit enumeration, or if an attempted program name was not enumerated, the AppImage should fallback by looking for the program name in a standard search path within the AppDir, e.g.,
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
.If there is still no matching program after looking at the explicit list and the search path, fallback to invoking the main payload application.
In all cases, set
argv[0]
to the attempted program name, possibly with a prepended path if one is found within the AppDir. This allows a program to change behavior based only on the name used to invoke it.The spec should specify one or more standard ways to identify which program was intended to be invoked by the user. Possibilities include (any or all could be implemented; the first two are probably the most useful):
Use
argv[0]
of the invoked AppImage to select the desired program (this works simply by symlinking the AppImage itself to the desired alternate name).Use a special command argument at the start of the argument list which is unlikely to be meaningful to payload applications, e.g.
--AppImageRun foobar
contained inargv[1]
andargv[2]
, with the remaining arguments passed through to the application. This could be used in .desktop files.Use a predefined environment variable name, which could be used in a wrapper script.