From: Miguel de Icaza Date: Sat, 14 May 2016 04:32:14 +0000 (-0700) Subject: mkbundle commands for cross compilation. (#2970) X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=2e3c90564aac3d44fac395041d728d1bf836d444;p=mono.git mkbundle commands for cross compilation. (#2970) * Start of packager for mkbundle * [mkbundle] Add fingerprint and directory at end of package * [mkbundle] Update embedding file format, add support for --options, support for --runtime, chmod +x * [driver] Add a way to parse arbitrary command line options * [mkbundle] Align the assemblies on a page boundary, do not release directory buffer * Work-around odd compiler error by using memcpy * Update makefile * Fix the windows build * [Windows] Export the new mono_parse_options_from API * Implement the various cross-compiler target fetching commands * Clean --- diff --git a/man/mkbundle.1 b/man/mkbundle.1 index ed704b89d6a..246bcfc2abd 100644 --- a/man/mkbundle.1 +++ b/man/mkbundle.1 @@ -21,9 +21,34 @@ default only the assemblies specified in the command line will be included in the bundle. To automatically include all of the dependencies referenced, use the "--deps" command line option. .PP -Use \fImkbundle\FP when you want the startup runtime to load the 1.0 -profile, and use \fImkbundle2\fP when you want the startup runtime to load -the 2.0 profile. +There are two modes of operation, the default one uses the +C compiler to create a bundle and requires a complete C and Mono SDK +to produced executables. The simple mode (enabled when using the +"--simple") command line option does not require this, and also allows +for cross compilation. +.PP +For example, to create a bundle for hello world, use the following +command: +.nf + $ mkbundle -o hello --simple hello.exe +.fi +.PP +The simple version allows for cross-compiling, this requires a Mono +runtime to be installed in the ~/.mono/targets/TARGET/mono to be +available. You can use the "--local-targets" to list all available +targets, and the "--cross" argument to specify the target, like this: +.nf + $ mkbundle --local-targets + Available targets: + default - Current System Mono + 4.4.0-macosx-x86 + 4.4.0-debian-8-arm64 + $ mkbundle --cross 4.4.0-debian-8-x86 hello.exe -o hello-debian +.fi +.PP +The above will bundle your native library into hello-debian for +PowerPC running on ARM64. +.SH OLD EMBEDDING .PP For example, to create a bundle for hello world, use the following command: @@ -57,6 +82,12 @@ are available to the embedded runtime. .I "-c" Produce the stub file, do not compile the resulting stub. .TP +.I "--cross target" +Creates a bundle for the specified target platform. The target +must be a directory in ~/.mono/targets/ that contains a "mono" +binary. You can fetch various targets using the --fetch-target +command line option. +.TP .I "-o filename" Places the output on `out'. If the flag -c is specified, this is the C host program. If not, this contains the resulting executable. @@ -74,20 +105,31 @@ Typically this is $prefix/etc/mono/1.0/machine.config or $prefix/etc/mono/2.0/machine.config depending on the profile that you are using (1.0 or 2.0) .TP -.I "--nodeps" -This is the default: \fImkbundle\fP will only include the assemblies that -were specified on the command line to reduce the size of the resulting -image created. -.TP .I "--deps" This option will bundle all of the referenced assemblies for the assemblies listed on the command line option. This is useful to distribute a self-contained image. .TP +.I "--fetch-target target" +Downloads a precompiled runtime for the specified target from the Mono +distribution site. +.TP +.I "--nodeps" +This is the default: \fImkbundle\fP will only include the assemblies that +were specified on the command line to reduce the size of the resulting +image created. +.TP .I "--keeptemp" By default \fImkbundle\fP will delete the temporary files that it uses to produce the bundle. This option keeps the file around. .TP +.I "--lists-targets" +Lists all of the available local cross compilation targets available +as precompiled binaries on the Mono distribution server. +.TP +.I "--local-targets" +Lists all of the available local cross compilation targets. +.TP .I "--machine-config FILE" Uses the given FILE as the machine.config file for the generated application. @@ -102,13 +144,10 @@ When passed, DIR will be set for the MONO_CFG_DIR environment variable By default \fImkbundle\fP dynamically links to mono and glib. This option causes it to statically link instead. .TP -.B Important: -Since the Mono runtime is licensed under the LGPL, even if you use -static you should transfer the component pieces of the mkbundle to -your users so they are able to upgrade the Mono runtime on their own. -.TP -If you want to use this for commercial licenses, you must obtain a -proprietary license for Mono from mono@novell.com +.I "--target-server SERVER" +By default the mkbundle tool will download from a Mono server the +target runtimes, you can specify a different server to provide +cross-compiled runtimes. .TP .I "-z" Compresses the assemblies before embedding. This results in smaller @@ -133,6 +172,8 @@ Mono runtime, separated by spaces. See the mono(1) manual page or run mono --hel .SH FILES This program will load referenced assemblies from the Mono assembly cache. +.PP +Targets are loaded from ~/.mono/targets/TARGETNAME/mono .SH BUGS The option "--static" is not supported under Windows. Moreover, a full cygwin environment containing at least "gcc" and "as" diff --git a/mcs/tools/mkbundle/mkbundle.cs b/mcs/tools/mkbundle/mkbundle.cs index 6395e90ff41..472c3793dc0 100755 --- a/mcs/tools/mkbundle/mkbundle.cs +++ b/mcs/tools/mkbundle/mkbundle.cs @@ -10,8 +10,8 @@ // (C) 2016 Xamarin Inc // // Missing features: -// * Implement --cross, --local-targets, --list-targets, --no-auto-fetch -// * concatenate target with package to form native binary +// * Add support for packaging native libraries, extracting at runtime and setting the library path. +// * Implement --list-targets lists all the available remote targets // using System; using System.Diagnostics; @@ -24,6 +24,7 @@ using System.Text; using IKVM.Reflection; using System.Linq; using System.Diagnostics; +using System.Net; using System.Threading.Tasks; class MakeBundle { @@ -46,9 +47,12 @@ class MakeBundle { static bool skip_scan; static string ctor_func; static bool quiet; + static string cross_target = null; + static string fetch_target = null; static bool custom_mode = true; static string embedded_options = null; static string runtime = null; + static string target_server = "https://runtimes.go-mono.com/raw/"; static int Main (string [] args) { @@ -76,7 +80,44 @@ class MakeBundle { case "-c": compile_only = true; break; + + case "--local-targets": + CommandLocalTargets (); + return 0; + + case "--cross": + if (i+1 == top){ + Help (); + return 1; + } + custom_mode = false; + autodeps = true; + cross_target = args [++i]; + break; + + case "--fetch-target": + if (i+1 == top){ + Help (); + return 1; + } + fetch_target = args [++i]; + break; + + case "--list-targets": + var wc = new WebClient (); + var s = wc.DownloadString (new Uri (target_server + "target-list.txt")); + Console.WriteLine ("Cross-compilation targets available:\n" + s); + + return 0; + case "--target-server": + if (i+1 == top){ + Help (); + return 1; + } + target_server = args [++i]; + break; + case "-o": if (i+1 == top){ Help (); @@ -230,14 +271,59 @@ class MakeBundle { if (!QueueAssembly (files, file)) return 1; + if (fetch_target != null){ + var truntime = Path.Combine (targets_dir, fetch_target, "mono"); + Directory.CreateDirectory (Path.GetDirectoryName (truntime)); + var wc = new WebClient (); + var uri = new Uri ($"{target_server}{fetch_target}"); + try { + wc.DownloadFile (uri, truntime); + } catch { + Console.Error.WriteLine ($"Failure to download the specified runtime from {uri}"); + File.Delete (truntime); + return 1; + } + return 0; + } + if (custom_mode) GenerateBundles (files); - else + else { + if (cross_target == "default") + runtime = null; + else { + var truntime = Path.Combine (targets_dir, cross_target, "mono"); + if (!File.Exists (truntime)){ + Console.Error.WriteLine ($"The runtime for the {cross_target} does not exist, use --fetch-target {cross_target} to download first"); + return 1; + } + } GeneratePackage (files); + } return 0; } + static string targets_dir = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.Personal), ".mono", "targets"); + + static void CommandLocalTargets () + { + string [] targets; + + Console.WriteLine ("Available targets:"); + Console.WriteLine ("\tdefault\t- Current System Mono"); + try { + targets = Directory.GetDirectories (targets_dir); + } catch { + return; + } + foreach (var target in targets){ + var p = Path.Combine (target, "mono"); + if (File.Exists (p)) + Console.WriteLine ("\t{0}", Path.GetFileName (target)); + } + } + static void WriteSymbol (StreamWriter sw, string name, long size) { switch (style){ @@ -934,10 +1020,10 @@ void mono_register_config_for_assembly (const char* assembly_name, cons "--simple Simple mode does not require a C toolchain and can cross compile\n" + " --cross TARGET Generates a binary for the given TARGET\n"+ " --local-targets Lists locally available targets\n" + - " --list-targets [SERVER] Lists available targets on the remote server\n" + - " --no-auto-fetch Prevents the tool from auto-fetching a TARGET\n" + + " --list-targets Lists available targets on the remote server\n" + " --options OPTIONS Embed the specified Mono command line options on target\n" + - " --runtime RUNTIME Manually specifies the Mono runtime to use\n" + + " --runtime RUNTIME Manually specifies the Mono runtime to use\n" + + " --target-server URL Specified a server to download targets from, default is " + target_server + "\n" + "\n" + "--custom Builds a custom launcher, options for --custom\n" + " -c Produce stub only, do not compile\n" +