public string GetLLVMOptimizations(Assembly assembly) { string opt; if (LLVMOptimizations.TryGetValue (assembly.FileName, out opt)) return opt; if (LLVMOptimizations.TryGetValue ("all", out opt)) return opt; return null; }
public void ManagedLink() { var cache_path = Path.Combine (ArchDirectory, "linked-assemblies.txt"); foreach (var a in Assemblies) a.CopyToDirectory (LinkDirectory, false, check_case: true); // Check if we can use a previous link result. if (!Driver.Force) { var input = new List<string> (); var output = new List<string> (); var cached_output = new List<string> (); if (File.Exists (cache_path)) { cached_output.AddRange (File.ReadAllLines (cache_path)); var cached_loaded = new HashSet<string> (); // Only add the previously linked assemblies (and their satellites) as the input/output assemblies. // Do not add assemblies which the linker process removed. foreach (var a in Assemblies) { if (!cached_output.Contains (a.FullPath)) continue; cached_loaded.Add (a.FullPath); input.Add (a.FullPath); output.Add (Path.Combine (PreBuildDirectory, a.FileName)); if (a.Satellites != null) { foreach (var s in a.Satellites) { input.Add (s); output.Add (Path.Combine (PreBuildDirectory, Path.GetFileName (Path.GetDirectoryName (s)), Path.GetFileName (s))); } } } // The linker might have added assemblies that weren't specified/reachable // from the command line arguments (such as I18N assemblies). Those are not // in the Assemblies list at this point (since we haven't run the linker yet) // so make sure we take those into account as well. var not_loaded = cached_output.Except (cached_loaded); foreach (var path in not_loaded) { input.Add (path); output.Add (Path.Combine (PreBuildDirectory, Path.GetFileName (path))); } // Include mtouch here too? // input.Add (Path.Combine (MTouch.MonoTouchDirectory, "usr", "bin", "mtouch")); if (Application.IsUptodate (input, output)) { cached_link = true; for (int i = Assemblies.Count - 1; i >= 0; i--) { var a = Assemblies [i]; if (!cached_output.Contains (a.FullPath)) { Assemblies.RemoveAt (i); continue; } // Load the cached assembly a.LoadAssembly (Path.Combine (PreBuildDirectory, a.FileName)); Driver.Log (3, "Target '{0}' is up-to-date.", a.FullPath); } foreach (var path in not_loaded) { var a = new Assembly (this, path); a.LoadAssembly (Path.Combine (PreBuildDirectory, a.FileName)); Assemblies.Add (a); } Driver.Watch ("Cached assemblies reloaded", 1); return; } } } // Load the assemblies into memory. foreach (var a in Assemblies) a.LoadAssembly (a.FullPath); var assemblies = new List<string> (); foreach (var a in Assemblies) assemblies.Add (a.FullPath); var linked_assemblies = new List<string> (assemblies); LinkAssemblies (App.RootAssembly, ref linked_assemblies, PreBuildDirectory, out LinkContext); // Remove assemblies that were linked away var removed = new HashSet<string> (assemblies); removed.ExceptWith (linked_assemblies); foreach (var assembly in removed) { for (int i = Assemblies.Count - 1; i >= 0; i--) { var ad = Assemblies [i]; if (assembly != ad.FullPath) continue; Assemblies.RemoveAt (i); } } // anything added by the linker will have it's original path var added = new HashSet<string> (); foreach (var assembly in linked_assemblies) added.Add (Path.GetFileName (assembly)); var original = new HashSet<string> (); foreach (var assembly in assemblies) original.Add (Path.GetFileName (assembly)); added.ExceptWith (original); foreach (var assembly in added) { // the linker already copied the assemblies (linked or not) into the output directory // and we must NOT overwrite the linker work with an original (unlinked) assembly string path = Path.Combine (PreBuildDirectory, assembly); var ad = ManifestResolver.Load (path); var a = new Assembly (this, ad); a.CopyToDirectory (PreBuildDirectory); Assemblies.Add (a); } assemblies = linked_assemblies; // Make the assemblies point to the right path. foreach (var a in Assemblies) a.FullPath = Path.Combine (PreBuildDirectory, a.FileName); File.WriteAllText (cache_path, string.Join ("\n", linked_assemblies)); }
void ComputeListOfAssemblies(HashSet<string> assemblies, AssemblyDefinition assembly, List<Exception> exceptions) { if (assembly == null) return; var fqname = assembly.MainModule.FullyQualifiedName; if (assemblies.Contains (fqname)) return; assemblies.Add (fqname); var asm = new Assembly (this, assembly); asm.ComputeSatellites (); this.Assemblies.Add (asm); var main = assembly.MainModule; foreach (AssemblyNameReference reference in main.AssemblyReferences) { // Verify that none of the references references an incorrect platform assembly. switch (reference.Name) { case "monotouch": case "Xamarin.iOS": case "Xamarin.TVOS": case "Xamarin.WatchOS": if (reference.Name != Driver.ProductAssembly) exceptions.Add (ErrorHelper.CreateError (34, "Cannot reference '{0}.dll' in a {1} project - it is implicitly referenced by '{2}'.", reference.Name, Driver.TargetFramework.Identifier, assembly.FullName)); break; } var reference_assembly = ManifestResolver.Resolve (reference); ComputeListOfAssemblies (assemblies, reference_assembly, exceptions); } // Custom Attribute metadata can include references to other assemblies, e.g. [X (typeof (Y)], // but it is not reflected in AssemblyReferences :-( ref: #37611 // so we must scan every custom attribute to look for System.Type GetCustomAttributeReferences (assembly, assemblies, exceptions); GetCustomAttributeReferences (main, assemblies, exceptions); if (main.HasTypes) { foreach (var t in main.Types) { GetTypeReferences (t, assemblies, exceptions); } } }
static bool IsBoundAssembly (Assembly s) { if (s.IsFrameworkAssembly) return false; AssemblyDefinition ad = s.AssemblyDefinition; foreach (ModuleDefinition md in ad.Modules) foreach (TypeDefinition td in md.Types) if (td.IsNSObject ()) return true; return false; }