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: