Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mono mkbundle throws 'IKVM.Reflection.BadImageFormatException'

I've been trying to compile or bundle my application using mkbundle. This is the script I'm executing:

set -o errexit
set -o nounset

mono_version="3.2.3"
export MONO=/cygdrive/c/progra~2/Mono-$mono_version

machineconfig=$PROGRAMFILES\\Mono-$mono_version\\etc\\mono\\4.0\\machine.config

export PATH=$PATH:$MONO/bin

export PKG_CONFIG_PATH=$MONO/lib/pkgconfig

icon_name='"icon.ico"'

echo "1 ICON $icon_name" > icon.rc

export CC="i686-pc-mingw32-gcc icon.o -U _WIN32"

output_name=Output.exe

mkbundle JiraTempoApp.exe MonoPosixHelper.dll gtk-sharp.dll glib-sharp.dll atk-sharp.dll gdk-sharp.dll glade-sharp.dll glib-sharp.dll pango-sharp.dll RestSharp.dll JiraRestLib.dll --deps --machine-config "$machineconfig" -o $output_name -z

rm icon.rc 
rm icon.o

cp $MONO/bin/mono-2.0.dll .
cp $MONO/bin/zlib1.dll .

./$output_name

I had to add MonoPosixHelper.dll because I got a EntryPoint not found error. Now I got this weird error:

$ ./mkbundle_cygwin.sh
OS is: Windows
WARNING:
  Check that the machine.config file you are bundling
  doesn't contain sensitive information specific to this machine.
Sources: 11 Auto-dependencies: True

Unhandled Exception:
IKVM.Reflection.BadImageFormatException: Exception of type 'IKVM.Reflection.BadImageFormatException' was thrown.
  at IKVM.Reflection.Reader.PEReader.RvaToFileOffset (UInt32 rva) [0x00000] in <filename unknown>:0
  at IKVM.Reflection.Reader.ModuleReader.Read (System.IO.Stream stream) [0x00000] in <filename unknown>:0
  at IKVM.Reflection.Reader.ModuleReader..ctor (IKVM.Reflection.Reader.AssemblyReader assembly, IKVM.Reflection.Universe universe, System.IO.Stream stream, System.String location) [0x00000] in <filename unknown>:0
  at IKVM.Reflection.Universe.OpenRawModule (System.IO.Stream stream, System.String location) [0x00000] in <filename unknown>:0
  at IKVM.Reflection.Universe.OpenRawModule (System.String path) [0x00000] in <filename unknown>:0
  at IKVM.Reflection.Universe.LoadFile (System.String path) [0x00000] in <filename unknown>:0
  at MakeBundle.LoadAssembly (System.String assembly) [0x00000] in <filename unknown>:0
  at MakeBundle.LoadAssemblies (System.Collections.Generic.List`1 sources) [0x00000] in <filename unknown>:0
  at MakeBundle.Main (System.String[] args) [0x00000] in <filename unknown>:0
[ERROR] FATAL UNHANDLED EXCEPTION: IKVM.Reflection.BadImageFormatException: Exception of type 'IKVM.Reflection.BadImageFormatException' was thrown.
  at IKVM.Reflection.Reader.PEReader.RvaToFileOffset (UInt32 rva) [0x00000] in <filename unknown>:0
  at IKVM.Reflection.Reader.ModuleReader.Read (System.IO.Stream stream) [0x00000] in <filename unknown>:0
  at IKVM.Reflection.Reader.ModuleReader..ctor (IKVM.Reflection.Reader.AssemblyReader assembly, IKVM.Reflection.Universe universe, System.IO.Stream stream, System.String location) [0x00000] in <filename unknown>:0
  at IKVM.Reflection.Universe.OpenRawModule (System.IO.Stream stream, System.String location) [0x00000] in <filename unknown>:0
  at IKVM.Reflection.Universe.OpenRawModule (System.String path) [0x00000] in <filename unknown>:0
  at IKVM.Reflection.Universe.LoadFile (System.String path) [0x00000] in <filename unknown>:0
  at MakeBundle.LoadAssembly (System.String assembly) [0x00000] in <filename unknown>:0
  at MakeBundle.LoadAssemblies (System.Collections.Generic.List`1 sources) [0x00000] in <filename unknown>:0
  at MakeBundle.Main (System.String[] args) [0x00000] in <filename unknown>:0

My .exe is succesfully running on Windows and Ubuntu but I'm trying to bundle it so that users don't have to download mono.

like image 886
Stijn Bernards Avatar asked Nov 19 '14 15:11

Stijn Bernards


1 Answers

mkbundle can't handle dynamically linked libraries as MonoPosixHelper.dll. If you want you application to run without mono, you will need to deploy this (and other libraries) together with your application on the target system.

If you want to run your application on Ubuntu and don't want the user to install libgtk2.0-cil, you will also have to deploy libatksharpglue-2.so libgdksharpglue-2.so libglibsharpglue-2.so libgtksharpglue-2.so libpangosharpglue-2.so as the *-sharp.dlls require them.

Then make sure the target system is able to find these libraries. Either by defining LD_LIBRARY_PATH or by creating DLL-maps on the build system (which is tricky and can get a little tedious).

You can also pass the --static parameter to mkbundle to include all needed mono libraries directly in your bundle (see manpage for details). Also, execute your final bundle only with MyApp.exe not with mono MyApp.exe.

Here are some options to do this for Linux targets. I didn't use mkbundle with mono on Windows, yet, but only compiled against .NET with msbuild, which also creates .msi files.

Option 1:

$DEPS = "gtk-sharp.dll glib-sharp.dll atk-sharp.dll gdk-sharp.dll glade-sharp.dll glib-sharp.dll pango-sharp.dll RestSharp.dll JiraRestLib.dll"
mkbundle --static -o JiraTempoApp JiraTempoApp.exe --deps $DEPS --machine-config "$machineconfig" -z

Then make sure to deploy MonoPosixHelper.dll. and the other .so files depicted above to your system. To start your application, execute

LD_LIBRARY_PATH=/path/to/deployed/libs:$LD_LIBRARY_PATH JiraTempoApp

However, I cannot verify that this method with setting the LD_LIBRARY_PATH works at the moment.

Option 2:

Build with the same command as in Option 1, but execute from the directory of your deployed libs:

cd /path/to/deployed/libs; /path/to/JiraTempoApp

Option 3:

This is a little more complicated: You need to find your the dependency .dlls and their .dll.config files on your build system. Copy them to your build directory and the dll mapping in the config file with a mapping that includes a relative path to the location of the .so files on the target system. This way, the dll mapping gets packed by mkbundle and the packed executable will be able to find the deployed .sos on the target system. I once wrote a Makefile for an application that uses this option, maybe it will help you.

like image 198
sburnicki Avatar answered Nov 06 '22 10:11

sburnicki