【发布时间】:2016-02-08 03:30:15
【问题描述】:
mono 生成的普通 EXE 在 IL 中。我想生成 Native Executable,使用 mkbundle 生成原生 Exe 还是应该使用 Mono AOT。
【问题讨论】:
标签: c# mono monodevelop xamarin-studio
mono 生成的普通 EXE 在 IL 中。我想生成 Native Executable,使用 mkbundle 生成原生 Exe 还是应该使用 Mono AOT。
【问题讨论】:
标签: c# mono monodevelop xamarin-studio
是的,mkbundle 生成本机可执行文件。 例如,在 Linux 上,这是我的 .NET 程序集:
file Agent.exe
Agent.exe: PE32 executable (console) Intel 80386, Mono/.Net assembly, for MS Windows
我告诉mkbundle 将其编译为本机可执行文件(这里我必须添加 Common.dll,它是我的 Agent.exe 程序集的依赖项):
现在,让我们再次运行file 命令,这次是针对生成的“代理”二进制文件:
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 选项获得一个独立、自包含的可执行文件。
【讨论】:
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 应包含三对 ldstr 和 call 指令,以及终止 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)
【讨论】:
mkbundle 和 AOT,但你可能在 mono-list@lists.ximian.com 有更好的解决方案