using System.Reflection;
using System.IO;
using System.Runtime.InteropServices;
+using System.Text;
using Mono.Unix;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
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)
{
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 ();
case "-z":
compress = true;
break;
+ case "--nomain":
+ nomain = true;
+ break;
default:
sources.Add (args [i]);
break;
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",
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 <mono/metadata/mono-config.h>");
tc.WriteLine ("#include <mono/metadata/assembly.h>\n");
if (compress) {
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;
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:");
}
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)
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;
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);
}
return;
}
Console.WriteLine ("Done");
+ }
+ }
} finally {
if (!keeptemp){
if (object_out == null){
{
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")]
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);
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;
}