Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Mono Mkbundle Produce Native Code

The normal EXE's generated by mono are in IL.I want to generate Native Executable,does using mkbundle produce native Exe's or should i use Mono AOT.

like image 550
techno Avatar asked Dec 10 '13 04:12

techno


People also ask

What does Mono runtime do?

Just like on Windows, the Mono runtime (the CLR) compiles the CIL bytecode in your . NET executable Just-in-time to native code that your computer can understand and execute. In this way, a . NET file is just as "native" to Linux as it is to Windows.

Is Mono a virtual machine?

The Mono runtime implements the ECMA Common Language Infrastructure (CLI). The Mono runtime implements this virtual machine. If you are interested in the technical aspects of the Mono runtime check the Runtime Documentation.


2 Answers

Yes, mkbundle produces native executables. For example, on Linux, here is my .NET assembly:

file Agent.exe
Agent.exe: PE32 executable (console) Intel 80386, Mono/.Net assembly, for MS Windows

I tell mkbundle to compile it to a native executable (here I have to add Common.dll which is a dependency to my Agent.exe assembly):

mkbundle --deps -o Agent Agent.exe Common.dll
   OS is: Linux
   Sources: 3 Auto-dependencies: True
   embedding: Agent/bin/Debug/Agent.exe
   embedding: Agent/bin/Debug/Common.dll
   embedding: /usr/lib/mono/4.5/mscorlib.dll
   embedding: /usr/lib/mono/gac/System.Runtime.Serialization/4.0.0.0__b77a5c561934e089/System.Runtime.Serialization.dll
   embedding: /usr/lib/mono/gac/System.Xml/4.0.0.0__b77a5c561934e089/System.Xml.dll
   embedding: /usr/lib/mono/gac/System/4.0.0.0__b77a5c561934e089/System.dll
   embedding: /usr/lib/mono/gac/Mono.Security/4.0.0.0__0738eb9f132ed756/Mono.Security.dll
   embedding: /usr/lib/mono/gac/System.Configuration/4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
   embedding: /usr/lib/mono/gac/System.Security/4.0.0.0__b03f5f7f11d50a3a/System.Security.dll
   embedding: /usr/lib/mono/gac/System.Core/4.0.0.0__b77a5c561934e089/System.Core.dll
   embedding: /usr/lib/mono/gac/Mono.Posix/4.0.0.0__0738eb9f132ed756/Mono.Posix.dll
   embedding: /usr/lib/mono/gac/System.Data.Linq/4.0.0.0__b77a5c561934e089/System.Data.Linq.dll
   embedding: /usr/lib/mono/gac/System.Data/4.0.0.0__b77a5c561934e089/System.Data.dll
   embedding: /usr/lib/mono/gac/Mono.Data.Tds/4.0.0.0__0738eb9f132ed756/Mono.Data.Tds.dll
   embedding: /usr/lib/mono/gac/System.Transactions/4.0.0.0__b77a5c561934e089/System.Transactions.dll
   embedding: /usr/lib/mono/gac/System.EnterpriseServices/4.0.0.0__b03f5f7f11d50a3a/System.EnterpriseServices.dll
Compiling:
as -o temp.o temp.s 
cc -ggdb -o Agent -Wall temp.c `pkg-config --cflags --libs mono-2`  temp.o
Done

Now, Let's run the file command again, this time against the generated 'Agent' binary:

file Agent
Agent: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=698384c13208eccc609e5a573deeb09ed3420a29, not stripped

Note : this native binary still depends on libmono (the Mono runtime library), so it won't work on a machine without a working Mono installation.

You can however embed libmono into your binary and get an independant, self-contained executable by using mkbundle --static option.

like image 81
mbarthelemy Avatar answered Nov 08 '22 10:11

mbarthelemy


  • http://www.mono-project.com/archived/guiderunning_mono_applications/#bundles

mkbundle generates an executable program that will contain static copies of the assemblies listed on the command line.

I doubt this is what you expected from a word "native exe." Here's a small experiment:

Test01.cs

using System;
public class Test01 {
  public static void Main()
  {
    Console.WriteLine("Hello, world!");
    Console.WriteLine("Hello, world!");
    Console.WriteLine("Hello, world!");
  }
}

The output MSIL should contain three pairs of ldstr and call instructions, and the terminating ret instruction. Their opcodes are 0x72, 0x28 and 0x2a, respectively:

  • https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes_fields%28v=vs.110%29.aspx

Let's check the hex dump (grep -P allows us to use non-greedy match *?)

$ od -t x1 -w9999999 Test01.exe | grep -o -P 72.*?28.*?2a
...
72 01 00 00 70 28 01 00 00 0a 72 01 00 00 70 28 01 00 00 0a 72 01 00 00 70 28 01 00 00 0a 2a

Now we know the MSIL byte sequence corresponding to the above Test01.cs. And the output from mkbundle contains exactly the same byte sequence:

$ mkbundle -o Test01 Test01.exe --deps
...
$ od -t x1 -w9999999 Test01 | fgrep -o '72 01 00 00 70 28 01 00 00 0a 72 01 00 00 70 28 01 00 00 0a 72 01 00 00 70 28 01 00 00 0a 2a'
72 01 00 00 70 28 01 00 00 0a 72 01 00 00 70 28 01 00 00 0a 72 01 00 00 70 28 01 00 00 0a 2a

Unfortunately I don't think mkbundle(1) has any options like --full-aot. So AOT and creating a (static) bundle exe is mutually exclusive as of now (Mono 4.2.2.30)

like image 3
nodakai Avatar answered Nov 08 '22 11:11

nodakai