Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make "mkbundle --deps" option working with mono 3.2.3

Tags:

c#

mono

mkbundle

I am trying to bundle the application with mono 3.2.3 to a stand-alone executable. To do so, I am following this guideline. After declarating variables:

mono_version="3.2.3"
export MONO=/cygdrive/c/progra~2/Mono-$mono_version
machineconfig=$PROGRAMFILES\\Mono-$mono_version\\etc\\mono\\4.5\\machine.config
export PATH=$PATH:$MONO/bin
export PKG_CONFIG_PATH=$MONO/lib/pkgconfig
export CC="i686-pc-mingw32-gcc -U _WIN32"

mkbundle --deps command cannot localize referenced assemblies:

Unhandled Exception:
System.IO.FileNotFoundException: Could not load file or assembly 'gtk-sharp' or 
one of its dependencies. The system cannot find the file specified.
File name: 'gtk-sharp'

performing exactly the same operation with mono 2.10.9:

mono_version="2.10.9"
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
export CC="i686-pc-mingw32-gcc -U _WIN32"

mkbundle --deps --machine-config "$machineconfig" -c UI.exe

gives positive result:

OS is: Windows
WARNING:
  Check that the machine.config file you are bundling
  doesn't contain sensitive information specific to this machine.
Sources: 3 Auto-dependencies: True
   embedding: C:\users\piotr\desktop\authoringtool\UI\bin\debug\UI.exe
 config from: C:\users\piotr\desktop\authoringtool\UI\bin\debug\UI.exe.config
   embedding: C:\PROGRA~2\MONO-2~1.9\lib\mono\gac\gtk-sharp\2.12.0.0__35e10195dab3c99f\gtk-sharp.dll
   embedding: C:\PROGRA~2\MONO-2~1.9\lib\mono\gac\glib-sharp\2.12.0.0__35e10195dab3c99f\glib-sharp.dll
   .
   .
   .
   embedding: C:\PROGRA~2\MONO-2~1.9\lib\mono\4.0\Mono.Posix.dll
Machine config from: C:\Program Files (x86)\Mono-2.10.9\etc\mono\4.0\machine.config
Compiling:
as -o temp.o temp.s

Does anyone know the reason of such behavior? I'm using 64-bit version of windows 7 and the Cygwin I found on the official website. The code was compiled and tested on Xamarin Studio 4.2 and Visual Studio 2010.

like image 762
Tinki Avatar asked Mar 06 '14 13:03

Tinki


1 Answers

Howto for mkbundle on cygwin + mingw

Tested with mono 4.0.3
In mono 4.0.3, mkbundle works but it can be tricky to make it work.
First, check your setup:

  • Install Mono/GTK# in a path that doesn't contains spaces (ie not Program Files then)
  • Setup a MinGw/Cygwin working compile chain (as the one for compiling mono on windows).
  • Define the mandatory environment variables for mkbundle:
    • mingw compiler location should be in the Windows PATH (used by cmd)
    • pkg-config should also be in the Windows PATH
  • Use the following cygwin script (it can be adapted to run on cmd)
# M_PREFIX refers to Mono installation # For more information, search for prefix installation in Mono documentation M_PREFIX='/cygdrive/c/Mono'  export DYLD_FALLBACK_LIBRARY_PATH=${M_PREFIX}/lib:${DYLD_FALLBACK_LIBRARY_PATH} export LD_LIBRARY_PATH=${M_PREFIX}/lib:${M_PREFIX}/lib/mono/4.5:${LD_LIBRARY_PATH} export C_INCLUDE_PATH=${M_PREFIX}/include:${C_INCLUDE_PATH} export ACLOCAL_PATH=${M_PREFIX}/share/aclocal:${ACLOCAL_PATH} export PKG_CONFIG_PATH=${M_PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH} # Here we added the system32 to make cmd available to mkbundle # /usr/bin is the default location for mingw export PATH=${M_PREFIX}/bin:/cygdrive/c/Windows/system32:/usr/bin:${PATH}  export CC="i686-pc-mingw32-gcc -U _WIN32" 

Then you can run:

mkbundle --deps --keeptemp my.exe my.dll -o bundled.exe 

Notes: - Copy mono-2.0.dll in the application directory as it should be distributed along the bundled exe

cp ${M_PREFIX}/bin/mono-2.0.dll . 
  • if -z is used, zlib1.dll should be copied as well. (note that gcc invocation change also). You may need more dll depending on your usage of framework features (not exhaustive list : libglib*.dll, libgmodule*.dll, libgthread*.dll, iconv.dll, intl.dll)
  • -c is used to generate only stub.
  • You must specify all exe and dll that are needed for the bundle.
  • --keeptemp will keep temp.c and temp.s which could come in handy if mkbundle fail on gcc invocation.
  • If you want to invoke gcc by hand (and it may be needed):
i686-pc-mingw32-gcc -U _WIN32 -g -o output.exe -Wall temp.c $(pkg-config --cflags --libs mono-2)  temp.o

For Console Applications

To make console application work you must remove -mwindows from the gcc command. To do that, you must invoke pkg-config --cflags --libs mono-2 and remove the -mwindows.

You should obtain something like that afterwards:

     i686-pc-mingw32-gcc  -g -o output.exe -Wall temp.c -mms-bitfields -IC:/Mono/include/mono-2.0 -mms-bitfields  -LC:/Mono/lib -lmono-2.0 -lws2_32 -lpsapi -lole32 -lwinmm -loleaut32 -l advapi32 -lversion temp.s 

Anyone can improve mkbundle

mkbundle is an open sourced C# console application (on mono github) so it can be easily modified and recompiled depending on your needs. Reading the code could also be helpful to understand how it works underneath.
cmd usage as the different commands used by mkbundle are hard coded so it would benefit from some parametrization enhancement.

like image 122
Fab Avatar answered Sep 24 '22 08:09

Fab