【问题标题】:Does Mono Mkbundle Produce Native CodeMono Mkbundle 是否生成本机代码
【发布时间】:2016-02-08 03:30:15
【问题描述】:

mono 生成的普通 EXE 在 IL 中。我想生成 Native Executable,使用 mkbundle 生成原生 Exe 还是应该使用 Mono AOT。

【问题讨论】:

    标签: c# mono monodevelop xamarin-studio


    【解决方案1】:

    是的,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 操作系统是:Linux 来源:3 自动依赖:真 嵌入:Agent/bin/Debug/Agent.exe 嵌入:Agent/bin/Debug/Common.dll 嵌入:/usr/lib/mono/4.5/mscorlib.dll 嵌入:/usr/lib/mono/gac/System.Runtime.Serialization/4.0.0.0__b77a5c561934e089/System.Runtime.Serialization.dll 嵌入:/usr/lib/mono/gac/System.Xml/4.0.0.0__b77a5c561934e089/System.Xml.dll 嵌入:/usr/lib/mono/gac/System/4.0.0.0__b77a5c561934e089/System.dll 嵌入:/usr/lib/mono/gac/Mono.Security/4.0.0.0__0738eb9f132ed756/Mono.Security.dll 嵌入:/usr/lib/mono/gac/System.Configuration/4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll 嵌入:/usr/lib/mono/gac/System.Security/4.0.0.0__b03f5f7f11d50a3a/System.Security.dll 嵌入:/usr/lib/mono/gac/System.Core/4.0.0.0__b77a5c561934e089/System.Core.dll 嵌入:/usr/lib/mono/gac/Mono.Posix/4.0.0.0__0738eb9f132ed756/Mono.Posix.dll 嵌入:/usr/lib/mono/gac/System.Data.Linq/4.0.0.0__b77a5c561934e089/System.Data.Linq.dll 嵌入:/usr/lib/mono/gac/System.Data/4.0.0.0__b77a5c561934e089/System.Data.dll 嵌入:/usr/lib/mono/gac/Mono.Data.Tds/4.0.0.0__0738eb9f132ed756/Mono.Data.Tds.dll 嵌入:/usr/lib/mono/gac/System.Transactions/4.0.0.0__b77a5c561934e089/System.Transactions.dll 嵌入:/usr/lib/mono/gac/System.EnterpriseServices/4.0.0.0__b03f5f7f11d50a3a/System.EnterpriseServices.dll 编译: as -o temp.o temp.s cc -ggdb -o 代理 -Wall temp.c `pkg-config --cflags --libs mono-2` temp.o 完毕

    现在,让我们再次运行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 选项获得一个独立、自包含的可执行文件。

    【讨论】:

    • 感谢您的详细回答。因此,如果我在 Windows 中使用 mkbundle,它将生成一个带有本机代码而不是 ILCODE 的 exe 文件,对吗?如果是 .net,我使用了混淆来保护,我也应该使用它吗?
    • 是的,这就是使用 mkbundle 的意义所在。但是我无法帮助你如何在 Windows 上运行它(我不使用它),我只知道你必须在使用 mkbundle 之前安装 Mingw 编译器和 Cygwin。
    • Visual Studio for Mac 的 UI 中是否提供此选项?
    【解决方案2】:

    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)

    【讨论】:

    • 本机是指特定于平台的代码.. 不是 IL 代码。我的意思是.. 我会得到一个像 c 编译器生成的二进制文件吗?
    • 再说一次,我不认为你可以同时使用mkbundle 和 AOT,但你可能在 mono-list@lists.ximian.com 有更好的解决方案
    • 他是对的,它只是直接将.dll和.exe文件复制到一个程序集中,并没有将它们编译成机器码
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-05
    • 2016-07-24
    • 1970-01-01
    • 2014-07-23
    • 1970-01-01
    相关资源
    最近更新 更多