mkbundle commands for cross compilation. (#2970)
authorMiguel de Icaza <miguel@gnome.org>
Sat, 14 May 2016 04:32:14 +0000 (21:32 -0700)
committerMiguel de Icaza <miguel@gnome.org>
Sat, 14 May 2016 04:32:14 +0000 (21:32 -0700)
* 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

man/mkbundle.1
mcs/tools/mkbundle/mkbundle.cs

index ed704b89d6aea515bdfa80ec664c4709a2b2e705..246bcfc2abd82f396ff5ec6ab3d3c11df2e21768 100644 (file)
@@ -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"
index 6395e90ff41b3499337d075e126a72376dd6f35e..472c3793dc089891612cf70ce2a7adc92de06efe 100755 (executable)
@@ -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" +