diff --git a/mk/mono.mk b/mk/mono.mk index 82bd64364866..1ada024dc6a1 100644 --- a/mk/mono.mk +++ b/mk/mono.mk @@ -1,5 +1,5 @@ -NEEDED_MONO_VERSION := 5e9cb6d1c1de430965312927d5aed7fcb27bfa73 -NEEDED_MONO_BRANCH := 2020-02 +NEEDED_MONO_VERSION := 4f173da78ae55ca7f4b09565b038a823f7ffd948 +NEEDED_MONO_BRANCH := 2021-02 MONO_DIRECTORY := mono -MONO_MODULE := https://github.com/mono/mono +MONO_MODULE := https://github.com/mynovelhost/mono diff --git a/tools/common/Application.cs b/tools/common/Application.cs index 8b6ea8421d0c..9062ca383182 100644 --- a/tools/common/Application.cs +++ b/tools/common/Application.cs @@ -1375,19 +1375,7 @@ public bool IsInterpreted (string assembly) // revision/testing to be used so desired. public bool IsAOTCompiled (string assembly) { - if (Platform == ApplePlatform.MacOSX) - throw ErrorHelper.CreateError (99, Errors.MX0099, "IsAOTCompiled isn't a valid operation for macOS apps."); - - 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); + return false; } public string AssemblyName { diff --git a/tools/common/Target.cs b/tools/common/Target.cs index 79d4bc68caf0..1d7f478cc39b 100644 --- a/tools/common/Target.cs +++ b/tools/common/Target.cs @@ -743,8 +743,7 @@ void GenerateIOSMain (StringWriter sw, Abi abi) 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);"); diff --git a/tools/mtouch/Target.mtouch.cs b/tools/mtouch/Target.mtouch.cs index b9ed896099f1..f0603fa1c959 100644 --- a/tools/mtouch/Target.mtouch.cs +++ b/tools/mtouch/Target.mtouch.cs @@ -941,299 +941,9 @@ public void CompilePInvokeWrappers () void AOTCompile () { - if (App.IsSimulatorBuild) - return; - - if (App.Platform == ApplePlatform.MacCatalyst) - return; - - // Here we create the tasks to run the AOT compiler. - foreach (var a in Assemblies) { - if (!a.IsAOTCompiled) - continue; - - foreach (var abi in GetArchitectures (a.BuildTarget)) { - a.CreateAOTTask (abi); - } - } - - // Group the assemblies according to their target name, and link everything together accordingly. - var grouped = Assemblies.GroupBy ((arg) => arg.BuildTargetName); - foreach (var @group in grouped) { - var name = @group.Key; - var assemblies = @group.AsEnumerable ().ToArray (); - if (assemblies.Length <= 0) - continue; - - // We ensure elsewhere that all assemblies in a group have the same build target. - var build_target = assemblies [0].BuildTarget; - - foreach (var abi in GetArchitectures (build_target)) { - Driver.Log (2, "Building {0} from {1}", name, string.Join (", ", assemblies.Select ((arg1) => Path.GetFileName (arg1.FileName)))); - - string install_name; - string compiler_output; - var compiler_flags = new CompilerFlags (this); - var link_dependencies = new List (); - var infos = assemblies.Where ((asm) => asm.AotInfos.ContainsKey (abi)).Select ((asm) => asm.AotInfos [abi]).ToList (); - var aottasks = infos.Select ((info) => info.Task); - if (aottasks == null) - continue; - - var existingLinkTask = infos.Where ((v) => v.LinkTask != null).Select ((v) => v.LinkTask).ToList (); - if (existingLinkTask.Count > 0) { - if (existingLinkTask.Count != infos.Count) - throw ErrorHelper.CreateError (99, Errors.MX0099, $"Not all assemblies for {name} have link tasks"); - if (!existingLinkTask.All ((v) => v == existingLinkTask [0])) - throw ErrorHelper.CreateError (99, Errors.MX0099, $"Link tasks for {name} aren't all the same"); - - LinkWithBuildTarget (build_target, name, existingLinkTask [0], assemblies); - continue; - } - - // We have to compile any source files to object files before we can link. - var sources = infos.SelectMany ((info) => info.AsmFiles); - if (sources.Count () > 0) { - foreach (var src in sources) { - // We might have to convert .s to bitcode assembly (.ll) first - var assembly = src; - BitCodeifyTask bitcode_task = null; - if (App.EnableAsmOnlyBitCode) { - bitcode_task = new BitCodeifyTask () - { - Input = assembly, - OutputFile = Path.ChangeExtension (assembly, ".ll"), - Platform = App.Platform, - Abi = abi, - DeploymentTarget = App.DeploymentTarget, - }; - bitcode_task.AddDependency (aottasks); - assembly = bitcode_task.OutputFile; - } - - // Compile assembly code (either .s or .ll) to object file - var compile_task = new CompileTask - { - Target = this, - SharedLibrary = false, - InputFile = assembly, - OutputFile = Path.ChangeExtension (assembly, ".o"), - Abi = abi, - Language = bitcode_task != null ? null : "assembler", - }; - compile_task.AddDependency (bitcode_task); - compile_task.AddDependency (aottasks); - link_dependencies.Add (compile_task); - } - } else { - aot_dependencies.AddRange (aottasks); - } - - // Compile any .bc files to .o - foreach (var info in infos) { - foreach (var bc in info.BitcodeFiles) { - var compile_task = new CompileTask { - Target = this, - SharedLibrary = false, - InputFile = bc, - OutputFile = bc + ".o", - Abi = abi, - }; - compile_task.CompilerFlags.AddOtherFlag (App.UserGccFlags); - compile_task.AddDependency (info.Task); - link_dependencies.Add (compile_task); - } - } - - var arch = abi.AsArchString (); - switch (build_target) { - case AssemblyBuildTarget.StaticObject: - LinkWithTaskOutput (link_dependencies); // Any .s or .ll files from the AOT compiler (compiled to object files) - foreach (var info in infos) { - LinkWithStaticLibrary (abi, info.ObjectFiles); - } - continue; // no linking to do here. - case AssemblyBuildTarget.DynamicLibrary: - install_name = $"@rpath/lib{name}.dylib"; - compiler_output = Path.Combine (App.Cache.Location, arch, $"lib{name}.dylib"); - break; - case AssemblyBuildTarget.Framework: - install_name = $"@rpath/{name}.framework/{name}"; - compiler_output = Path.Combine (App.Cache.Location, arch, name); - break; - default: - throw ErrorHelper.CreateError (100, Errors.MT0100, build_target); - } - - CompileTask pinvoke_task; - if (pinvoke_tasks.TryGetValue (abi, out pinvoke_task)) - link_dependencies.Add (pinvoke_task); - - foreach (var info in infos) { - compiler_flags.AddLinkWith (info.ObjectFiles); - } - - foreach (var task in link_dependencies) - compiler_flags.AddLinkWith (task.OutputFile); - - foreach (var a in assemblies) { - compiler_flags.AddFrameworks (a.Frameworks, a.WeakFrameworks); - compiler_flags.AddLinkWith (a.LinkWith, a.ForceLoad); - compiler_flags.AddOtherFlag (a.LinkerFlags.ToArray ()); - if (a.HasLinkWithAttributes) { - var symbols = GetRequiredSymbols (a); - switch (App.SymbolMode) { - case SymbolMode.Ignore: - break; - case SymbolMode.Code: - var tasks = GenerateReferencingSource (Path.Combine (App.Cache.Location, Path.GetFileNameWithoutExtension (a.FullPath) + "-unresolved-externals.m"), symbols); - foreach (var task in tasks) - compiler_flags.AddLinkWith (task.OutputFile); - link_dependencies.AddRange (tasks); - break; - case SymbolMode.Linker: - compiler_flags.ReferenceSymbols (symbols); - break; - default: - throw ErrorHelper.CreateError (99, Errors.MX0099, $"invalid symbol mode: {App.SymbolMode}"); - } - } - } - if (App.Embeddinator) - compiler_flags.AddOtherFlag (App.UserGccFlags); - compiler_flags.LinkWithMono (); - compiler_flags.LinkWithXamarin (); - if (GetAllSymbols ().Contains ("UIApplicationMain")) - compiler_flags.AddFramework ("UIKit"); - - if (App.EnableLLVMOnlyBitCode) { - // The AOT compiler doesn't optimize the bitcode so clang will do it - compiler_flags.AddOtherFlag ("-fexceptions"); - var optimizations = assemblies.Select ((a) => App.GetLLVMOptimizations (a)).Where ((opt) => opt != null).Distinct ().ToList (); - if (optimizations.Count == 0) { - compiler_flags.AddOtherFlag ("-O2"); - } else if (optimizations.Count == 1) { - compiler_flags.AddOtherFlag (optimizations [0]); - } else { - throw ErrorHelper.CreateError (107, Errors.MT0107, string.Join (", ", assemblies.Select ((v) => v.Identity)), string.Join ("', '", optimizations)); - } - } - - HandleMonoNative (App, compiler_flags); - - var link_task = new LinkTask () - { - Target = this, - Abi = abi, - OutputFile = compiler_output, - InstallName = install_name, - CompilerFlags = compiler_flags, - Language = compiler_output.EndsWith (".s", StringComparison.Ordinal) ? "assembler" : null, - SharedLibrary = build_target != AssemblyBuildTarget.StaticObject, - }; - link_task.AddDependency (link_dependencies); - link_task.AddDependency (aottasks); - - if (App.Embeddinator) { - link_task.AddDependency (link_with_task_output); - link_task.CompilerFlags.AddLinkWith (link_with_task_output.Select ((v) => v.OutputFile)); - embeddinator_tasks.Add (link_task); - } - - LinkWithBuildTarget (build_target, name, link_task, assemblies); - - foreach (var info in infos) - info.LinkTask = link_task; - } - } - - if (App.UseInterpreter) - /* TODO: not sure? we might have to continue here, depending on - * the set of assemblies are AOT'd? */ - return; - - // Code in one assembly (either in a P/Invoke or a third-party library) can depend on a third-party library in another assembly. - // This means that we must always build assemblies only when all their dependent assemblies have been built, so that - // we can link (natively) with the frameworks/dylibs for those dependent assemblies. - // Fortunately we can cheat a bit, since this can (currently at least) only happen for assemblies that - // have third-party libraries. This means that we only enforce this order for any assemblies that depend - // on other assemblies that have third-party libraries. - // Example: - // * We can build System.dll and mscorlib.dll in parallel, even if System.dll depends on mscorlib.dll, - // because we know that mscorlib.dll does not have any third-party libraries. - if (Assemblies.All ((arg) => arg.HasDependencyMap)) { - var dict = Assemblies.ToDictionary ((arg) => Path.GetFileNameWithoutExtension (arg.FileName)); - foreach (var asm in Assemblies) { - if (!asm.HasDependencyMap) - continue; - - if (asm.BuildTarget == AssemblyBuildTarget.StaticObject) - continue; - - if (Profile.IsSdkAssembly (asm.AssemblyDefinition) || Profile.IsProductAssembly (asm.AssemblyDefinition)) { - //Console.WriteLine ("SDK assembly, so skipping assembly dependency checks: {0}", Path.GetFileNameWithoutExtension (asm.FileName)); - continue; - } - - HashSet dependent_assemblies = new HashSet (); - foreach (var dep in asm.DependencyMap) { - Assembly dependentAssembly; - if (!dict.TryGetValue (Path.GetFileNameWithoutExtension (dep), out dependentAssembly)) { - //Console.WriteLine ("Could not find dependency '{0}' of '{1}'", dep, asm.Identity); - continue; - } - if (asm == dependentAssembly) - continue; // huh? - - // Nothing can depend on anything in our SDK, nor does our SDK depend on anything else in our SDK - // So we can remove any SDK dependency - if (Profile.IsSdkAssembly (dependentAssembly.AssemblyDefinition) || Profile.IsProductAssembly (dependentAssembly.AssemblyDefinition)) { - //Console.WriteLine ("SDK assembly, so not a dependency of anything: {0}", Path.GetFileNameWithoutExtension (dependentAssembly.FileName)); - continue; - } - - if (!dependentAssembly.HasLinkWithAttributes) { - //Console.WriteLine ("Assembly {0} does not have LinkWith attributes, so there's nothing we can depend on.", dependentAssembly.Identity); - continue; - } - - if (dependentAssembly.BuildTargetName == asm.BuildTargetName) { - //Console.WriteLine ("{0} is a dependency of {1}, but both are being built into the same target, so no dependency added.", Path.GetFileNameWithoutExtension (dep), Path.GetFileNameWithoutExtension (asm.FileName)); - continue; - } - - //Console.WriteLine ("Added {0} as a dependency of {1}", Path.GetFileNameWithoutExtension (dep), Path.GetFileNameWithoutExtension (asm.FileName)); - dependent_assemblies.Add (dependentAssembly); - } - - // Circular dependencies shouldn't happen, but still make sure, since it's technically possible - // for users to do it. - foreach (var abi in GetArchitectures (asm.BuildTarget)) { - var target_task = asm.AotInfos [abi].LinkTask; - var dependent_tasks = dependent_assemblies.Select ((v) => v.AotInfos [abi].LinkTask); - - var stack = new Stack (); - foreach (var dep in dependent_tasks) { - stack.Clear (); - stack.Push (target_task); - if (target_task == dep || IsCircularTask (target_task, stack, dep)) { - Driver.Log ("Found circular task."); - Driver.Log ("Task {0} (with output {1}) depends on:", target_task.GetType ().Name, target_task.Outputs.First ()); - stack = new Stack (stack.Reverse ()); - while (stack.Count > 0) { - var node = stack.Pop (); - Driver.Log (" -> {0} (Output: {1})", node.GetType ().Name, node.Outputs.First ()); - } - } else { - target_task.AddDependency (dep); - target_task.CompilerFlags.AddLinkWith (dep.OutputFile); - } - } - } - } - } + } - + bool IsCircularTask (BuildTask root, Stack stack, BuildTask task) { stack.Push (task);