Skip to content

Bundling Mono apps

probonopd edited this page Mar 21, 2017 · 13 revisions

Just unpacking Mono-based applications almost never works because they clutter libraries all over the place which need to be specifically installed, otherwise we get errors like

Unhandled Exception:
System.IO.FileNotFoundException: Could not load file or assembly 'log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=a5715cc6d5c3540b' or one of its dependencies.
File name: 'log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=a5715cc6d5c3540b'
[ERROR] FATAL UNHANDLED EXCEPTION: System.IO.FileNotFoundException: Could not load file or assembly 'log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=a5715cc6d5c3540b' or one of its dependencies.
File name: 'log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=a5715cc6d5c3540b'

For example, liblog4net1.2-cil_1.2.10+dfsg-6_all.deb has a nasty postinstall script that does

#!/bin/sh
set -e
# Automatically added by dh_installcligac
if [ "$1" = "configure" ] && [ -x /usr/share/cli-common/gac-package-install ]; then
	/usr/share/cli-common/gac-package-install liblog4net1.2-cil
fi
# End automatically added section
# Automatically added by dh_cligacpolicy
if [ "$1" = "configure" ] && [ -x /usr/share/cli-common/policy-install ]; then
	/usr/share/cli-common/policy-install log4net 1.2
fi
# End automatically added section

Why such things are needed is completely beyond me. Have they never heard of $PATH and /usr/lib?

What are we supposed to do with this when putting together an AppImange?

cat ./usr/share/cli-common/packages.d/liblog4net1.2-cil.installcligac
/usr/lib/cli/log4net-1.2/log4net.dll

Hence we seemingly need to do something along the lines of

cat ./usr/share/cli-common/packages.d/*.installcligac > DLLS
sed -i -e 's|/usr|./usr|g' DLLS
DLLS=$(cat DLLS)
cp $DLLS usr/lib/
rm DLLS

Please edit this page if you know more.

Reader comments

@Juniorsnet reports

I success do a app.image from my C#/Gtk# mono app. (by hand)

  1. Download a runtime from mono servers https://download.mono-project.com/runtimes/raw/ in my case 4.8.0-linux-libc2.12-i386.zip

  2. The Zip file has 3 folder (etc, lib, bin), put lib/ and bin/ under AppDir/usr/ and etc/ folder in AppDir

  3. make AppDir/usr/bin/mono executable

  4. In my case aditionally y grab the GTK# libs from ubuntu packages and put in AppDir/usr/lib/cli

  5. Important: Edit all Dll Maping of GTK# libs (info) and remove the absolute path.

The File gtk-sharp.dll.config has:

<configuration>
  <dllmap dll="libglib-2.0-0.dll" target="libglib-2.0.so.0"/>
  <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.so.0"/>
  <dllmap dll="libatk-1.0-0.dll" target="libatk-1.0.so.0"/>
  <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-x11-2.0.so.0"/>
  <dllmap dll="gtksharpglue-2" target="/usr/lib/cli/gtk-sharp-2.0/libgtksharpglue-2.so"/>
  <dllmap dll="glibsharpglue-2" target="/usr/lib/cli/glib-sharp-2.0/libglibsharpglue-2.so"/>
</configuration>

Remove the absolute path.

<configuration>
  <dllmap dll="libglib-2.0-0.dll" target="libglib-2.0.so.0"/>
  <dllmap dll="libgobject-2.0-0.dll" target="libgobject-2.0.so.0"/>
  <dllmap dll="libatk-1.0-0.dll" target="libatk-1.0.so.0"/>
  <dllmap dll="libgtk-win32-2.0-0.dll" target="libgtk-x11-2.0.so.0"/>
  <dllmap dll="gtksharpglue-2" target="libgtksharpglue-2.so"/>
  <dllmap dll="glibsharpglue-2" target="libglibsharpglue-2.so"/>
</configuration>
  1. Create a bash that set the MONO_PATH environment variable and the LD_PATH_LIBRARY to add de folder where library has, for example in my script:
#!/bin/bash
echo "Ejecutando VisorDatosTaco en ${0}"
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./lib/mono/4.5:./lib/cli/gtk-sharp-2.0:./lib/cli/atk-sharp-2.0:./lib/cli/gdk-sharp-2.0:./lib/cli/glade-sharp-2.0:./lib/cli/glib-sharp-2.0:./lib/cli/gtk-dotnet-2.0:./lib/cli/pango-sharp-2.0:./lib/cli/webkit-sharp-1.1
export MONO_PATH=./lib/mono/4.5:./lib/cli/gtk-sharp-2.0:./lib/cli/atk-sharp-2.0:./lib/cli/gdk-sharp-2.0:./lib/cli/glade-sharp-2.0:./lib/cli/glib-sharp-2.0:./lib/cli/gtk-dotnet-2.0:./lib/cli/pango-sharp-2.0:./lib/cli/webkit-sharp-1.1
MONO_LOG_LEVEL=debug ./bin/mono --config ../etc/mono/config ./local/bin/VisorDatosTaco.exe

And thats it, at least is a start point.

Here is my app.image Visor.appimage you can decompress and see how is the structure.

AppImage is really great.

Mono runtimes

These are all but documented and seemingly cannot be downloaded using a normal browser but wget. It is almost like Microsoft is actively hiding them:

Apparently these are originally meant for a tool called mkbundle which is supposed to do a very similar thing like AppImage but often fails at doing the job: https://forum.ubuntuusers.de/topic/monodevelop-mkbundle-bug-tipp/ Can AppImage succeed where mkbundle fails?