[mtouch] Move mtouch's GenerateMain to shared Target code.
This means moving a lot of supporting code to shared code as well.
This commit is contained in:
Родитель
f513501443
Коммит
6240e848f3
|
@ -79,6 +79,8 @@ namespace Xamarin.Bundler {
|
|||
public bool IsExtension;
|
||||
public ApplePlatform Platform { get { return Driver.TargetFramework.Platform; } }
|
||||
|
||||
public List<string> InterpretedAssemblies = new List<string> ();
|
||||
|
||||
// Linker config
|
||||
public LinkMode LinkMode = LinkMode.Full;
|
||||
public List<string> LinkSkipped = new List<string> ();
|
||||
|
@ -112,6 +114,80 @@ namespace Xamarin.Bundler {
|
|||
public bool? DisableOmitFramePointer = null; // Only applicable to Xamarin.Mac
|
||||
public string CustomBundleName = "MonoBundle"; // Only applicable to Xamarin.Mac
|
||||
|
||||
public bool? UseMonoFramework;
|
||||
|
||||
public BitCodeMode BitCodeMode { get; set; }
|
||||
|
||||
public bool EnableAsmOnlyBitCode { get { return BitCodeMode == BitCodeMode.ASMOnly; } }
|
||||
public bool EnableLLVMOnlyBitCode { get { return BitCodeMode == BitCodeMode.LLVMOnly; } }
|
||||
public bool EnableMarkerOnlyBitCode { get { return BitCodeMode == BitCodeMode.MarkerOnly; } }
|
||||
public bool EnableBitCode { get { return BitCodeMode != BitCodeMode.None; } }
|
||||
|
||||
Dictionary<string, Tuple<AssemblyBuildTarget, string>> assembly_build_targets = new Dictionary<string, Tuple<AssemblyBuildTarget, string>> ();
|
||||
|
||||
public AssemblyBuildTarget LibMonoLinkMode {
|
||||
get {
|
||||
if (Embeddinator) {
|
||||
return AssemblyBuildTarget.StaticObject;
|
||||
} else if (HasFrameworks || UseMonoFramework.Value) {
|
||||
return AssemblyBuildTarget.Framework;
|
||||
} else if (HasDynamicLibraries) {
|
||||
return AssemblyBuildTarget.DynamicLibrary;
|
||||
} else {
|
||||
return AssemblyBuildTarget.StaticObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
public AssemblyBuildTarget LibXamarinLinkMode {
|
||||
get {
|
||||
if (Embeddinator) {
|
||||
return AssemblyBuildTarget.StaticObject;
|
||||
} else if (HasFrameworks) {
|
||||
return AssemblyBuildTarget.Framework;
|
||||
} else if (HasDynamicLibraries) {
|
||||
return AssemblyBuildTarget.DynamicLibrary;
|
||||
} else {
|
||||
return AssemblyBuildTarget.StaticObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
public AssemblyBuildTarget LibPInvokesLinkMode => LibXamarinLinkMode;
|
||||
public AssemblyBuildTarget LibProfilerLinkMode => OnlyStaticLibraries ? AssemblyBuildTarget.StaticObject : AssemblyBuildTarget.DynamicLibrary;
|
||||
public AssemblyBuildTarget LibMonoNativeLinkMode => HasDynamicLibraries ? AssemblyBuildTarget.DynamicLibrary : AssemblyBuildTarget.StaticObject;
|
||||
|
||||
public bool OnlyStaticLibraries {
|
||||
get {
|
||||
return assembly_build_targets.All ((abt) => abt.Value.Item1 == AssemblyBuildTarget.StaticObject);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasDynamicLibraries {
|
||||
get {
|
||||
return assembly_build_targets.Any ((abt) => abt.Value.Item1 == AssemblyBuildTarget.DynamicLibrary);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasFrameworks {
|
||||
get {
|
||||
return assembly_build_targets.Any ((abt) => abt.Value.Item1 == AssemblyBuildTarget.Framework);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasFrameworksDirectory {
|
||||
get {
|
||||
if (Platform == ApplePlatform.MacOSX)
|
||||
return false;
|
||||
|
||||
if (!IsExtension)
|
||||
return true;
|
||||
|
||||
if (IsWatchExtension && Platform == ApplePlatform.WatchOS)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool RequiresXcodeHeaders {
|
||||
get {
|
||||
switch (Platform) {
|
||||
|
@ -1108,5 +1184,49 @@ namespace Xamarin.Bundler {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsInterpreted (string assembly)
|
||||
{
|
||||
// IsAOTCompiled and IsInterpreted are not opposites: mscorlib.dll can be both.
|
||||
if (!UseInterpreter)
|
||||
return false;
|
||||
|
||||
// Go through the list of assemblies to interpret in reverse order,
|
||||
// so that the last option passed to mtouch takes precedence.
|
||||
for (int i = InterpretedAssemblies.Count - 1; i >= 0; i--) {
|
||||
var opt = InterpretedAssemblies [i];
|
||||
if (opt == "all")
|
||||
return true;
|
||||
else if (opt == "-all")
|
||||
return false;
|
||||
else if (opt == assembly)
|
||||
return true;
|
||||
else if (opt [0] == '-' && opt.Substring (1) == assembly)
|
||||
return false;
|
||||
}
|
||||
|
||||
// There's an implicit 'all' at the start of the list.
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsAOTCompiled (string assembly)
|
||||
{
|
||||
if (!UseInterpreter)
|
||||
return true;
|
||||
|
||||
// IsAOTCompiled and IsInterpreted are not opposites: mscorlib.dll can be both:
|
||||
// - mscorlib will always be processed by the AOT compiler to generate required wrapper functions for the interpreter to work
|
||||
// - mscorlib might also be fully AOT-compiled (both when the interpreter is enabled and when it's not)
|
||||
if (assembly == "mscorlib")
|
||||
return true;
|
||||
|
||||
return !IsInterpreted (assembly);
|
||||
}
|
||||
|
||||
public string AssemblyName {
|
||||
get {
|
||||
return Path.GetFileName (RootAssemblies [0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,9 @@ namespace Xamarin.Bundler {
|
|||
|
||||
public partial class Assembly
|
||||
{
|
||||
public AssemblyBuildTarget BuildTarget;
|
||||
public string BuildTargetName;
|
||||
public bool IsCodeShared;
|
||||
public List<string> Satellites;
|
||||
public Application App { get { return Target.App; } }
|
||||
|
||||
|
@ -722,6 +725,12 @@ namespace Xamarin.Bundler {
|
|||
Application.UpdateFile (config_src, config_target, true);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAOTCompiled {
|
||||
get {
|
||||
return App.IsAOTCompiled (Identity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class NormalizedStringComparer : IEqualityComparer<string>
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
namespace Xamarin.Bundler {
|
||||
public enum BitCodeMode {
|
||||
None = 0,
|
||||
ASMOnly = 1,
|
||||
LLVMOnly = 2,
|
||||
MarkerOnly = 3,
|
||||
}
|
||||
}
|
|
@ -559,5 +559,270 @@ namespace Xamarin.Bundler {
|
|||
return sb.ToString ();
|
||||
}
|
||||
|
||||
// note: this is executed under Parallel.ForEach
|
||||
public string GenerateIOSMain (Abi abi, string main_source, IList<string> registration_methods)
|
||||
{
|
||||
var app = App;
|
||||
var assemblies = Assemblies;
|
||||
var assembly_name = App.AssemblyName;
|
||||
var assembly_externs = new StringBuilder ();
|
||||
var assembly_aot_modules = new StringBuilder ();
|
||||
var register_assemblies = new StringBuilder ();
|
||||
var assembly_location = new StringBuilder ();
|
||||
var assembly_location_count = 0;
|
||||
var enable_llvm = (abi & Abi.LLVM) != 0;
|
||||
|
||||
register_assemblies.AppendLine ("\tguint32 exception_gchandle = 0;");
|
||||
foreach (var s in assemblies) {
|
||||
if (!s.IsAOTCompiled)
|
||||
continue;
|
||||
if ((abi & Abi.SimulatorArchMask) == 0) {
|
||||
var info = s.AssemblyDefinition.Name.Name;
|
||||
info = EncodeAotSymbol (info);
|
||||
assembly_externs.Append ("extern void *mono_aot_module_").Append (info).AppendLine ("_info;");
|
||||
assembly_aot_modules.Append ("\tmono_aot_register_module (mono_aot_module_").Append (info).AppendLine ("_info);");
|
||||
}
|
||||
string sname = s.FileName;
|
||||
if (assembly_name != sname && IsBoundAssembly (s)) {
|
||||
register_assemblies.Append ("\txamarin_open_and_register (\"").Append (sname).Append ("\", &exception_gchandle);").AppendLine ();
|
||||
register_assemblies.AppendLine ("\txamarin_process_managed_exception_gchandle (exception_gchandle);");
|
||||
}
|
||||
}
|
||||
|
||||
if ((abi & Abi.SimulatorArchMask) == 0 || app.Embeddinator) {
|
||||
var frameworks = assemblies.Where ((a) => a.BuildTarget == AssemblyBuildTarget.Framework)
|
||||
.OrderBy ((a) => a.Identity, StringComparer.Ordinal);
|
||||
foreach (var asm_fw in frameworks) {
|
||||
var asm_name = asm_fw.Identity;
|
||||
if (asm_fw.BuildTargetName == asm_name)
|
||||
continue; // this is deduceable
|
||||
var prefix = string.Empty;
|
||||
if (!app.HasFrameworksDirectory && asm_fw.IsCodeShared)
|
||||
prefix = "../../";
|
||||
var suffix = string.Empty;
|
||||
if (app.IsSimulatorBuild)
|
||||
suffix = "/simulator";
|
||||
assembly_location.AppendFormat ("\t{{ \"{0}\", \"{2}Frameworks/{1}.framework/MonoBundle{3}\" }},\n", asm_name, asm_fw.BuildTargetName, prefix, suffix);
|
||||
assembly_location_count++;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder ();
|
||||
using (var sw = new StringWriter (sb)) {
|
||||
sw.WriteLine ("#include \"xamarin/xamarin.h\"");
|
||||
|
||||
if (assembly_location.Length > 0) {
|
||||
sw.WriteLine ();
|
||||
sw.WriteLine ("struct AssemblyLocation assembly_location_entries [] = {");
|
||||
sw.WriteLine (assembly_location);
|
||||
sw.WriteLine ("};");
|
||||
|
||||
sw.WriteLine ();
|
||||
sw.WriteLine ("struct AssemblyLocations assembly_locations = {{ {0}, assembly_location_entries }};", assembly_location_count);
|
||||
}
|
||||
|
||||
sw.WriteLine ();
|
||||
sw.WriteLine (assembly_externs);
|
||||
|
||||
sw.WriteLine ("void xamarin_register_modules_impl ()");
|
||||
sw.WriteLine ("{");
|
||||
sw.WriteLine (assembly_aot_modules);
|
||||
sw.WriteLine ("}");
|
||||
sw.WriteLine ();
|
||||
|
||||
sw.WriteLine ("void xamarin_register_assemblies_impl ()");
|
||||
sw.WriteLine ("{");
|
||||
sw.WriteLine (register_assemblies);
|
||||
sw.WriteLine ("}");
|
||||
sw.WriteLine ();
|
||||
|
||||
if (registration_methods != null) {
|
||||
foreach (var method in registration_methods) {
|
||||
sw.Write ("extern \"C\" void ");
|
||||
sw.Write (method);
|
||||
sw.WriteLine ("();");
|
||||
}
|
||||
}
|
||||
|
||||
// Burn in a reference to the profiling symbol so that the native linker doesn't remove it
|
||||
// On iOS we can pass -u to the native linker, but that doesn't work on tvOS, where
|
||||
// we're building with bitcode (even when bitcode is disabled, we still build with the
|
||||
// bitcode marker, which makes the linker reject -u).
|
||||
if (app.EnableProfiling) {
|
||||
sw.WriteLine ("extern \"C\" { void mono_profiler_init_log (); }");
|
||||
sw.WriteLine ("typedef void (*xamarin_profiler_symbol_def)();");
|
||||
sw.WriteLine ("extern xamarin_profiler_symbol_def xamarin_profiler_symbol;");
|
||||
sw.WriteLine ("xamarin_profiler_symbol_def xamarin_profiler_symbol = NULL;");
|
||||
}
|
||||
|
||||
if (app.UseInterpreter) {
|
||||
sw.WriteLine ("extern \"C\" { void mono_ee_interp_init (const char *); }");
|
||||
sw.WriteLine ("extern \"C\" { void mono_icall_table_init (void); }");
|
||||
sw.WriteLine ("extern \"C\" { void mono_marshal_ilgen_init (void); }");
|
||||
sw.WriteLine ("extern \"C\" { void mono_method_builder_ilgen_init (void); }");
|
||||
sw.WriteLine ("extern \"C\" { void mono_sgen_mono_ilgen_init (void); }");
|
||||
}
|
||||
|
||||
sw.WriteLine ("void xamarin_setup_impl ()");
|
||||
sw.WriteLine ("{");
|
||||
|
||||
if (app.EnableProfiling)
|
||||
sw.WriteLine ("\txamarin_profiler_symbol = mono_profiler_init_log;");
|
||||
|
||||
if (app.EnableLLVMOnlyBitCode)
|
||||
sw.WriteLine ("\tmono_jit_set_aot_mode (MONO_AOT_MODE_LLVMONLY);");
|
||||
else if (app.UseInterpreter) {
|
||||
sw.WriteLine ("\tmono_icall_table_init ();");
|
||||
sw.WriteLine ("\tmono_marshal_ilgen_init ();");
|
||||
sw.WriteLine ("\tmono_method_builder_ilgen_init ();");
|
||||
sw.WriteLine ("\tmono_sgen_mono_ilgen_init ();");
|
||||
sw.WriteLine ("\tmono_ee_interp_init (NULL);");
|
||||
sw.WriteLine ("\tmono_jit_set_aot_mode (MONO_AOT_MODE_INTERP);");
|
||||
} else if (app.IsDeviceBuild)
|
||||
sw.WriteLine ("\tmono_jit_set_aot_mode (MONO_AOT_MODE_FULL);");
|
||||
|
||||
if (assembly_location.Length > 0)
|
||||
sw.WriteLine ("\txamarin_set_assembly_directories (&assembly_locations);");
|
||||
|
||||
if (registration_methods != null) {
|
||||
for (int i = 0; i < registration_methods.Count; i++) {
|
||||
sw.Write ("\t");
|
||||
sw.Write (registration_methods [i]);
|
||||
sw.WriteLine ("();");
|
||||
}
|
||||
}
|
||||
|
||||
if (app.MonoNativeMode != MonoNativeMode.None) {
|
||||
string mono_native_lib;
|
||||
if (app.LibMonoNativeLinkMode == AssemblyBuildTarget.StaticObject)
|
||||
mono_native_lib = "__Internal";
|
||||
else
|
||||
mono_native_lib = app.GetLibNativeName () + ".dylib";
|
||||
sw.WriteLine ();
|
||||
sw.WriteLine ($"\tmono_dllmap_insert (NULL, \"System.Native\", NULL, \"{mono_native_lib}\", NULL);");
|
||||
sw.WriteLine ($"\tmono_dllmap_insert (NULL, \"System.Security.Cryptography.Native.Apple\", NULL, \"{mono_native_lib}\", NULL);");
|
||||
sw.WriteLine ($"\tmono_dllmap_insert (NULL, \"System.Net.Security.Native\", NULL, \"{mono_native_lib}\", NULL);");
|
||||
sw.WriteLine ();
|
||||
}
|
||||
|
||||
if (app.EnableDebug)
|
||||
sw.WriteLine ("\txamarin_gc_pump = {0};", app.DebugTrack.Value ? "TRUE" : "FALSE");
|
||||
sw.WriteLine ("\txamarin_init_mono_debug = {0};", app.PackageManagedDebugSymbols ? "TRUE" : "FALSE");
|
||||
sw.WriteLine ("\txamarin_executable_name = \"{0}\";", assembly_name);
|
||||
sw.WriteLine ("\tmono_use_llvm = {0};", enable_llvm ? "TRUE" : "FALSE");
|
||||
sw.WriteLine ("\txamarin_log_level = {0};", Driver.Verbosity.ToString (CultureInfo.InvariantCulture));
|
||||
sw.WriteLine ("\txamarin_arch_name = \"{0}\";", abi.AsArchString ());
|
||||
if (!app.IsDefaultMarshalManagedExceptionMode)
|
||||
sw.WriteLine ("\txamarin_marshal_managed_exception_mode = MarshalManagedExceptionMode{0};", app.MarshalManagedExceptions);
|
||||
sw.WriteLine ("\txamarin_marshal_objectivec_exception_mode = MarshalObjectiveCExceptionMode{0};", app.MarshalObjectiveCExceptions);
|
||||
if (app.EnableDebug)
|
||||
sw.WriteLine ("\txamarin_debug_mode = TRUE;");
|
||||
if (!string.IsNullOrEmpty (app.MonoGCParams))
|
||||
sw.WriteLine ("\tsetenv (\"MONO_GC_PARAMS\", \"{0}\", 1);", app.MonoGCParams);
|
||||
foreach (var kvp in app.EnvironmentVariables)
|
||||
sw.WriteLine ("\tsetenv (\"{0}\", \"{1}\", 1);", kvp.Key.Replace ("\"", "\\\""), kvp.Value.Replace ("\"", "\\\""));
|
||||
sw.WriteLine ("\txamarin_supports_dynamic_registration = {0};", app.DynamicRegistrationSupported ? "TRUE" : "FALSE");
|
||||
sw.WriteLine ("}");
|
||||
sw.WriteLine ();
|
||||
sw.Write ("int ");
|
||||
sw.Write (app.IsWatchExtension ? "xamarin_watchextension_main" : "main");
|
||||
sw.WriteLine (" (int argc, char **argv)");
|
||||
sw.WriteLine ("{");
|
||||
sw.WriteLine ("\tNSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];");
|
||||
if (app.IsExtension) {
|
||||
// the name of the executable must be the bundle id (reverse dns notation)
|
||||
// but we do not want to impose that (ugly) restriction to the managed .exe / project name / ...
|
||||
sw.WriteLine ("\targv [0] = (char *) \"{0}\";", Path.GetFileNameWithoutExtension (app.RootAssemblies [0]));
|
||||
sw.WriteLine ("\tint rv = xamarin_main (argc, argv, XamarinLaunchModeExtension);");
|
||||
} else {
|
||||
sw.WriteLine ("\tint rv = xamarin_main (argc, argv, XamarinLaunchModeApp);");
|
||||
}
|
||||
sw.WriteLine ("\t[pool drain];");
|
||||
sw.WriteLine ("\treturn rv;");
|
||||
sw.WriteLine ("}");
|
||||
|
||||
string extension_main = null;
|
||||
if (app.Platform == ApplePlatform.WatchOS && app.IsWatchExtension) {
|
||||
// We're building a watch extension, and we have multiple scenarios, depending on the watchOS version we're executing on:
|
||||
//
|
||||
// * watchOS 2.0 -> 5.*: we must call a `main` function provided in the WatchKit framework.
|
||||
// * watchOS 6.0 -> * : we must call a `WKExtensionMain` function provided in the WatchKit framework.
|
||||
// * watchOS 7.0 -> * : The `WKExtensionMain` function uses dlsym to find any `main` functions in the
|
||||
// main executable, and calls that function (otherwise WKExtensionMain will call
|
||||
// UIApplicationMain and normal startup occurs)
|
||||
//
|
||||
// * We can't call our entry point "main", because we call WKExtensionMain, and then we run into an
|
||||
// infinite loop on watchOS 7.0. So we call it xamarin_watch_extension_main.
|
||||
// * The watchOS 6+ SDK helpfully provides a static library (WKExtensionMainLegacy) that has a
|
||||
// WKExtensionMain function, which we use when the deployment target is earlier than watchOS 6.0.
|
||||
// This means that calling WKExtensionMain works everywhere (as long as we're using the
|
||||
// watchOS 6+ SDK to build; otherwise we just call "main" directly and don't link with the
|
||||
// WKExtensionMainLegacy library)
|
||||
|
||||
if (app.SdkVersion.Major >= 6) {
|
||||
extension_main = "WKExtensionMain";
|
||||
} else {
|
||||
extension_main = "main";
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty (extension_main)) {
|
||||
sw.WriteLine ($"extern \"C\" {{ int {extension_main} (int argc, char* argv[]); }}");
|
||||
sw.WriteLine ();
|
||||
}
|
||||
|
||||
sw.WriteLine ();
|
||||
sw.WriteLine ("void xamarin_initialize_callbacks () __attribute__ ((constructor));");
|
||||
sw.WriteLine ("void xamarin_initialize_callbacks ()");
|
||||
sw.WriteLine ("{");
|
||||
sw.WriteLine ("\txamarin_setup = xamarin_setup_impl;");
|
||||
sw.WriteLine ("\txamarin_register_assemblies = xamarin_register_assemblies_impl;");
|
||||
sw.WriteLine ("\txamarin_register_modules = xamarin_register_modules_impl;");
|
||||
if (!string.IsNullOrEmpty (extension_main))
|
||||
sw.WriteLine ($"\txamarin_extension_main = {extension_main};");
|
||||
sw.WriteLine ("}");
|
||||
}
|
||||
Driver.WriteIfDifferent (main_source, sb.ToString (), true);
|
||||
} catch (ProductException) {
|
||||
throw;
|
||||
} catch (Exception e) {
|
||||
throw new ProductException (4001, true, e, Errors.MT4001, main_source);
|
||||
}
|
||||
|
||||
return main_source;
|
||||
}
|
||||
|
||||
static string EncodeAotSymbol (string symbol)
|
||||
{
|
||||
var sb = new StringBuilder ();
|
||||
/* This mimics what the aot-compiler does */
|
||||
foreach (var b in System.Text.Encoding.UTF8.GetBytes (symbol)) {
|
||||
char c = (char) b;
|
||||
if ((c >= '0' && c <= '9') ||
|
||||
(c >= 'a' && c <= 'z') ||
|
||||
(c >= 'A' && c <= 'Z')) {
|
||||
sb.Append (c);
|
||||
continue;
|
||||
}
|
||||
sb.Append ('_');
|
||||
}
|
||||
return sb.ToString ();
|
||||
}
|
||||
|
||||
static bool IsBoundAssembly (Assembly s)
|
||||
{
|
||||
if (s.IsFrameworkAssembly == true)
|
||||
return false;
|
||||
|
||||
AssemblyDefinition ad = s.AssemblyDefinition;
|
||||
|
||||
foreach (ModuleDefinition md in ad.Modules)
|
||||
foreach (TypeDefinition td in md.Types)
|
||||
if (td.IsNSObject (s.Target.LinkContext))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,14 +57,6 @@ namespace Xamarin.Bundler {
|
|||
Driver.Log (1, $"Registrar mode: {Registrar}");
|
||||
}
|
||||
|
||||
public AssemblyBuildTarget LibMonoLinkMode {
|
||||
get { throw new NotImplementedException (); }
|
||||
}
|
||||
|
||||
public AssemblyBuildTarget LibXamarinLinkMode {
|
||||
get { throw new NotImplementedException (); }
|
||||
}
|
||||
|
||||
public bool HasAnyDynamicLibraries {
|
||||
get { throw new NotImplementedException (); }
|
||||
}
|
||||
|
|
|
@ -182,6 +182,9 @@
|
|||
<Compile Include="..\..\external\Xamarin.MacDev\Xamarin.MacDev\PListObject.cs">
|
||||
<Link>external\Xamarin.MacDev\Xamarin.MacDev\PListObject.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\common\BitCodeMode.cs">
|
||||
<Link>external\tools\common\BitCodeMode.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="..\mtouch\Errors.resx">
|
||||
|
|
|
@ -455,6 +455,12 @@
|
|||
<Compile Include="..\mtouch\Stripper.cs">
|
||||
<Link>external\tools\mtouch\Stripper.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\common\AssemblyBuildTarget.cs">
|
||||
<Link>tools\common\AssemblyBuildTarget.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\common\BitCodeMode.cs">
|
||||
<Link>tools\common\BitCodeMode.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ItemGroup>
|
||||
|
|
|
@ -17,13 +17,6 @@ using Xamarin.Utils;
|
|||
|
||||
namespace Xamarin.Bundler {
|
||||
|
||||
public enum BitCodeMode {
|
||||
None = 0,
|
||||
ASMOnly = 1,
|
||||
LLVMOnly = 2,
|
||||
MarkerOnly = 3,
|
||||
}
|
||||
|
||||
public enum DlsymOptions
|
||||
{
|
||||
Default,
|
||||
|
@ -57,7 +50,6 @@ namespace Xamarin.Bundler {
|
|||
|
||||
public DlsymOptions DlsymOptions;
|
||||
public List<Tuple<string, bool>> DlsymAssemblies;
|
||||
public bool? UseMonoFramework;
|
||||
public bool? PackageMonoFramework;
|
||||
|
||||
public bool NoFastSim;
|
||||
|
@ -69,7 +61,6 @@ namespace Xamarin.Bundler {
|
|||
public List<string> AotOtherArguments = null;
|
||||
public bool? LLVMAsmWriter;
|
||||
public Dictionary<string, string> LLVMOptimizations = new Dictionary<string, string> ();
|
||||
public List<string> InterpretedAssemblies = new List<string> ();
|
||||
|
||||
//
|
||||
// Linker config
|
||||
|
@ -80,44 +71,6 @@ namespace Xamarin.Bundler {
|
|||
|
||||
public bool? BuildDSym;
|
||||
|
||||
public bool IsInterpreted (string assembly)
|
||||
{
|
||||
// IsAOTCompiled and IsInterpreted are not opposites: mscorlib.dll can be both.
|
||||
if (!UseInterpreter)
|
||||
return false;
|
||||
|
||||
// Go through the list of assemblies to interpret in reverse order,
|
||||
// so that the last option passed to mtouch takes precedence.
|
||||
for (int i = InterpretedAssemblies.Count - 1; i >= 0; i--) {
|
||||
var opt = InterpretedAssemblies [i];
|
||||
if (opt == "all")
|
||||
return true;
|
||||
else if (opt == "-all")
|
||||
return false;
|
||||
else if (opt == assembly)
|
||||
return true;
|
||||
else if (opt [0] == '-' && opt.Substring (1) == assembly)
|
||||
return false;
|
||||
}
|
||||
|
||||
// There's an implicit 'all' at the start of the list.
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsAOTCompiled (string assembly)
|
||||
{
|
||||
if (!UseInterpreter)
|
||||
return true;
|
||||
|
||||
// IsAOTCompiled and IsInterpreted are not opposites: mscorlib.dll can be both:
|
||||
// - mscorlib will always be processed by the AOT compiler to generate required wrapper functions for the interpreter to work
|
||||
// - mscorlib might also be fully AOT-compiled (both when the interpreter is enabled and when it's not)
|
||||
if (assembly == "mscorlib")
|
||||
return true;
|
||||
|
||||
return !IsInterpreted (assembly);
|
||||
}
|
||||
|
||||
public List<string> UserGccFlags;
|
||||
|
||||
// If we didn't link the final executable because the existing binary is up-to-date.
|
||||
|
@ -136,52 +89,8 @@ namespace Xamarin.Bundler {
|
|||
BuildTasks build_tasks;
|
||||
BuildTask final_build_task; // either lipo or file copy (to final destination)
|
||||
|
||||
Dictionary<string, Tuple<AssemblyBuildTarget, string>> assembly_build_targets = new Dictionary<string, Tuple<AssemblyBuildTarget, string>> ();
|
||||
|
||||
public AssemblyBuildTarget LibMonoLinkMode {
|
||||
get {
|
||||
if (Embeddinator) {
|
||||
return AssemblyBuildTarget.StaticObject;
|
||||
} else if (HasFrameworks || UseMonoFramework.Value) {
|
||||
return AssemblyBuildTarget.Framework;
|
||||
} else if (HasDynamicLibraries) {
|
||||
return AssemblyBuildTarget.DynamicLibrary;
|
||||
} else {
|
||||
return AssemblyBuildTarget.StaticObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
public AssemblyBuildTarget LibXamarinLinkMode {
|
||||
get {
|
||||
if (Embeddinator) {
|
||||
return AssemblyBuildTarget.StaticObject;
|
||||
} else if (HasFrameworks) {
|
||||
return AssemblyBuildTarget.Framework;
|
||||
} else if (HasDynamicLibraries) {
|
||||
return AssemblyBuildTarget.DynamicLibrary;
|
||||
} else {
|
||||
return AssemblyBuildTarget.StaticObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
public AssemblyBuildTarget LibPInvokesLinkMode => LibXamarinLinkMode;
|
||||
public AssemblyBuildTarget LibProfilerLinkMode => OnlyStaticLibraries ? AssemblyBuildTarget.StaticObject : AssemblyBuildTarget.DynamicLibrary;
|
||||
public AssemblyBuildTarget LibMonoNativeLinkMode => HasDynamicLibraries ? AssemblyBuildTarget.DynamicLibrary : AssemblyBuildTarget.StaticObject;
|
||||
|
||||
Dictionary<string, BundleFileInfo> bundle_files = new Dictionary<string, BundleFileInfo> ();
|
||||
|
||||
public bool OnlyStaticLibraries {
|
||||
get {
|
||||
return assembly_build_targets.All ((abt) => abt.Value.Item1 == AssemblyBuildTarget.StaticObject);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasDynamicLibraries {
|
||||
get {
|
||||
return assembly_build_targets.Any ((abt) => abt.Value.Item1 == AssemblyBuildTarget.DynamicLibrary);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasAnyDynamicLibraries {
|
||||
get {
|
||||
if (LibMonoLinkMode == AssemblyBuildTarget.DynamicLibrary)
|
||||
|
@ -198,12 +107,6 @@ namespace Xamarin.Bundler {
|
|||
}
|
||||
}
|
||||
|
||||
public bool HasFrameworks {
|
||||
get {
|
||||
return assembly_build_targets.Any ((abt) => abt.Value.Item1 == AssemblyBuildTarget.Framework);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearAssemblyBuildTargets ()
|
||||
{
|
||||
assembly_build_targets.Clear ();
|
||||
|
@ -455,13 +358,6 @@ namespace Xamarin.Bundler {
|
|||
}
|
||||
}
|
||||
|
||||
public BitCodeMode BitCodeMode { get; set; }
|
||||
|
||||
public bool EnableAsmOnlyBitCode { get { return BitCodeMode == BitCodeMode.ASMOnly; } }
|
||||
public bool EnableLLVMOnlyBitCode { get { return BitCodeMode == BitCodeMode.LLVMOnly; } }
|
||||
public bool EnableMarkerOnlyBitCode { get { return BitCodeMode == BitCodeMode.MarkerOnly; } }
|
||||
public bool EnableBitCode { get { return BitCodeMode != BitCodeMode.None; } }
|
||||
|
||||
public ICollection<Abi> AllArchitectures {
|
||||
get {
|
||||
if (all_architectures == null) {
|
||||
|
@ -477,19 +373,6 @@ namespace Xamarin.Bundler {
|
|||
}
|
||||
}
|
||||
|
||||
public bool HasFrameworksDirectory {
|
||||
get {
|
||||
if (!IsExtension)
|
||||
return true;
|
||||
|
||||
if (IsWatchExtension && Platform == ApplePlatform.WatchOS)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public string BundleId {
|
||||
get {
|
||||
return GetStringFromInfoPList ("CFBundleIdentifier");
|
||||
|
@ -1125,12 +1008,6 @@ namespace Xamarin.Bundler {
|
|||
return rv;
|
||||
}
|
||||
|
||||
public string AssemblyName {
|
||||
get {
|
||||
return Path.GetFileName (RootAssemblies [0]);
|
||||
}
|
||||
}
|
||||
|
||||
public string Executable {
|
||||
get {
|
||||
if (Embeddinator)
|
||||
|
|
|
@ -23,9 +23,6 @@ namespace Xamarin.Bundler {
|
|||
|
||||
public partial class Assembly
|
||||
{
|
||||
public AssemblyBuildTarget BuildTarget;
|
||||
public string BuildTargetName;
|
||||
public bool IsCodeShared;
|
||||
public bool BundleInContainerApp;
|
||||
|
||||
public Dictionary<Abi, AotInfo> AotInfos = new Dictionary<Abi, AotInfo> ();
|
||||
|
@ -45,12 +42,6 @@ namespace Xamarin.Bundler {
|
|||
}
|
||||
}
|
||||
|
||||
public bool IsAOTCompiled {
|
||||
get {
|
||||
return App.IsAOTCompiled (Identity);
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively list all the assemblies the specified assembly depends on.
|
||||
HashSet<string> ComputeDependencies (List<Exception> warnings)
|
||||
{
|
||||
|
|
|
@ -83,7 +83,7 @@ namespace Xamarin.Bundler
|
|||
|
||||
protected override void Execute ()
|
||||
{
|
||||
Driver.GenerateMain (Target, Target.Assemblies, Target.App.AssemblyName, Abi, MainM, RegistrationMethods);
|
||||
Target.GenerateIOSMain (Abi, MainM, RegistrationMethods);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -294,255 +294,6 @@ namespace Xamarin.Bundler
|
|||
return args;
|
||||
}
|
||||
|
||||
static string EncodeAotSymbol (string symbol)
|
||||
{
|
||||
var sb = new StringBuilder ();
|
||||
/* This mimics what the aot-compiler does */
|
||||
foreach (var b in System.Text.Encoding.UTF8.GetBytes (symbol)) {
|
||||
char c = (char) b;
|
||||
if ((c >= '0' && c <= '9') ||
|
||||
(c >= 'a' && c <= 'z') ||
|
||||
(c >= 'A' && c <= 'Z')) {
|
||||
sb.Append (c);
|
||||
continue;
|
||||
}
|
||||
sb.Append ('_');
|
||||
}
|
||||
return sb.ToString ();
|
||||
}
|
||||
|
||||
// note: this is executed under Parallel.ForEach
|
||||
public static string GenerateMain (Target target, IEnumerable<Assembly> assemblies, string assembly_name, Abi abi, string main_source, IList<string> registration_methods)
|
||||
{
|
||||
var app = target.App;
|
||||
var assembly_externs = new StringBuilder ();
|
||||
var assembly_aot_modules = new StringBuilder ();
|
||||
var register_assemblies = new StringBuilder ();
|
||||
var assembly_location = new StringBuilder ();
|
||||
var assembly_location_count = 0;
|
||||
var enable_llvm = (abi & Abi.LLVM) != 0;
|
||||
|
||||
register_assemblies.AppendLine ("\tguint32 exception_gchandle = 0;");
|
||||
foreach (var s in assemblies) {
|
||||
if (!s.IsAOTCompiled)
|
||||
continue;
|
||||
if ((abi & Abi.SimulatorArchMask) == 0) {
|
||||
var info = s.AssemblyDefinition.Name.Name;
|
||||
info = EncodeAotSymbol (info);
|
||||
assembly_externs.Append ("extern void *mono_aot_module_").Append (info).AppendLine ("_info;");
|
||||
assembly_aot_modules.Append ("\tmono_aot_register_module (mono_aot_module_").Append (info).AppendLine ("_info);");
|
||||
}
|
||||
string sname = s.FileName;
|
||||
if (assembly_name != sname && IsBoundAssembly (s)) {
|
||||
register_assemblies.Append ("\txamarin_open_and_register (\"").Append (sname).Append ("\", &exception_gchandle);").AppendLine ();
|
||||
register_assemblies.AppendLine ("\txamarin_process_managed_exception_gchandle (exception_gchandle);");
|
||||
}
|
||||
}
|
||||
|
||||
if ((abi & Abi.SimulatorArchMask) == 0 || app.Embeddinator) {
|
||||
var frameworks = assemblies.Where ((a) => a.BuildTarget == AssemblyBuildTarget.Framework)
|
||||
.OrderBy ((a) => a.Identity, StringComparer.Ordinal);
|
||||
foreach (var asm_fw in frameworks) {
|
||||
var asm_name = asm_fw.Identity;
|
||||
if (asm_fw.BuildTargetName == asm_name)
|
||||
continue; // this is deduceable
|
||||
var prefix = string.Empty;
|
||||
if (!app.HasFrameworksDirectory && asm_fw.IsCodeShared)
|
||||
prefix = "../../";
|
||||
var suffix = string.Empty;
|
||||
if (app.IsSimulatorBuild)
|
||||
suffix = "/simulator";
|
||||
assembly_location.AppendFormat ("\t{{ \"{0}\", \"{2}Frameworks/{1}.framework/MonoBundle{3}\" }},\n", asm_name, asm_fw.BuildTargetName, prefix, suffix);
|
||||
assembly_location_count++;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder ();
|
||||
using (var sw = new StringWriter (sb)) {
|
||||
sw.WriteLine ("#include \"xamarin/xamarin.h\"");
|
||||
|
||||
if (assembly_location.Length > 0) {
|
||||
sw.WriteLine ();
|
||||
sw.WriteLine ("struct AssemblyLocation assembly_location_entries [] = {");
|
||||
sw.WriteLine (assembly_location);
|
||||
sw.WriteLine ("};");
|
||||
|
||||
sw.WriteLine ();
|
||||
sw.WriteLine ("struct AssemblyLocations assembly_locations = {{ {0}, assembly_location_entries }};", assembly_location_count);
|
||||
}
|
||||
|
||||
sw.WriteLine ();
|
||||
sw.WriteLine (assembly_externs);
|
||||
|
||||
sw.WriteLine ("void xamarin_register_modules_impl ()");
|
||||
sw.WriteLine ("{");
|
||||
sw.WriteLine (assembly_aot_modules);
|
||||
sw.WriteLine ("}");
|
||||
sw.WriteLine ();
|
||||
|
||||
sw.WriteLine ("void xamarin_register_assemblies_impl ()");
|
||||
sw.WriteLine ("{");
|
||||
sw.WriteLine (register_assemblies);
|
||||
sw.WriteLine ("}");
|
||||
sw.WriteLine ();
|
||||
|
||||
if (registration_methods != null) {
|
||||
foreach (var method in registration_methods) {
|
||||
sw.Write ("extern \"C\" void ");
|
||||
sw.Write (method);
|
||||
sw.WriteLine ("();");
|
||||
}
|
||||
}
|
||||
|
||||
// Burn in a reference to the profiling symbol so that the native linker doesn't remove it
|
||||
// On iOS we can pass -u to the native linker, but that doesn't work on tvOS, where
|
||||
// we're building with bitcode (even when bitcode is disabled, we still build with the
|
||||
// bitcode marker, which makes the linker reject -u).
|
||||
if (app.EnableProfiling) {
|
||||
sw.WriteLine ("extern \"C\" { void mono_profiler_init_log (); }");
|
||||
sw.WriteLine ("typedef void (*xamarin_profiler_symbol_def)();");
|
||||
sw.WriteLine ("extern xamarin_profiler_symbol_def xamarin_profiler_symbol;");
|
||||
sw.WriteLine ("xamarin_profiler_symbol_def xamarin_profiler_symbol = NULL;");
|
||||
}
|
||||
|
||||
if (app.UseInterpreter) {
|
||||
sw.WriteLine ("extern \"C\" { void mono_ee_interp_init (const char *); }");
|
||||
sw.WriteLine ("extern \"C\" { void mono_icall_table_init (void); }");
|
||||
sw.WriteLine ("extern \"C\" { void mono_marshal_ilgen_init (void); }");
|
||||
sw.WriteLine ("extern \"C\" { void mono_method_builder_ilgen_init (void); }");
|
||||
sw.WriteLine ("extern \"C\" { void mono_sgen_mono_ilgen_init (void); }");
|
||||
}
|
||||
|
||||
sw.WriteLine ("void xamarin_setup_impl ()");
|
||||
sw.WriteLine ("{");
|
||||
|
||||
if (app.EnableProfiling)
|
||||
sw.WriteLine ("\txamarin_profiler_symbol = mono_profiler_init_log;");
|
||||
|
||||
if (app.EnableLLVMOnlyBitCode)
|
||||
sw.WriteLine ("\tmono_jit_set_aot_mode (MONO_AOT_MODE_LLVMONLY);");
|
||||
else if (app.UseInterpreter) {
|
||||
sw.WriteLine ("\tmono_icall_table_init ();");
|
||||
sw.WriteLine ("\tmono_marshal_ilgen_init ();");
|
||||
sw.WriteLine ("\tmono_method_builder_ilgen_init ();");
|
||||
sw.WriteLine ("\tmono_sgen_mono_ilgen_init ();");
|
||||
sw.WriteLine ("\tmono_ee_interp_init (NULL);");
|
||||
sw.WriteLine ("\tmono_jit_set_aot_mode (MONO_AOT_MODE_INTERP);");
|
||||
} else if (app.IsDeviceBuild)
|
||||
sw.WriteLine ("\tmono_jit_set_aot_mode (MONO_AOT_MODE_FULL);");
|
||||
|
||||
if (assembly_location.Length > 0)
|
||||
sw.WriteLine ("\txamarin_set_assembly_directories (&assembly_locations);");
|
||||
|
||||
if (registration_methods != null) {
|
||||
for (int i = 0; i < registration_methods.Count; i++) {
|
||||
sw.Write ("\t");
|
||||
sw.Write (registration_methods [i]);
|
||||
sw.WriteLine ("();");
|
||||
}
|
||||
}
|
||||
|
||||
if (app.MonoNativeMode != MonoNativeMode.None) {
|
||||
string mono_native_lib;
|
||||
if (app.LibMonoNativeLinkMode == AssemblyBuildTarget.StaticObject)
|
||||
mono_native_lib = "__Internal";
|
||||
else
|
||||
mono_native_lib = app.GetLibNativeName () + ".dylib";
|
||||
sw.WriteLine ();
|
||||
sw.WriteLine ($"\tmono_dllmap_insert (NULL, \"System.Native\", NULL, \"{mono_native_lib}\", NULL);");
|
||||
sw.WriteLine ($"\tmono_dllmap_insert (NULL, \"System.Security.Cryptography.Native.Apple\", NULL, \"{mono_native_lib}\", NULL);");
|
||||
sw.WriteLine ($"\tmono_dllmap_insert (NULL, \"System.Net.Security.Native\", NULL, \"{mono_native_lib}\", NULL);");
|
||||
sw.WriteLine ();
|
||||
}
|
||||
|
||||
if (app.EnableDebug)
|
||||
sw.WriteLine ("\txamarin_gc_pump = {0};", app.DebugTrack.Value ? "TRUE" : "FALSE");
|
||||
sw.WriteLine ("\txamarin_init_mono_debug = {0};", app.PackageManagedDebugSymbols ? "TRUE" : "FALSE");
|
||||
sw.WriteLine ("\txamarin_executable_name = \"{0}\";", assembly_name);
|
||||
sw.WriteLine ("\tmono_use_llvm = {0};", enable_llvm ? "TRUE" : "FALSE");
|
||||
sw.WriteLine ("\txamarin_log_level = {0};", Verbosity.ToString (CultureInfo.InvariantCulture));
|
||||
sw.WriteLine ("\txamarin_arch_name = \"{0}\";", abi.AsArchString ());
|
||||
if (!app.IsDefaultMarshalManagedExceptionMode)
|
||||
sw.WriteLine ("\txamarin_marshal_managed_exception_mode = MarshalManagedExceptionMode{0};", app.MarshalManagedExceptions);
|
||||
sw.WriteLine ("\txamarin_marshal_objectivec_exception_mode = MarshalObjectiveCExceptionMode{0};", app.MarshalObjectiveCExceptions);
|
||||
if (app.EnableDebug)
|
||||
sw.WriteLine ("\txamarin_debug_mode = TRUE;");
|
||||
if (!string.IsNullOrEmpty (app.MonoGCParams))
|
||||
sw.WriteLine ("\tsetenv (\"MONO_GC_PARAMS\", \"{0}\", 1);", app.MonoGCParams);
|
||||
foreach (var kvp in app.EnvironmentVariables)
|
||||
sw.WriteLine ("\tsetenv (\"{0}\", \"{1}\", 1);", kvp.Key.Replace ("\"", "\\\""), kvp.Value.Replace ("\"", "\\\""));
|
||||
sw.WriteLine ("\txamarin_supports_dynamic_registration = {0};", app.DynamicRegistrationSupported ? "TRUE" : "FALSE");
|
||||
sw.WriteLine ("}");
|
||||
sw.WriteLine ();
|
||||
sw.Write ("int ");
|
||||
sw.Write (app.IsWatchExtension ? "xamarin_watchextension_main" : "main");
|
||||
sw.WriteLine (" (int argc, char **argv)");
|
||||
sw.WriteLine ("{");
|
||||
sw.WriteLine ("\tNSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];");
|
||||
if (app.IsExtension) {
|
||||
// the name of the executable must be the bundle id (reverse dns notation)
|
||||
// but we do not want to impose that (ugly) restriction to the managed .exe / project name / ...
|
||||
sw.WriteLine ("\targv [0] = (char *) \"{0}\";", Path.GetFileNameWithoutExtension (app.RootAssemblies [0]));
|
||||
sw.WriteLine ("\tint rv = xamarin_main (argc, argv, XamarinLaunchModeExtension);");
|
||||
} else {
|
||||
sw.WriteLine ("\tint rv = xamarin_main (argc, argv, XamarinLaunchModeApp);");
|
||||
}
|
||||
sw.WriteLine ("\t[pool drain];");
|
||||
sw.WriteLine ("\treturn rv;");
|
||||
sw.WriteLine ("}");
|
||||
|
||||
string extension_main = null;
|
||||
if (app.Platform == ApplePlatform.WatchOS && app.IsWatchExtension) {
|
||||
// We're building a watch extension, and we have multiple scenarios, depending on the watchOS version we're executing on:
|
||||
//
|
||||
// * watchOS 2.0 -> 5.*: we must call a `main` function provided in the WatchKit framework.
|
||||
// * watchOS 6.0 -> * : we must call a `WKExtensionMain` function provided in the WatchKit framework.
|
||||
// * watchOS 7.0 -> * : The `WKExtensionMain` function uses dlsym to find any `main` functions in the
|
||||
// main executable, and calls that function (otherwise WKExtensionMain will call
|
||||
// UIApplicationMain and normal startup occurs)
|
||||
//
|
||||
// * We can't call our entry point "main", because we call WKExtensionMain, and then we run into an
|
||||
// infinite loop on watchOS 7.0. So we call it xamarin_watch_extension_main.
|
||||
// * The watchOS 6+ SDK helpfully provides a static library (WKExtensionMainLegacy) that has a
|
||||
// WKExtensionMain function, which we use when the deployment target is earlier than watchOS 6.0.
|
||||
// This means that calling WKExtensionMain works everywhere (as long as we're using the
|
||||
// watchOS 6+ SDK to build; otherwise we just call "main" directly and don't link with the
|
||||
// WKExtensionMainLegacy library)
|
||||
|
||||
if (app.SdkVersion.Major >= 6) {
|
||||
extension_main = "WKExtensionMain";
|
||||
} else {
|
||||
extension_main = "main";
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty (extension_main)) {
|
||||
sw.WriteLine ($"extern \"C\" {{ int {extension_main} (int argc, char* argv[]); }}");
|
||||
sw.WriteLine ();
|
||||
}
|
||||
|
||||
sw.WriteLine ();
|
||||
sw.WriteLine ("void xamarin_initialize_callbacks () __attribute__ ((constructor));");
|
||||
sw.WriteLine ("void xamarin_initialize_callbacks ()");
|
||||
sw.WriteLine ("{");
|
||||
sw.WriteLine ("\txamarin_setup = xamarin_setup_impl;");
|
||||
sw.WriteLine ("\txamarin_register_assemblies = xamarin_register_assemblies_impl;");
|
||||
sw.WriteLine ("\txamarin_register_modules = xamarin_register_modules_impl;");
|
||||
if (!string.IsNullOrEmpty (extension_main))
|
||||
sw.WriteLine ($"\txamarin_extension_main = {extension_main};");
|
||||
sw.WriteLine ("}");
|
||||
}
|
||||
WriteIfDifferent (main_source, sb.ToString (), true);
|
||||
} catch (ProductException) {
|
||||
throw;
|
||||
} catch (Exception e) {
|
||||
throw new ProductException (4001, true, e, Errors.MT4001, main_source);
|
||||
}
|
||||
|
||||
return main_source;
|
||||
}
|
||||
|
||||
public static void CopyAssembly (string source, string target, string target_dir = null)
|
||||
{
|
||||
if (File.Exists (target))
|
||||
|
@ -1175,20 +926,5 @@ namespace Xamarin.Bundler
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsBoundAssembly (Assembly s)
|
||||
{
|
||||
if (s.IsFrameworkAssembly == true)
|
||||
return false;
|
||||
|
||||
AssemblyDefinition ad = s.AssemblyDefinition;
|
||||
|
||||
foreach (ModuleDefinition md in ad.Modules)
|
||||
foreach (TypeDefinition td in md.Types)
|
||||
if (td.IsNSObject (s.Target.LinkContext))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -472,6 +472,9 @@
|
|||
<Compile Include="..\common\Driver.execution.cs">
|
||||
<Link>tools\common\Driver.execution.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\common\BitCodeMode.cs">
|
||||
<Link>tools\common\BitCodeMode.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Core" />
|
||||
|
|
Загрузка…
Ссылка в новой задаче