public override Assembly Resolve(MetadataLoadContext context, AssemblyName assemblyName) { Assembly core = base.Resolve(context, assemblyName); if (core != null) { return(core); } ReadOnlySpan <byte> pktFromAssemblyName = assemblyName.GetPublicKeyToken(); foreach (Assembly assembly in context.GetAssemblies()) { AssemblyName assemblyNameFromContext = assembly.GetName(); if (assemblyName.Name.Equals(assemblyNameFromContext.Name, StringComparison.OrdinalIgnoreCase) && NormalizeVersion(assemblyName.Version).Equals(assemblyNameFromContext.Version) && pktFromAssemblyName.SequenceEqual(assemblyNameFromContext.GetPublicKeyToken()) && NormalizeCultureName(assemblyName.CultureName).Equals(NormalizeCultureName(assemblyNameFromContext.CultureName))) { return(assembly); } } return(null); }
public static void GetAssemblies() { using (MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver())) { Assembly[] loadedAssemblies = lc.GetAssemblies().ToArray(); Assert.Equal(1, loadedAssemblies.Length); // EmptyCoreMetadataAssemblyResolver already loaded s_SimpleNameOnlyImage Assembly a1 = lc.LoadFromByteArray(TestData.s_SimpleAssemblyImage); Assembly a2 = lc.LoadFromByteArray(TestData.s_SimpleNameOnlyImage); loadedAssemblies = lc.GetAssemblies().ToArray(); Assert.Equal(2, loadedAssemblies.Length); Assert.Contains <Assembly>(a1, loadedAssemblies); Assert.Contains <Assembly>(a2, loadedAssemblies); } }
public override Assembly?Resolve(MetadataLoadContext context, AssemblyName assemblyName) { string?name = assemblyName.Name; if (name != null) { foreach (var asm in context.GetAssemblies()) { if (asm.GetName().Name == name) { return(asm); } } string dllName = name + ".dll"; foreach (var libraryPath in libraryPaths) { string path = Path.Combine(libraryPath, dllName); if (File.Exists(path)) { return(context.LoadFromAssemblyPath(path)); } } foreach (var reference in references) { if (Path.GetFileName(reference).Equals(dllName, StringComparison.OrdinalIgnoreCase)) { return(context.LoadFromAssemblyPath(reference)); } } } return(null); }
private List <Assembly> LoadReferencedAssembliesMetadata() { var explorationContext = new MetadataLoadContext(_resolver); var knownAssemblies = explorationContext.GetAssemblies().Union(new[] { ImplementingAssembly }).ToList(); var recursions = 0; List <string> newAssemblyNames; do { recursions++; var knownNames = knownAssemblies.Select(a => a.GetName().FullName).Distinct().ToList(); var referencedNames = knownAssemblies.SelectMany( a => a.GetReferencedAssemblies().Where(n => n.FullName.StartsWith("Trakx"))) .Select(a => a.FullName); newAssemblyNames = referencedNames.Except(knownNames).ToList(); foreach (var name in newAssemblyNames) { try { knownAssemblies.Add(explorationContext.LoadFromAssemblyName(name)); } catch (Exception e) { _output.WriteLine("Failed to load assembly {0} with exception {1}", name, e); } } } while (newAssemblyNames.Any() && recursions <= _maxRecursions); return(knownAssemblies); }
public static void GetAssemblies_EmptyMetadataLoadContext() { using (MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver())) { Assembly[] loadedAssemblies = lc.GetAssemblies().ToArray(); Assert.Equal(1, loadedAssemblies.Length); } }
public static void DuplicateSignedAssembliesSameMvid() { using (TempDirectory dir = new TempDirectory()) using (TempDirectory dir2 = new TempDirectory()) using (TempFile core = new TempFile(Path.Combine(dir.Path, TestData.s_PhonyCoreAssemblySimpleName), TestData.s_PhonyCoreAssemblyImage)) using (TempFile tf1 = new TempFile(Path.Combine(dir.Path, TestData.s_SimpleVersionedShortName), TestData.s_SimpleSignedVersioned100Image)) using (TempFile tf2 = new TempFile(Path.Combine(dir2.Path, TestData.s_SimpleVersionedShortName), TestData.s_SimpleSignedVersioned100Image)) { var resolver = new PathAssemblyResolver(new string[] { core.Path, tf1.Path, tf2.Path }); using (var lc = new MetadataLoadContext(resolver, TestData.s_PhonyCoreAssemblyFullName)) { Assert.Equal(1, lc.GetAssemblies().Count()); Assembly a1 = lc.LoadFromAssemblyName(TestData.s_SimpleVersionedShortName); Assembly a2 = lc.LoadFromAssemblyName(TestData.s_SimpleSignedVersioned100FullName); Assert.Same(a1, a2); Assert.Equal(2, lc.GetAssemblies().Count()); } } }
public static void MetadataLoadContextApisAfterDispose() { MetadataLoadContext lc = new MetadataLoadContext(new EmptyCoreMetadataAssemblyResolver()); lc.Dispose(); Assert.Throws <ObjectDisposedException>(() => lc.LoadFromAssemblyName(new AssemblyName("Foo"))); Assert.Throws <ObjectDisposedException>(() => lc.LoadFromAssemblyName("Foo")); Assert.Throws <ObjectDisposedException>(() => lc.LoadFromAssemblyPath("Foo")); Assert.Throws <ObjectDisposedException>(() => lc.LoadFromByteArray(TestData.s_SimpleAssemblyImage)); Assert.Throws <ObjectDisposedException>(() => lc.LoadFromStream(new MemoryStream(TestData.s_SimpleAssemblyImage))); Assert.Throws <ObjectDisposedException>(() => lc.CoreAssembly); Assert.Throws <ObjectDisposedException>(() => lc.GetAssemblies()); }
public static void DuplicateSignedAndUnsignedAssemblies() { using (TempDirectory dir = new TempDirectory()) using (TempDirectory dir2 = new TempDirectory()) using (TempFile core = new TempFile(Path.Combine(dir.Path, TestData.s_PhonyCoreAssemblySimpleName), TestData.s_PhonyCoreAssemblyImage)) using (TempFile tf1 = new TempFile(Path.Combine(dir.Path, TestData.s_SimpleVersionedShortName), TestData.s_SimpleSignedVersioned100Image)) using (TempFile tf2 = new TempFile(Path.Combine(dir2.Path, TestData.s_SimpleVersionedShortName), TestData.s_SimpleUnsignedVersioned100Image)) { var resolver = new PathAssemblyResolver(new string[] { core.Path, tf1.Path, tf2.Path }); using (var lc = new MetadataLoadContext(resolver, TestData.s_PhonyCoreAssemblyFullName)) { Assert.Equal(1, lc.GetAssemblies().Count()); // These are treated as different since one contains a PublicKeyToken and one does not. Assembly a1 = lc.LoadFromAssemblyName(TestData.s_SimpleUnsignedVersioned100FullName); Assembly a2 = lc.LoadFromAssemblyName(TestData.s_SimpleSignedVersioned100FullName); Assert.NotSame(a1, a2); Assert.Equal(3, lc.GetAssemblies().Count()); } } }
public Type FindType(Type type) { var assemblyName = type.Assembly.GetName(); var assemblies = _metadataLoadContext.GetAssemblies(); var assembly = assemblies.FirstOrDefault(x => string.Equals(x.FullName, assemblyName.FullName)); if (assembly == null) { assembly = _metadataLoadContext.LoadFromAssemblyName(assemblyName); } var result = assembly.GetType(type.FullName); return(result); }
public static void DuplicateSignedAssembliesDifferentVersions() { using (TempDirectory dir = new TempDirectory()) using (TempDirectory dir2 = new TempDirectory()) using (TempFile core = new TempFile(Path.Combine(dir.Path, TestData.s_PhonyCoreAssemblySimpleName), TestData.s_PhonyCoreAssemblyImage)) using (TempFile tf1 = new TempFile(Path.Combine(dir.Path, TestData.s_SimpleVersionedShortName), TestData.s_SimpleSignedVersioned100Image)) using (TempFile tf2 = new TempFile(Path.Combine(dir2.Path, TestData.s_SimpleVersionedShortName), TestData.s_SimpleSignedVersioned200Image)) { var resolver = new PathAssemblyResolver(new string[] { core.Path, tf1.Path, tf2.Path }); using (var lc = new MetadataLoadContext(resolver, TestData.s_PhonyCoreAssemblyFullName)) { Assert.Equal(1, lc.GetAssemblies().Count()); // Using simple name will find first assembly that matches. Assembly a1 = lc.LoadFromAssemblyName(TestData.s_SimpleVersionedShortName); Assembly a2 = lc.LoadFromAssemblyName(TestData.s_SimpleSignedVersioned100FullName); Assembly a3 = lc.LoadFromAssemblyName(TestData.s_SimpleSignedVersioned200FullName); Assert.True(object.ReferenceEquals(a1, a2) || object.ReferenceEquals(a1, a3)); Assert.Equal(3, lc.GetAssemblies().Count()); } } }
public override Assembly Resolve(MetadataLoadContext context, AssemblyName assemblyName) { var matchedAssembly = context.GetAssemblies() .FirstOrDefault(a => a.GetName().Name == assemblyName.Name); if (matchedAssembly != null) { return(matchedAssembly); } var path = Path.Combine(this.directory, assemblyName.Name + ".dll"); if (File.Exists(path)) { return(context.LoadFromAssemblyPath(path)); } throw new FileLoadException($"Could not resolve {assemblyName}"); }
public static void GetAssemblies_SnapshotIsAtomic() { Assembly a1 = null; var resolver = new FuncMetadataAssemblyResolver( delegate(MetadataLoadContext context, AssemblyName refName) { if (a1 == null) { // Initial request to load core assembly return(a1 = context.LoadFromByteArray(TestData.s_SimpleAssemblyImage)); } return(null); }); using (MetadataLoadContext lc = new MetadataLoadContext(resolver)) { IEnumerable <Assembly> loadedAssembliesSnapshot = lc.GetAssemblies(); Assembly a2 = lc.LoadFromByteArray(TestData.s_SimpleNameOnlyImage); Assembly[] loadedAssemblies = loadedAssembliesSnapshot.ToArray(); Assert.Equal(1, loadedAssemblies.Length); Assert.Equal(a1, loadedAssemblies[0]); } }
public static void ResolveToAssemblyNameCombinations() { using (TempDirectory dir = new TempDirectory()) using (TempFile core = new TempFile(Path.Combine(dir.Path, TestData.s_PhonyCoreAssemblySimpleName), TestData.s_PhonyCoreAssemblyImage)) using (TempFile tf1 = new TempFile(Path.Combine(dir.Path, TestData.s_SimpleVersionedShortName), TestData.s_SimpleSignedVersioned100Image)) { var resolver = new PathAssemblyResolver(new string[] { core.Path, tf1.Path }); using (MetadataLoadContext lc = new MetadataLoadContext(resolver, TestData.s_PhonyCoreAssemblySimpleName)) { Assert.Equal(1, lc.GetAssemblies().Count()); Assembly assembly = lc.LoadFromAssemblyName(TestData.s_SimpleVersionedShortName); Assert.NotNull(assembly); // Name { Assembly assemblyAgain = lc.LoadFromAssemblyName(TestData.s_SimpleVersionedShortName.ToUpper()); Assert.NotNull(assemblyAgain); } AssemblyName assemblyName = new AssemblyName(TestData.s_SimpleVersionedShortName); // Version { assemblyName.Version = new Version(999, 998); lc.LoadFromAssemblyName(assemblyName); Assert.Equal(2, lc.GetAssemblies().Count()); } { assemblyName.Version = null; Assembly assemblyAgain = lc.LoadFromAssemblyName(assemblyName); Assert.Same(assembly, assemblyAgain); } { assemblyName.Version = new Version(0, 0, 0, 0); Assembly assemblyAgain = lc.LoadFromAssemblyName(assemblyName); Assert.Same(assembly, assemblyAgain); } { assemblyName.Version = assembly.GetName().Version; Assembly assemblyAgain = lc.LoadFromAssemblyName(assemblyName); Assert.Same(assembly, assemblyAgain); } // CultureName; match not required { assemblyName.CultureName = "en"; Assembly assemblyAgain = lc.LoadFromAssemblyName(assemblyName); Assert.Same(assembly, assemblyAgain); } { assemblyName.CultureName = ""; Assembly assemblyAgain = lc.LoadFromAssemblyName(assemblyName); Assert.Same(assembly, assemblyAgain); } { assemblyName.CultureName = null; Assembly assemblyAgain = lc.LoadFromAssemblyName(assemblyName); Assert.Same(assembly, assemblyAgain); } assemblyName.CultureName = assembly.GetName().CultureName; // PublicKeyToken assemblyName.SetPublicKeyToken(new byte[] { 1 }); Assert.Throws <FileNotFoundException>(() => lc.LoadFromAssemblyName(assemblyName)); { assemblyName.SetPublicKeyToken(null); Assembly assemblyAgain = lc.LoadFromAssemblyName(assemblyName); Assert.Same(assembly, assemblyAgain); } { assemblyName.SetPublicKeyToken(Array.Empty <byte>()); Assembly assemblyAgain = lc.LoadFromAssemblyName(assemblyName); Assert.Same(assembly, assemblyAgain); } { assemblyName.SetPublicKeyToken(assembly.GetName().GetPublicKeyToken()); Assembly assemblyAgain = lc.LoadFromAssemblyName(assemblyName); Assert.Same(assembly, assemblyAgain); } // None of the above should have affected the number of loaded assemblies. Assert.Equal(2, lc.GetAssemblies().Count()); } } }
int Main3(string [] args) { bool show_help = false; bool zero_copy = false; string basedir = null; string tmpdir = null; string ns = null; bool delete_temp = true, debug = false; bool unsafef = true; bool external = false; bool public_mode = true; bool nostdlib = false; bool? inline_selectors = null; List <string> sources; var resources = new List <string> (); var linkwith = new List <string> (); var api_sources = new List <string> (); var core_sources = new List <string> (); var extra_sources = new List <string> (); var defines = new List <string> (); string generate_file_list = null; bool process_enums = false; string compiler = "/Library/Frameworks/Mono.framework/Versions/Current/bin/csc"; ErrorHelper.ClearWarningLevels(); var os = new OptionSet() { { "h|?|help", "Displays the help", v => show_help = true }, { "a", "Include alpha bindings (Obsolete).", v => {}, true }, { "outdir=", "Sets the output directory for the temporary binding files", v => { basedir = v; } }, { "o|out=", "Sets the name of the output library", v => outfile = v }, { "tmpdir=", "Sets the working directory for temp files", v => { tmpdir = v; delete_temp = false; } }, { "debug", "Generates a debugging build of the binding", v => debug = true }, { "sourceonly=", "Only generates the source", v => generate_file_list = v }, { "ns=", "Sets the namespace for storing helper classes", v => ns = v }, { "unsafe", "Sets the unsafe flag for the build", v => unsafef = true }, { "core", "Use this to build product assemblies", v => BindThirdPartyLibrary = false }, { "r|reference=", "Adds a reference", v => references.Add(v) }, { "lib=", "Adds the directory to the search path for the compiler", v => libs.Add(v) }, { "compiler=", "Sets the compiler to use (Obsolete) ", v => compiler = v, true }, { "sdk=", "Sets the .NET SDK to use (Obsolete)", v => {}, true }, { "new-style", "Build for Unified (Obsolete).", v => { Console.WriteLine("The --new-style option is obsolete and ignored."); }, true }, { "d=", "Defines a symbol", v => defines.Add(v) }, { "api=", "Adds a API definition source file", v => api_sources.Add(v) }, { "s=", "Adds a source file required to build the API", v => core_sources.Add(v) }, { "q", "Quiet", v => ErrorHelper.Verbosity-- }, { "v", "Sets verbose mode", v => ErrorHelper.Verbosity++ }, { "x=", "Adds the specified file to the build, used after the core files are compiled", v => extra_sources.Add(v) }, { "e", "Generates smaller classes that can not be subclassed (previously called 'external mode')", v => external = true }, { "p", "Sets private mode", v => public_mode = false }, { "baselib=", "Sets the base library", v => baselibdll = v }, { "attributelib=", "Sets the attribute library", v => attributedll = v }, { "use-zero-copy", v => zero_copy = true }, { "nostdlib", "Does not reference mscorlib.dll library", l => nostdlib = true }, { "no-mono-path", "Launches compiler with empty MONO_PATH", l => { }, true }, { "native-exception-marshalling", "Enable the marshalling support for Objective-C exceptions", (v) => { /* no-op */ } }, { "inline-selectors:", "If Selector.GetHandle is inlined and does not need to be cached (enabled by default in Xamarin.iOS, disabled in Xamarin.Mac)", v => inline_selectors = string.Equals("true", v, StringComparison.OrdinalIgnoreCase) || string.IsNullOrEmpty(v) }, { "process-enums", "Process enums as bindings, not external, types.", v => process_enums = true }, { "link-with=,", "Link with a native library {0:FILE} to the binding, embedded as a resource named {1:ID}", (path, id) => { if (path == null || path.Length == 0) { throw new Exception("-link-with=FILE,ID requires a filename."); } if (id == null || id.Length == 0) { id = Path.GetFileName(path); } if (linkwith.Contains(id)) { throw new Exception("-link-with=FILE,ID cannot assign the same resource id to multiple libraries."); } resources.Add(string.Format("-res:{0},{1}", path, id)); linkwith.Add(id); } }, { "unified-full-profile", "Launches compiler pointing to XM Full Profile", l => { /* no-op*/ }, true }, { "unified-mobile-profile", "Launches compiler pointing to XM Mobile Profile", l => { /* no-op*/ }, true }, { "target-framework=", "Specify target framework to use. Always required, and the currently supported values are: 'Xamarin.iOS,v1.0', 'Xamarin.TVOS,v1.0', 'Xamarin.WatchOS,v1.0', 'XamMac,v1.0', 'Xamarin.Mac,Version=v2.0,Profile=Mobile', 'Xamarin.Mac,Version=v4.5,Profile=Full' and 'Xamarin.Mac,Version=v4.5,Profile=System')", v => SetTargetFramework(v) }, { "warnaserror:", "An optional comma-separated list of warning codes that should be reported as errors (if no warnings are specified all warnings are reported as errors).", v => { try { if (!string.IsNullOrEmpty(v)) { foreach (var code in v.Split(new char [] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { ErrorHelper.SetWarningLevel(ErrorHelper.WarningLevel.Error, int.Parse(code)); } } else { ErrorHelper.SetWarningLevel(ErrorHelper.WarningLevel.Error); } } catch (Exception ex) { throw ErrorHelper.CreateError(26, ex.Message); } } }, { "nowarn:", "An optional comma-separated list of warning codes to ignore (if no warnings are specified all warnings are ignored).", v => { try { if (!string.IsNullOrEmpty(v)) { foreach (var code in v.Split(new char [] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { ErrorHelper.SetWarningLevel(ErrorHelper.WarningLevel.Disable, int.Parse(code)); } } else { ErrorHelper.SetWarningLevel(ErrorHelper.WarningLevel.Disable); } } catch (Exception ex) { throw ErrorHelper.CreateError(26, ex.Message); } } }, new Mono.Options.ResponseFileSource(), }; try { sources = os.Parse(args); } catch (Exception e) { Console.Error.WriteLine("{0}: {1}", ToolName, e.Message); Console.Error.WriteLine("see {0} --help for more information", ToolName); return(1); } if (show_help) { ShowHelp(os); return(0); } if (!target_framework.HasValue) { throw ErrorHelper.CreateError(86); } switch (target_framework.Value.Platform) { case ApplePlatform.iOS: CurrentPlatform = PlatformName.iOS; nostdlib = true; if (string.IsNullOrEmpty(baselibdll)) { baselibdll = Path.Combine(GetSDKRoot(), "lib/mono/Xamarin.iOS/Xamarin.iOS.dll"); } if (!IsDotNet) { references.Add("Facades/System.Drawing.Common"); ReferenceFixer.FixSDKReferences(GetSDKRoot(), "lib/mono/Xamarin.iOS", references); } break; case ApplePlatform.TVOS: CurrentPlatform = PlatformName.TvOS; nostdlib = true; if (string.IsNullOrEmpty(baselibdll)) { baselibdll = Path.Combine(GetSDKRoot(), "lib/mono/Xamarin.TVOS/Xamarin.TVOS.dll"); } if (!IsDotNet) { references.Add("Facades/System.Drawing.Common"); ReferenceFixer.FixSDKReferences(GetSDKRoot(), "lib/mono/Xamarin.TVOS", references); } break; case ApplePlatform.WatchOS: CurrentPlatform = PlatformName.WatchOS; nostdlib = true; if (string.IsNullOrEmpty(baselibdll)) { baselibdll = Path.Combine(GetSDKRoot(), "lib/mono/Xamarin.WatchOS/Xamarin.WatchOS.dll"); } if (!IsDotNet) { references.Add("Facades/System.Drawing.Common"); ReferenceFixer.FixSDKReferences(GetSDKRoot(), "lib/mono/Xamarin.WatchOS", references); } break; case ApplePlatform.MacCatalyst: CurrentPlatform = PlatformName.MacCatalyst; nostdlib = true; if (string.IsNullOrEmpty(baselibdll)) { baselibdll = Path.Combine(GetSDKRoot(), "lib/mono/Xamarin.MacCatalyst/Xamarin.MacCatalyst.dll"); } if (!IsDotNet) { // references.Add ("Facades/System.Drawing.Common"); ReferenceFixer.FixSDKReferences(GetSDKRoot(), "lib/mono/Xamarin.MacCatalyst", references); } break; case ApplePlatform.MacOSX: CurrentPlatform = PlatformName.MacOSX; nostdlib = true; if (string.IsNullOrEmpty(baselibdll)) { if (target_framework == TargetFramework.Xamarin_Mac_2_0_Mobile) { baselibdll = Path.Combine(GetSDKRoot(), "lib", "reference", "mobile", "Xamarin.Mac.dll"); } else if (target_framework == TargetFramework.Xamarin_Mac_4_5_Full || target_framework == TargetFramework.Xamarin_Mac_4_5_System) { baselibdll = Path.Combine(GetSDKRoot(), "lib", "reference", "full", "Xamarin.Mac.dll"); } else { throw ErrorHelper.CreateError(1053, target_framework); } } if (target_framework == TargetFramework.Xamarin_Mac_2_0_Mobile) { skipSystemDrawing = true; references.Add("Facades/System.Drawing.Common"); ReferenceFixer.FixSDKReferences(GetSDKRoot(), "lib/mono/Xamarin.Mac", references); } else if (target_framework == TargetFramework.Xamarin_Mac_4_5_Full) { skipSystemDrawing = true; references.Add("Facades/System.Drawing.Common"); ReferenceFixer.FixSDKReferences(GetSDKRoot(), "lib/mono/4.5", references); } else if (target_framework == TargetFramework.Xamarin_Mac_4_5_System) { skipSystemDrawing = false; ReferenceFixer.FixSDKReferences("/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5", references, forceSystemDrawing: true); } else if (target_framework == TargetFramework.DotNet_5_0_macOS) { skipSystemDrawing = false; } else { throw ErrorHelper.CreateError(1053, target_framework); } break; default: throw ErrorHelper.CreateError(1053, target_framework); } if (sources.Count > 0) { api_sources.Insert(0, sources [0]); for (int i = 1; i < sources.Count; i++) { core_sources.Insert(i - 1, sources [i]); } } if (api_sources.Count == 0) { Console.WriteLine("Error: no api file provided"); ShowHelp(os); return(1); } if (tmpdir == null) { tmpdir = GetWorkDir(); } string firstApiDefinitionName = Path.GetFileNameWithoutExtension(api_sources [0]); firstApiDefinitionName = firstApiDefinitionName.Replace('-', '_'); // This is not exhaustive, but common. if (outfile == null) { outfile = firstApiDefinitionName + ".dll"; } var refs = references.Select((v) => "-r:" + v); var paths = libs.Select((v) => "-lib:" + v); try { var tmpass = Path.Combine(tmpdir, "temp.dll"); // -nowarn:436 is to avoid conflicts in definitions between core.dll and the sources // Keep source files at the end of the command line - csc will create TWO assemblies if any sources preceed the -out parameter var cargs = new List <string> (); cargs.Add("-debug"); cargs.Add("-unsafe"); cargs.Add("-target:library"); cargs.Add("-nowarn:436"); cargs.Add("-out:" + tmpass); cargs.Add("-r:" + GetAttributeLibraryPath()); cargs.AddRange(refs); if (unsafef) { cargs.Add("-unsafe"); } cargs.Add("-r:" + baselibdll); foreach (var def in defines) { cargs.Add("-define:" + def); } cargs.AddRange(paths); if (nostdlib) { cargs.Add("-nostdlib"); cargs.Add("-noconfig"); } cargs.AddRange(api_sources); cargs.AddRange(core_sources); if (!string.IsNullOrEmpty(Path.GetDirectoryName(baselibdll))) { cargs.Add("-lib:" + Path.GetDirectoryName(baselibdll)); } if (Driver.RunCommand(compiler, cargs, null, out var compile_output, true, Driver.Verbosity) != 0) { throw ErrorHelper.CreateError(2, $"{compiler} {StringUtils.FormatArguments (cargs)}\n{compile_output}".Replace("\n", "\n\t")); } universe = new MetadataLoadContext( new SearchPathsAssemblyResolver( GetLibraryDirectories().ToArray(), references.ToArray()), "mscorlib" ); Assembly api; try { api = universe.LoadFromAssemblyPath(tmpass); } catch (Exception e) { if (Driver.Verbosity > 0) { Console.WriteLine(e); } Console.Error.WriteLine("Error loading API definition from {0}", tmpass); return(1); } Assembly baselib; try { baselib = universe.LoadFromAssemblyPath(baselibdll); } catch (Exception e) { if (Driver.Verbosity > 0) { Console.WriteLine(e); } Console.Error.WriteLine("Error loading base library {0}", baselibdll); return(1); } AttributeManager = new AttributeManager(this); Frameworks = new Frameworks(CurrentPlatform); // Explicitly load our attribute library so that IKVM doesn't try (and fail) to find it. universe.LoadFromAssemblyPath(GetAttributeLibraryPath()); TypeManager.Initialize(this, api, universe.CoreAssembly, baselib); foreach (var linkWith in AttributeManager.GetCustomAttributes <LinkWithAttribute> (api)) { if (!linkwith.Contains(linkWith.LibraryName)) { Console.Error.WriteLine("Missing native library {0}, please use `--link-with' to specify the path to this library.", linkWith.LibraryName); return(1); } } foreach (var r in references) { // IKVM has a bug where it doesn't correctly compare assemblies, which means it // can end up loading the same assembly (in particular any System.Runtime whose // version > 4.0, but likely others as well) more than once. This is bad, because // we compare types based on reference equality, which breaks down when there are // multiple instances of the same type. // // So just don't ask IKVM to load assemblies that have already been loaded. var fn = Path.GetFileNameWithoutExtension(r); var assemblies = universe.GetAssemblies(); if (assemblies.Any((v) => v.GetName().Name == fn)) { continue; } if (File.Exists(r)) { try { universe.LoadFromAssemblyPath(r); } catch (Exception ex) { ErrorHelper.Warning(1104, r, ex.Message); } } } var types = new List <Type> (); var strong_dictionaries = new List <Type> (); foreach (var t in api.GetTypes()) { if ((process_enums && t.IsEnum) || AttributeManager.HasAttribute <BaseTypeAttribute> (t) || AttributeManager.HasAttribute <ProtocolAttribute> (t) || AttributeManager.HasAttribute <StaticAttribute> (t) || AttributeManager.HasAttribute <PartialAttribute> (t)) { types.Add(t); } if (AttributeManager.HasAttribute <StrongDictionaryAttribute> (t)) { strong_dictionaries.Add(t); } } var nsManager = new NamespaceManager( this, ns == null ? firstApiDefinitionName : ns, skipSystemDrawing ); var g = new Generator(this, nsManager, public_mode, external, debug, types.ToArray(), strong_dictionaries.ToArray()) { BaseDir = basedir != null ? basedir : tmpdir, ZeroCopyStrings = zero_copy, InlineSelectors = inline_selectors ?? (CurrentPlatform != PlatformName.MacOSX), }; g.Go(); if (generate_file_list != null) { using (var f = File.CreateText(generate_file_list)){ foreach (var x in g.GeneratedFiles.OrderBy((v) => v)) { f.WriteLine(x); } } return(0); } cargs.Clear(); if (unsafef) { cargs.Add("-unsafe"); } cargs.Add("-target:library"); cargs.Add("-out:" + outfile); foreach (var def in defines) { cargs.Add("-define:" + def); } cargs.AddRange(g.GeneratedFiles); cargs.AddRange(core_sources); cargs.AddRange(extra_sources); cargs.AddRange(refs); cargs.Add("-r:" + baselibdll); cargs.AddRange(resources); if (nostdlib) { cargs.Add("-nostdlib"); cargs.Add("-noconfig"); } if (!string.IsNullOrEmpty(Path.GetDirectoryName(baselibdll))) { cargs.Add("-lib:" + Path.GetDirectoryName(baselibdll)); } if (Driver.RunCommand(compiler, cargs, null, out var generated_compile_output, true, Driver.Verbosity) != 0) { throw ErrorHelper.CreateError(1000, $"{compiler} {StringUtils.FormatArguments (cargs)}\n{generated_compile_output}".Replace("\n", "\n\t")); } } finally { if (delete_temp) { Directory.Delete(tmpdir, true); } } return(0); }