X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Ftools%2Fmkbundle%2Fmkbundle.cs;h=47365ca07c316266468a2645d69a1e200e3112f3;hb=c67160f3c8c6f46c56e5140d7d7b4872cde13d3a;hp=f8c65c53f04b81e341d0e636e9bc2c8fa5c02217;hpb=b2262f41726a89c8209facb3ea9e4be9582422b5;p=mono.git diff --git a/mcs/tools/mkbundle/mkbundle.cs b/mcs/tools/mkbundle/mkbundle.cs index f8c65c53f04..47365ca07c3 100644 --- a/mcs/tools/mkbundle/mkbundle.cs +++ b/mcs/tools/mkbundle/mkbundle.cs @@ -15,6 +15,7 @@ using System.Collections; using System.Reflection; using System.IO; using System.Runtime.InteropServices; +using System.Text; using Mono.Unix; using ICSharpCode.SharpZipLib.Zip.Compression.Streams; @@ -27,9 +28,11 @@ class MakeBundle { static bool compile_only = false; static bool static_link = false; static string config_file = null; + static string machine_config_file = null; static string config_dir = null; static string style = "linux"; static bool compress; + static bool nomain; static int Main (string [] args) { @@ -101,6 +104,16 @@ class MakeBundle { config_file = args [++i]; break; + case "--machine-config": + if (i+1 == top) { + Help (); + return 1; + } + + machine_config_file = args [++i]; + + Console.WriteLine ("WARNING:\n Check that the machine.config file you are bundling\n doesn't contain sensitive information specific to this machine."); + break; case "--config-dir": if (i+1 == top) { Help (); @@ -112,6 +125,9 @@ class MakeBundle { case "-z": compress = true; break; + case "--nomain": + nomain = true; + break; default: sources.Add (args [i]); break; @@ -128,6 +144,23 @@ class MakeBundle { ArrayList files = new ArrayList (); foreach (Assembly a in assemblies) QueueAssembly (files, a.CodeBase); + + // Special casing mscorlib.dll: any specified mscorlib.dll cannot be loaded + // by Assembly.ReflectionFromLoadFrom(). Instead the fx assembly which runs + // mkbundle.exe is loaded, which is not what we want. + // So, replace it with whatever actually specified. + foreach (string srcfile in sources) { + if (Path.GetFileName (srcfile) == "mscorlib.dll") { + foreach (string file in files) { + if (Path.GetFileName (new Uri (file).LocalPath) == "mscorlib.dll") { + files.Remove (file); + files.Add (new Uri (Path.GetFullPath (srcfile)).LocalPath); + break; + } + } + break; + } + } GenerateBundles (files); //GenerateJitWrapper (); @@ -142,7 +175,7 @@ class MakeBundle { sw.WriteLine ( ".globl {0}\n" + "\t.section .rodata\n" + - "\t.align 32\n" + + "\t.p2align 5\n" + "\t.type {0}, @object\n" + "\t.size {0}, {1}\n" + "{0}:\n", @@ -185,11 +218,12 @@ class MakeBundle { ArrayList config_names = new ArrayList (); byte [] buffer = new byte [8192]; - StreamWriter ts = new StreamWriter (File.Create (temp_s)); - StreamWriter tc = new StreamWriter (File.Create (temp_c)); + using (StreamWriter ts = new StreamWriter (File.Create (temp_s))) { + using (StreamWriter tc = new StreamWriter (File.Create (temp_c))) { string prog = null; tc.WriteLine ("/* This source code was produced by mkbundle, do not edit */"); + tc.WriteLine ("#include "); tc.WriteLine ("#include \n"); if (compress) { @@ -276,7 +310,7 @@ class MakeBundle { return; } Console.WriteLine ("System config from: " + config_file); - tc.WriteLine ("extern const unsigned char system_config;"); + tc.WriteLine ("extern const char system_config;"); WriteSymbol (ts, "system_config", config_file.Length); int n; @@ -289,6 +323,29 @@ class MakeBundle { ts.Write ("\t.byte 0\n"); ts.WriteLine (); } + + if (machine_config_file != null){ + FileStream conf; + try { + conf = File.OpenRead (machine_config_file); + } catch { + Error (String.Format ("Failure to open {0}", machine_config_file)); + return; + } + Console.WriteLine ("Machine config from: " + machine_config_file); + tc.WriteLine ("extern const char machine_config;"); + WriteSymbol (ts, "machine_config", machine_config_file.Length); + + int n; + while ((n = conf.Read (buffer, 0, 8192)) != 0){ + for (int i = 0; i < n; i++){ + ts.Write ("\t.byte {0}\n", buffer [i]); + } + } + // null terminator + ts.Write ("\t.byte 0\n"); + ts.WriteLine (); + } ts.Close (); Console.WriteLine ("Compiling:"); @@ -316,6 +373,8 @@ class MakeBundle { } if (config_file != null) tc.WriteLine ("\tmono_config_parse_memory (&system_config);\n"); + if (machine_config_file != null) + tc.WriteLine ("\tmono_register_machine_config (&machine_config);\n"); tc.WriteLine ("}\n"); if (config_dir != null) @@ -333,8 +392,16 @@ class MakeBundle { StreamReader s = new StreamReader (template_stream); string template = s.ReadToEnd (); tc.Write (template); - tc.Close (); + + if (!nomain) { + Stream template_main_stream = Assembly.GetAssembly (typeof(MakeBundle)).GetManifestResourceStream ("template_main.c"); + StreamReader st = new StreamReader (template_main_stream); + string maintemplate = st.ReadToEnd (); + tc.Write (maintemplate); + } + tc.Close (); + if (compile_only) return; @@ -347,16 +414,16 @@ class MakeBundle { if (static_link) { string smonolib; if (style == "osx") - smonolib = "`pkg-config --variable=libdir mono`/libmono.a "; + smonolib = "`pkg-config --variable=libdir mono-2`/libmono-2.0.a "; else - smonolib = "-Wl,-Bstatic -lmono -Wl,-Bdynamic "; - cmd = String.Format ("{4} -o {2} -Wall `pkg-config --cflags mono` {0} {3} " + - "`pkg-config --libs-only-L mono` " + smonolib + - "`pkg-config --libs-only-l mono | sed -e \"s/\\-lmono //\"` {1}", + smonolib = "-Wl,-Bstatic -lmono-2.0 -Wl,-Bdynamic "; + cmd = String.Format ("{4} -o {2} -Wall `pkg-config --cflags mono-2` {0} {3} " + + "`pkg-config --libs-only-L mono-2` " + smonolib + + "`pkg-config --libs-only-l mono-2 | sed -e \"s/\\-lmono-2.0 //\"` {1}", temp_c, temp_o, output, zlib, cc); } else { - cmd = String.Format ("{4} " + debugging + " -o {2} -Wall {0} `pkg-config --cflags --libs mono` {3} {1}", + cmd = String.Format ("{4} " + debugging + " -o {2} -Wall {0} `pkg-config --cflags --libs mono-2` {3} {1}", temp_c, temp_o, output, zlib, cc); } @@ -366,6 +433,8 @@ class MakeBundle { return; } Console.WriteLine ("Done"); + } + } } finally { if (!keeptemp){ if (object_out == null){ @@ -472,17 +541,20 @@ class MakeBundle { { Console.WriteLine ("Usage is: mkbundle [options] assembly1 [assembly2...]\n\n" + "Options:\n" + - " -c Produce stub only, do not compile\n" + - " -o out Specifies output filename\n" + - " -oo obj Specifies output filename for helper object file\n" + - " -L path Adds `path' to the search path for assemblies\n" + - " --nodeps Turns off automatic dependency embedding (default)\n" + - " --deps Turns on automatic dependency embedding\n" + - " --keeptemp Keeps the temporary files\n" + - " --config F Bundle system config file `F'\n" + - " --config-dir D Set MONO_CFG_DIR to `D'\n" + - " --static Statically link to mono libs\n" + - " -z Compress the assemblies before embedding.\n"); + " -c Produce stub only, do not compile\n" + + " -o out Specifies output filename\n" + + " -oo obj Specifies output filename for helper object file\n" + + " -L path Adds `path' to the search path for assemblies\n" + + " --nodeps Turns off automatic dependency embedding (default)\n" + + " --deps Turns on automatic dependency embedding\n" + + " --keeptemp Keeps the temporary files\n" + + " --config F Bundle system config file `F'\n" + + " --config-dir D Set MONO_CFG_DIR to `D'\n" + + " --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" + + " -z Compress the assemblies before embedding.\n" + + " You need zlib development headers and libraries.\n"); } [DllImport ("libc")] @@ -501,6 +573,7 @@ class MakeBundle { IntPtr buf = UnixMarshal.AllocHeap(8192); if (uname (buf) != 0){ Console.WriteLine ("Warning: Unable to detect OS"); + UnixMarshal.FreeHeap(buf); return; } string os = Marshal.PtrToStringAnsi (buf); @@ -514,17 +587,41 @@ class MakeBundle { static bool IsUnix { get { int p = (int) Environment.OSVersion.Platform; - return ((p == 4) || (p == 128)); + return ((p == 4) || (p == 128) || (p == 6)); } } static int Execute (string cmdLine) { - Console.WriteLine (cmdLine); if (IsUnix) { + Console.WriteLine (cmdLine); return system (cmdLine); - } else { - Process p = Process.Start ("sh", String.Format ("-c \"{0}\"", cmdLine)); + } + + // on Windows, we have to pipe the output of a + // `cmd` interpolation to dos2unix, because the shell does not + // strip the CRLFs generated by the native pkg-config distributed + // with Mono. + StringBuilder b = new StringBuilder (); + int count = 0; + for (int i = 0; i < cmdLine.Length; i++) { + if (cmdLine [i] == '`') { + if (count % 2 != 0) { + b.Append ("|dos2unix"); + } + count++; + } + b.Append (cmdLine [i]); + } + cmdLine = b.ToString (); + Console.WriteLine (cmdLine); + + ProcessStartInfo psi = new ProcessStartInfo (); + psi.UseShellExecute = false; + psi.FileName = "sh"; + psi.Arguments = String.Format ("-c \"{0}\"", cmdLine); + + using (Process p = Process.Start (psi)) { p.WaitForExit (); return p.ExitCode; }