Create C# executable with mkbundle on windows

2020-02-26 11:27发布

问题:

Im trying to create an executable from a console application. I have installed mono,cygwin (mingw-gcc, mingw-zlib1, mingw-zlib-devel, pkg-config) and I have added the following lines to my .bashrc file

export PKG_CONFIG_PATH=/cygdrive/c/progra~1/Mono-3.2.3/lib/pkgconfig
export PATH=$PATH:/cygdrive/c/progra~1/Mono-3.2.3/bin
export CC="i686-pc-mingw32-gcc -U _WIN32"

But everytime I try to use mkbundle I receive the following message

Is there a way to make mkbundle work properly on windows.?

(Im using windows 7 x86, mono 3.2.3, the cygwin I found on the official website, xamarin studio 4.2 and net framwork 4)

回答1:

This problem is still presented in the current mono version under the Windows. This happened because of mono team switched default GC to SGEN. So when you try to use mkbundle as you can see in your error mkbundle utility try to find mono-2 library but this lib didn't included in setup and you have a fail. To solve this you should configure mkbundle to use libmonosgen-2.0 instead of mono-2. Let's try to do this.

The key moment is setting this variable:

export PKG_CONFIG_PATH=/cygdrive/c/progra~1/Mono-3.2.3/lib/pkgconfig

If you go to this directory you will see a lot of *.pc files (package config). This files are responsible for configuration of linking libraries during bundling process. For some reasons mono team hard coded package config file and library to mono-2 (see this line 492). How could we fix it without rebuilding mkbundle? The solution is to use the next bundle script:

# Mono paths
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
# Compiller
export CC="i686-pc-mingw32-gcc -U _WIN32"
# Output file name
output_name=Prog.exe
# Produce stub only, do not compile
mkbundle --deps --machine-config "$machineconfig" -c Program.exe
# Produce helper object file. You may see errors at this step but it's a side effect of this method.
mkbundle --deps --machine-config "$machineconfig" -oo temp.o Program.exe
# Compile. Pay attention where I use monosgen-2 
i686-pc-mingw32-gcc -U _WIN32 -g -o "$output_name" -Wall temp.c `pkg-config --cflags --libs monosgen-2` temp.o
# Copy libmonosgen-2.dll
cp $MONO/bin/libmonosgen-2.0.dll .
# Run
./$output_name


回答2:

I had the same problem some time ago and made a script for cygwin. You can try it, would be interesting whether it still works:

mkbunde cygwin script

There are explanations in the script how to setup the environment.



回答3:

Howto for mkbundle on cygwin + mingw

Here you can find an updated howto make mkbundle work on Windows


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 a cygwin script to defined mono and mingw required variables.

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

  • 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

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.



标签: c# mono mkbundle