From 6b3581bb6cbe22a790411665b014ccc5fe8dd533 Mon Sep 17 00:00:00 2001 From: "Frank A. Krueger" Date: Wed, 25 Apr 2018 15:46:01 -0700 Subject: [PATCH] Use custom assembly resolver Before, I was relying on a bit of luck that the resolver would use the correct asms - now I make sure it does. The build step will now fail if a resolution failure occurs - this is better than runtime errors. --- Ooui.Wasm.Build.Tasks/BuildDistTask.cs | 59 ++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/Ooui.Wasm.Build.Tasks/BuildDistTask.cs b/Ooui.Wasm.Build.Tasks/BuildDistTask.cs index 6dd5ce2..bb11585 100644 --- a/Ooui.Wasm.Build.Tasks/BuildDistTask.cs +++ b/Ooui.Wasm.Build.Tasks/BuildDistTask.cs @@ -24,9 +24,12 @@ namespace Ooui.Wasm.Build.Tasks public string OutputPath { get; set; } public string ReferencePath { get; set; } + bool ok = false; + public override bool Execute () { try { + ok = true; InstallSdk (); GetBcl (); CreateDist (); @@ -35,9 +38,10 @@ namespace Ooui.Wasm.Build.Tasks ExtractClientJs (); DiscoverEntryPoint (); GenerateHtml (); - return true; + return ok; } catch (Exception ex) { + Console.WriteLine (ex); Log.LogErrorFromException (ex); return false; } @@ -117,21 +121,24 @@ namespace Ooui.Wasm.Build.Tasks foreach (var r in references) { var name = Path.GetFileName (r); if (bclAssemblies.ContainsKey (name)) { - refpaths.Add (bclAssemblies[name]); + refpaths.Add (bclAssemblies[name]); + //Console.WriteLine ($"+ {name}"); } else { refpaths.Add (r); + //Console.WriteLine ($"- {r}"); } } var asmPath = Path.GetFullPath (Assembly); var pipeline = GetLinkerPipeline (); - using (var context = new LinkContext (pipeline)) { + var resolver = new AsmResolver (this); + using (var context = new LinkContext (pipeline, resolver)) { context.CoreAction = AssemblyAction.CopyUsed; context.UserAction = AssemblyAction.CopyUsed; context.OutputDirectory = managedPath; - context.IgnoreUnresolved = true; + context.IgnoreUnresolved = false; pipeline.PrependStep (new ResolveFromAssemblyStep (asmPath, ResolveFromAssemblyStep.RootVisibility.Any)); @@ -222,7 +229,7 @@ namespace Ooui.Wasm.Build.Tasks p.AppendStep (new PreserveUsingAttributesStep (bclAssemblies.Values.Select (Path.GetFileNameWithoutExtension))); p.AppendStep (new BlacklistStep ()); p.AppendStep (new TypeMapStep ()); - p.AppendStep (new MarkStepWithUnresolvedLogging { Log = Log }); + p.AppendStep (new MarkStepWithUnresolvedLogging (this)); p.AppendStep (new SweepStep ()); p.AppendStep (new CleanStep ()); p.AppendStep (new RegenerateGuidStep ()); @@ -242,16 +249,23 @@ namespace Ooui.Wasm.Build.Tasks class MarkStepWithUnresolvedLogging : MarkStep { - public TaskLoggingHelper Log; + BuildDistTask task; + + public MarkStepWithUnresolvedLogging (BuildDistTask task) + { + this.task = task; + } protected override void HandleUnresolvedType (TypeReference reference) { - Log.LogWarning ($"Failed to resolve type {reference}"); + task.ok = false; + task.Log.LogError ($"Linker failed to resolve type {reference} in {reference.Scope}"); } protected override void HandleUnresolvedMethod (MethodReference reference) { - Log.LogWarning ($"Failed to resolve method {reference}"); + task.ok = false; + task.Log.LogError ($"Linker failed to resolve method {reference}"); } } @@ -326,5 +340,34 @@ namespace Ooui.Wasm.Build.Tasks } Log.LogMessage ($"HTML {htmlPath}"); } + + class AsmResolver : Mono.Linker.AssemblyResolver + { + BuildDistTask task; + + public AsmResolver (BuildDistTask buildDistTask) + { + task = buildDistTask; + } + + public override AssemblyDefinition Resolve (AssemblyNameReference name, ReaderParameters parameters) + { + AssemblyDefinition asm = null; + if (!AssemblyCache.TryGetValue (name.Name, out asm)) { + var path = task.refpaths.FirstOrDefault (x => { + var rname = Path.GetFileNameWithoutExtension (x); + var eq = rname.Equals (name.Name, StringComparison.InvariantCultureIgnoreCase); + return eq; + }); + if (path != null) { + //Console.WriteLine ($"SUCCESS {path}"); + asm = ModuleDefinition.ReadModule (path, parameters).Assembly; + CacheAssembly (asm); + } + return base.Resolve (name, parameters); + } + return asm; + } + } } }