You've already forked linux-packaging-mono
Imported Upstream version 4.4.0.182
Former-commit-id: ea38b2115ac3af9a394fe6cddf2be2acd11bc002
This commit is contained in:
parent
ee13743634
commit
180e8b1935
@ -7,6 +7,11 @@
|
||||
// Miguel de Icaza
|
||||
//
|
||||
// (C) Novell, Inc 2004
|
||||
// (C) 2016 Xamarin Inc
|
||||
//
|
||||
// Missing features:
|
||||
// * 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;
|
||||
@ -17,8 +22,9 @@ using System.IO.Compression;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using IKVM.Reflection;
|
||||
|
||||
|
||||
using System.Linq;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
class MakeBundle {
|
||||
@ -40,6 +46,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://download.mono-project.com/runtimes/raw/";
|
||||
|
||||
static int Main (string [] args)
|
||||
{
|
||||
@ -55,10 +67,56 @@ class MakeBundle {
|
||||
Help ();
|
||||
return 1;
|
||||
|
||||
case "--simple":
|
||||
custom_mode = false;
|
||||
autodeps = true;
|
||||
break;
|
||||
|
||||
case "--custom":
|
||||
custom_mode = true;
|
||||
break;
|
||||
|
||||
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 ();
|
||||
@ -67,6 +125,20 @@ class MakeBundle {
|
||||
output = args [++i];
|
||||
break;
|
||||
|
||||
case "--options":
|
||||
if (i+1 == top){
|
||||
Help ();
|
||||
return 1;
|
||||
}
|
||||
embedded_options = args [++i];
|
||||
break;
|
||||
case "--runtime":
|
||||
if (i+1 == top){
|
||||
Help ();
|
||||
return 1;
|
||||
}
|
||||
runtime = args [++i];
|
||||
break;
|
||||
case "-oo":
|
||||
if (i+1 == top){
|
||||
Help ();
|
||||
@ -94,6 +166,7 @@ class MakeBundle {
|
||||
case "--keeptemp":
|
||||
keeptemp = true;
|
||||
break;
|
||||
|
||||
case "--static":
|
||||
static_link = true;
|
||||
if (!quiet) {
|
||||
@ -193,13 +266,60 @@ class MakeBundle {
|
||||
foreach (string file in assemblies)
|
||||
if (!QueueAssembly (files, file))
|
||||
return 1;
|
||||
|
||||
GenerateBundles (files);
|
||||
//GenerateJitWrapper ();
|
||||
|
||||
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 {
|
||||
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){
|
||||
@ -260,6 +380,138 @@ class MakeBundle {
|
||||
|
||||
ts.WriteLine ();
|
||||
}
|
||||
|
||||
class PackageMaker {
|
||||
Dictionary<string, Tuple<long,int>> locations = new Dictionary<string, Tuple<long,int>> ();
|
||||
const int align = 4096;
|
||||
Stream package;
|
||||
|
||||
public PackageMaker (string output)
|
||||
{
|
||||
package = File.Create (output, 128*1024);
|
||||
if (IsUnix){
|
||||
File.SetAttributes (output, unchecked ((FileAttributes) 0x80000000));
|
||||
}
|
||||
}
|
||||
|
||||
public int AddFile (string fname)
|
||||
{
|
||||
using (Stream fileStream = File.OpenRead (fname)){
|
||||
var ret = fileStream.Length;
|
||||
|
||||
Console.WriteLine ("At {0:x} with input {1}", package.Position, fileStream.Length);
|
||||
fileStream.CopyTo (package);
|
||||
package.Position = package.Position + (align - (package.Position % align));
|
||||
|
||||
return (int) ret;
|
||||
}
|
||||
}
|
||||
|
||||
public void Add (string entry, string fname)
|
||||
{
|
||||
var p = package.Position;
|
||||
var size = AddFile (fname);
|
||||
|
||||
locations [entry] = Tuple.Create(p, size);
|
||||
}
|
||||
|
||||
public void AddString (string entry, string text)
|
||||
{
|
||||
var bytes = Encoding.UTF8.GetBytes (text);
|
||||
locations [entry] = Tuple.Create (package.Position, bytes.Length);
|
||||
package.Write (bytes, 0, bytes.Length);
|
||||
package.Position = package.Position + (align - (package.Position % align));
|
||||
}
|
||||
|
||||
public void Dump ()
|
||||
{
|
||||
foreach (var floc in locations.Keys){
|
||||
Console.WriteLine ($"{floc} at {locations[floc]:x}");
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteIndex ()
|
||||
{
|
||||
var indexStart = package.Position;
|
||||
var binary = new BinaryWriter (package);
|
||||
|
||||
binary.Write (locations.Count);
|
||||
foreach (var entry in from entry in locations orderby entry.Value.Item1 ascending select entry){
|
||||
var bytes = Encoding.UTF8.GetBytes (entry.Key);
|
||||
binary.Write (bytes.Length+1);
|
||||
binary.Write (bytes);
|
||||
binary.Write ((byte) 0);
|
||||
binary.Write (entry.Value.Item1);
|
||||
binary.Write (entry.Value.Item2);
|
||||
}
|
||||
binary.Write (indexStart);
|
||||
binary.Write (Encoding.UTF8.GetBytes ("xmonkeysloveplay"));
|
||||
binary.Flush ();
|
||||
}
|
||||
|
||||
public void Close ()
|
||||
{
|
||||
WriteIndex ();
|
||||
package.Close ();
|
||||
package = null;
|
||||
}
|
||||
}
|
||||
|
||||
static bool MaybeAddFile (PackageMaker maker, string code, string file)
|
||||
{
|
||||
if (file == null)
|
||||
return true;
|
||||
|
||||
if (!File.Exists (file)){
|
||||
Console.Error.WriteLine ("The file {0} does not exist", file);
|
||||
return false;
|
||||
}
|
||||
maker.Add (code, file);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool GeneratePackage (List<string> files)
|
||||
{
|
||||
if (runtime == null){
|
||||
if (IsUnix)
|
||||
runtime = Process.GetCurrentProcess().MainModule.FileName;
|
||||
else {
|
||||
Console.Error.WriteLine ("You must specify at least one runtime with --runtime or --cross");
|
||||
Environment.Exit (1);
|
||||
}
|
||||
}
|
||||
if (!File.Exists (runtime)){
|
||||
Console.Error.WriteLine ($"The specified runtime at {runtime} does not exist");
|
||||
Environment.Exit (1);
|
||||
}
|
||||
|
||||
if (ctor_func != null){
|
||||
Console.Error.WriteLine ("--static-ctor not supported with package bundling, you must use native compilation for this");
|
||||
return false;
|
||||
}
|
||||
|
||||
var maker = new PackageMaker (output);
|
||||
maker.AddFile (runtime);
|
||||
|
||||
foreach (var url in files){
|
||||
string fname = LocateFile (new Uri (url).LocalPath);
|
||||
string aname = Path.GetFileName (fname);
|
||||
|
||||
maker.Add ("assembly:" + aname, fname);
|
||||
if (File.Exists (fname + ".config"))
|
||||
maker.Add ("config:" + aname, fname + ".config");
|
||||
}
|
||||
if (!MaybeAddFile (maker, "systemconfig:", config_file) || !MaybeAddFile (maker, "machineconfig:", machine_config_file))
|
||||
return false;
|
||||
|
||||
if (config_dir != null)
|
||||
maker.Add ("config_dir:", config_dir);
|
||||
if (embedded_options != null)
|
||||
maker.AddString ("options:", embedded_options);
|
||||
maker.Dump ();
|
||||
maker.Close ();
|
||||
return true;
|
||||
}
|
||||
|
||||
static void GenerateBundles (List<string> files)
|
||||
{
|
||||
@ -710,24 +962,34 @@ void mono_register_config_for_assembly (const char* assembly_name, cons
|
||||
{
|
||||
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" +
|
||||
" --config F Bundle system config file `F'\n" +
|
||||
" --config-dir D Set MONO_CFG_DIR to `D'\n" +
|
||||
" --deps Turns on automatic dependency embedding (default on simple)\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" +
|
||||
" --machine-config F Use the given file as the machine.config for the application.\n" +
|
||||
" -o out Specifies output filename\n" +
|
||||
" --nodeps Turns off automatic dependency embedding (default on custom)\n" +
|
||||
" --skip-scan Skip scanning assemblies that could not be loaded (but still embed them).\n" +
|
||||
"\n" +
|
||||
"--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 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" +
|
||||
" --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" +
|
||||
" -oo obj Specifies output filename for helper object file\n" +
|
||||
" --dos2unix[=true|false]\n" +
|
||||
" When no value provided, or when `true` specified\n" +
|
||||
" `dos2unix` will be invoked to convert paths on Windows.\n" +
|
||||
" When `--dos2unix=false` used, dos2unix is NEVER used.\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" +
|
||||
" --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" +
|
||||
" You need zlib development headers and libraries.\n");
|
||||
}
|
||||
|
Reference in New Issue
Block a user