diff options
author | Alexis Christoforides <alexis@thenull.net> | 2016-01-23 01:38:32 +0300 |
---|---|---|
committer | Alexis Christoforides <alexis@thenull.net> | 2016-01-26 22:48:14 +0300 |
commit | e978bcdc36332dbe9503a60a80cac9e936c2d38f (patch) | |
tree | 844d82a1cb5f190b0f93ddc8e8bdc8d14c98c7c9 | |
parent | 040d26ee915cd05035ba488603e43facd6905064 (diff) |
[mkbundle] More Windows linking fixes, added "--custom-main" option
-rwxr-xr-x | mcs/tools/mkbundle/mkbundle.cs | 96 |
1 files changed, 73 insertions, 23 deletions
diff --git a/mcs/tools/mkbundle/mkbundle.cs b/mcs/tools/mkbundle/mkbundle.cs index fa39892bb03..7a3936fd34b 100755 --- a/mcs/tools/mkbundle/mkbundle.cs +++ b/mcs/tools/mkbundle/mkbundle.cs @@ -36,6 +36,7 @@ class MakeBundle { static string os_message = ""; static bool compress; static bool nomain; + static string custom_main = null; static bool? use_dos2unix = null; static bool skip_scan; static string ctor_func; @@ -134,6 +135,13 @@ class MakeBundle { case "--nomain": nomain = true; break; + case "--custom-main": + if (i+1 == top) { + Help (); + return 1; + } + custom_main = args [++i]; + break; case "--style": if (i+1 == top) { Help (); @@ -476,7 +484,7 @@ void mono_register_config_for_assembly (const char* assembly_name, cons string template = s.ReadToEnd (); tc.Write (template); - if (!nomain) { + if (!nomain && custom_main == null) { Stream template_main_stream = System.Reflection.Assembly.GetAssembly (typeof(MakeBundle)).GetManifestResourceStream ("template_main.c"); StreamReader st = new StreamReader (template_main_stream); string maintemplate = st.ReadToEnd (); @@ -502,37 +510,78 @@ void mono_register_config_for_assembly (const char* assembly_name, cons 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 12.0\VC"); + 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[] 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" }; - string monoFile; - - var compilerArgs = new List<string>(); - foreach (string include in includes) - compilerArgs.Add(String.Format ("/I {0}", quote (include))); + 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) - monoFile = LocateFile (monoPath + @"\lib\monosgen-2.0.lib"); - else - monoFile = LocateFile (monoPath + @"\lib\monosgen-2.0.dll"); + monoLib = LocateFile (monoPath + @"\lib\monosgen-2.0-static.lib"); - compilerArgs.Add("/MD"); - compilerArgs.Add(temp_c); - compilerArgs.Add(temp_o); - compilerArgs.Add("/link"); + 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 + } - if (nomain) - compilerArgs.Add("/NOENTRY"); - compilerArgs.Add("/DLL"); + var compilerArgs = new List<string>(); + compilerArgs.Add("/MT"); - foreach (string lib in libs) - compilerArgs.Add(String.Format ("/LIBPATH:{0}", quote(lib))); - compilerArgs.Add (quote(monoFile)); + foreach (string include in includes) + compilerArgs.Add(String.Format ("/I {0}", quote (include))); - string cl_cmd = String.Format("{0} {1}", compiler, String.Join(" ", compilerArgs.ToArray())); - Execute (cl_cmd); + if (!nomain || custom_main != null) { + compilerArgs.Add(temp_c); + compilerArgs.Add(temp_o); + if (custom_main != null) + compilerArgs.Add(quote(custom_main)); + compilerArgs.Add(monoLib); + compilerArgs.Add("/link"); + compilerArgs.Add("/NODEFAULTLIB"); + compilerArgs.Add("/SUBSYSTEM:CONSOLE"); + compilerArgs.AddRange(linkLibraries); + compilerArgs.Add("/out:"+ output); + + string cl_cmd = String.Format("{0} {1}", compiler, String.Join(" ", compilerArgs.ToArray())); + Execute (cl_cmd); + } + else + { + // we are just creating a .lib + compilerArgs.Add("/c"); // compile only + compilerArgs.Add(temp_c); + compilerArgs.Add(String.Format("/Fo" + glue_obj)); // .obj output name + + string cl_cmd = String.Format("{0} {1}", compiler, String.Join(" ", compilerArgs.ToArray())); + Execute (cl_cmd); + + string librarian = GetEnv ("LIB", "lib.exe"); + var librarianArgs = new List<string> (); + librarianArgs.Add (String.Format ("/out:{0}.lib" + output)); + librarianArgs.Add (temp_o); + librarianArgs.Add (glue_obj); + librarianArgs.Add (monoLib); + string lib_cmd = String.Format("{0} {1}", librarian, String.Join(" ", librarianArgs.ToArray())); + Execute (lib_cmd); + } } else { @@ -724,6 +773,7 @@ void mono_register_config_for_assembly (const char* assembly_name, cons " --machine-config F Use the given file as the machine.config for the application.\n" + " --static Statically link to mono libs\n" + " --nomain Don't include a main() function, for libraries\n" + + " --custom-main C Link the specified compilation unit (.c or .obj) with entry point/init code\n" + " -z Compress the assemblies before embedding.\n" + " --skip-scan Skip scanning assemblies that could not be loaded (but still embed them).\n" + " --static-ctor ctor Add a constructor call to the supplied function.\n" + |