0

I'm having trouble statically linking Mono using mkbundle in Windows. In my attempts to figure out what's going on I hit a wall. When you pass the static flag to mkbundle in windows it looks for the file monosgen-2.0-static.lib in the mono directory. This directory is defined by the line the below:

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

The contents of this directory after installing mono 5.1.1 is:

enter image description here

First I noticed the file naming convention is different from that that mkbundle is looking for (monosgen-2.0 should be mono-2.0-sgen). I can change this just fine, however I suspect - given the file name - that the mono-2.0-sgen.lib file shown in the screenshot isn't statically compiled, as when I try to run my bundled application it first can't find the sgen dll, and then when it can it can't find others.

At this point I'm wondering if mkbundle officially works on Windows, and if it does am I doing something fundamentally wrong? I have seen older post asking for help setting mkbundle in Windows and have posted questions regarding this myself. Most point to using mingw instead of cl.exe. Should I be using this instead?

The source for this snippet is shown below. You can find the entire source code here 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);
            }
user3078629
  • 139
  • 1
  • 2
  • 9
  • does this scrip help you? https://gist.github.com/tebjan/5581296 – thalm Jun 20 '17 at 16:06
  • you can look for my post answer here: https://stackoverflow.com/questions/39905982/on-windows-mkbundle-fails-with-linker-error/41072885#41072885 – azraelrabbit Oct 18 '17 at 14:52

0 Answers0