在Windows中使用mkbundle静态链接Mono

时间:2017-06-20 07:37:23

标签: c# .net xamarin mono mkbundle

我在使用Windows中的mkbundle静态链接Mono时遇到了麻烦。在我试图找出发生了什么的时候,我碰到了一堵墙。当您将静态标志传递给Windows中的mkbundle时,它会在mono目录中查找monosgen-2.0-static.lib文件。该目录由以下行定义:

string monoPath = GetEnv("MONOPREFIX", @"C:\Program Files (x86)\Mono");

安装mono 5.1.1后该目录的内容是:

enter image description here

首先我注意到文件命名约定与mkbundle正在寻找的不同(monosgen-2.0应该是mono-2.0-sgen)。我可以改变这个很好,但我怀疑 - 给定文件名 - 截图中显示的mono-2.0-sgen.lib文件不是静态编译的,因为当我尝试运行我的捆绑应用程序时,它首先不能找到sgen dll,然后什么时候可以找不到别的。

此时我想知道mkbundle是否在Windows上正式运行,如果它确实是我做了一些根本错误的事情?我看过旧帖子在Windows中寻求帮助设置mkbundle并自己发布了有关此问题。大多数人指向使用mingw而不是cl.exe。我应该使用它吗?

此代码段的来源如下所示。您可以在https://github.com/mono/mono/blob/master/mcs/tools/mkbundle/mkbundle.cs找到完整的源代码。

if (style == "windows")
        {

            Func<string, string> quote = (pp) => { return "\"" + pp + "\""; };

            string compiler = GetEnv("CC", "cl.exe");
            string winsdkPath = GetEnv("WINSDK", @"C:\Program Files (x86)\Windows Kits\8.1");
            string vsPath = GetEnv("VSINCLUDE", @"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC");
            string monoPath = GetEnv("MONOPREFIX", @"C:\Program Files (x86)\Mono");

            string[] includes = new string[] {winsdkPath + @"\Include\um", winsdkPath + @"\Include\shared", vsPath + @"\include", monoPath + @"\include\mono-2.0", "." };
            // string[] libs = new string[] { winsdkPath + @"\Lib\winv6.3\um\x86" , vsPath + @"\lib" };
            var linkLibraries = new string[] {  "kernel32.lib",
                                            "version.lib",
                                            "Ws2_32.lib",
                                            "Mswsock.lib",
                                            "Psapi.lib",
                                            "shell32.lib",
                                            "OleAut32.lib",
                                            "ole32.lib",
                                            "winmm.lib",
                                            "user32.lib",
                                            "libvcruntime.lib",
                                            "advapi32.lib",
                                            "OLDNAMES.lib",
                                            "libucrt.lib" };

            string glue_obj = "mkbundle_glue.obj";
            string monoLib;

            if (static_link)
                monoLib = LocateFile (monoPath + @"\lib\monosgen-2.0-static.lib");

            else {
                Console.WriteLine ("WARNING: Dynamically linking the Mono runtime on Windows is not a tested option.");
                monoLib = LocateFile (monoPath + @"\lib\monosgen-2.0.lib");
                LocateFile (monoPath + @"\lib\monosgen-2.0.dll"); // in this case, the .lib is just the import library, and the .dll is also needed
            }

            var compilerArgs = new List<string>();
            compilerArgs.Add("/MT");

            foreach (string include in includes)
                compilerArgs.Add(String.Format ("/I {0}", quote (include)));

            if (!nomain || custom_main != null) {
                compilerArgs.Add(quote(temp_c));
                compilerArgs.Add(quote(temp_o));
                if (custom_main != null)
                    compilerArgs.Add(quote(custom_main));
                compilerArgs.Add(quote(monoLib));
                compilerArgs.Add("/link");
                compilerArgs.Add("/NODEFAULTLIB");
                compilerArgs.Add("/SUBSYSTEM:windows");
                compilerArgs.Add("/ENTRY:mainCRTStartup");
                compilerArgs.AddRange(linkLibraries);
                compilerArgs.Add("/out:"+ output);

                string cl_cmd = String.Format("{0} {1}", compiler, String.Join(" ", compilerArgs.ToArray()));
                Execute (cl_cmd);
            }

0 个答案:

没有答案