Mono Mkbundle是否制作本地代码

时间:2013-12-10 04:03:42

标签: c# mono monodevelop xamarin-studio

单声道生成的正常EXE在IL中。我想生成Native Executable,使用mkbundle生成本机Exe还是应该使用Mono AOT。

2 个答案:

答案 0 :(得分:15)

是的,mkbundle会生成本机可执行文件。 例如,在Linux上,这是我的.NET程序集:

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

我告诉mkbundle将其编译为本机可执行文件(这里我必须添加Common.dll,它是我的Agent.exe程序集的依赖项):

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

现在,让我们再次运行file命令,这次是针对生成的'Agent'二进制文件:

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

注意:这个本机二进制文件仍然依赖于libmono(Mono运行时库),因此如果没有可用的Mono安装,它将无法在计算机上运行。

但是,您可以将libmono嵌入到二进制文件中,并使用mkbundle --static选项获取独立的,自包含的可执行文件。

答案 1 :(得分:3)

  

mkbundle 生成一个可执行程序,该程序将包含命令行中列出的程序集的静态副本。

我怀疑这是你对单词"本地exe的期望。"这是一个小实验:

Test01.cs

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

输出MSIL应包含三对ldstrcall指令以及终止ret指令。它们的操作码分别为0x72,0x28和0x2a:

让我们检查十六进制转储(grep -P允许我们使用非贪婪的匹配*?

$ 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

现在我们知道对应于上述Test01.cs的MSIL字节序列。并且mkbundle的输出包含完全相同的字节序列:

$ 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

不幸的是,我不认为mkbundle(1)有任何选项,例如--full-aot。所以AOT和创建(静态)包exe是截至目前互为排斥的(Mono 4.2.2.30)