diff --git a/nukebuild/BuildTasksPatcher.cs b/nukebuild/BuildTasksPatcher.cs
index 5fd331035a..f2dd217657 100644
--- a/nukebuild/BuildTasksPatcher.cs
+++ b/nukebuild/BuildTasksPatcher.cs
@@ -4,9 +4,58 @@ using System.IO.Compression;
using System.Linq;
using ILRepacking;
using Mono.Cecil;
+using Mono.Cecil.Cil;
public class BuildTasksPatcher
{
+ ///
+ /// This helper class, avoid argument null exception
+ /// when cecil write AssemblyNameDefinition on MemoryStream.
+ ///
+ private class Wrapper : ISymbolWriterProvider
+ {
+ readonly ISymbolWriterProvider _provider;
+ readonly string _filename;
+
+ public Wrapper(ISymbolWriterProvider provider, string filename)
+ {
+ _provider = provider;
+ _filename = filename;
+ }
+
+ public ISymbolWriter GetSymbolWriter(ModuleDefinition module, string fileName) =>
+ _provider.GetSymbolWriter(module, string.IsNullOrWhiteSpace(fileName) ? _filename : fileName);
+
+ public ISymbolWriter GetSymbolWriter(ModuleDefinition module, Stream symbolStream) =>
+ _provider.GetSymbolWriter(module, symbolStream);
+ }
+
+ private static string GetSourceLinkInfo(string path)
+ {
+ try
+ {
+ using (var asm = AssemblyDefinition.ReadAssembly(path,
+ new ReaderParameters
+ {
+ ReadWrite = true,
+ InMemory = true,
+ ReadSymbols = true,
+ SymbolReaderProvider = new DefaultSymbolReaderProvider(false),
+ }))
+ {
+ if (asm.MainModule.CustomDebugInformations?.OfType()?.FirstOrDefault() is { } sli)
+ {
+ return sli.Content;
+ }
+ }
+ }
+ catch
+ {
+
+ }
+ return null;
+ }
+
public static void PatchBuildTasksInPackage(string packagePath)
{
using (var archive = new ZipArchive(File.Open(packagePath, FileMode.Open, FileAccess.ReadWrite),
@@ -19,7 +68,7 @@ public class BuildTasksPatcher
{
var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempDir);
- var temp = Path.Combine(tempDir, Guid.NewGuid() + ".dll");
+ var temp = Path.Combine(tempDir, entry.Name);
var output = temp + ".output";
File.Copy(typeof(Microsoft.Build.Framework.ITask).Assembly.GetModules()[0].FullyQualifiedName,
Path.Combine(tempDir, "Microsoft.Build.Framework.dll"));
@@ -27,41 +76,74 @@ public class BuildTasksPatcher
try
{
entry.ExtractToFile(temp, true);
+ // Get Original SourceLinkInfo Content
+ var sourceLinkInfoContent = GetSourceLinkInfo(temp);
var repack = new ILRepacking.ILRepack(new RepackOptions()
{
Internalize = true,
InputAssemblies = new[]
{
- temp, typeof(Mono.Cecil.AssemblyDefinition).Assembly.GetModules()[0]
- .FullyQualifiedName,
+ temp,
+ typeof(Mono.Cecil.AssemblyDefinition).Assembly.GetModules()[0].FullyQualifiedName,
typeof(Mono.Cecil.Rocks.MethodBodyRocks).Assembly.GetModules()[0].FullyQualifiedName,
typeof(Mono.Cecil.Pdb.PdbReaderProvider).Assembly.GetModules()[0].FullyQualifiedName,
- typeof(Mono.Cecil.Mdb.MdbReaderProvider).Assembly.GetModules()[0].FullyQualifiedName
-
+ typeof(Mono.Cecil.Mdb.MdbReaderProvider).Assembly.GetModules()[0].FullyQualifiedName,
},
- SearchDirectories = new string[0],
+ SearchDirectories = Array.Empty(),
+ DebugInfo = true, // Allowed read debug info
OutputFile = output
});
repack.Repack();
-
// 'hurr-durr assembly with the same name is already loaded' prevention
using (var asm = AssemblyDefinition.ReadAssembly(output,
- new ReaderParameters { ReadWrite = true, InMemory = true, }))
+ new ReaderParameters
+ {
+ ReadWrite = true,
+ InMemory = true,
+ ReadSymbols = true,
+ SymbolReaderProvider = new DefaultSymbolReaderProvider(false),
+ }))
{
asm.Name = new AssemblyNameDefinition(
"Avalonia.Build.Tasks."
+ Guid.NewGuid().ToString().Replace("-", ""),
new Version(0, 0, 0));
- asm.Write(patched);
+
+ var mainModule = asm.MainModule;
+
+ // If we have SourceLink info copy to patched assembly.
+ if (!string.IsNullOrEmpty(sourceLinkInfoContent))
+ {
+ mainModule.CustomDebugInformations.Add(new SourceLinkDebugInformation(sourceLinkInfoContent));
+ }
+
+ // Try to get SymbolWriter if it has it
+ var reader = mainModule.SymbolReader;
+ var hasDebugInfo = reader is not null;
+ var proivder = reader?.GetWriterProvider() is ISymbolWriterProvider p
+ ? new Wrapper(p, "Avalonia.Build.Tasks.dll")
+ : default(ISymbolWriterProvider);
+
+ var parameters = new WriterParameters
+ {
+#if ISNETFULLFRAMEWORK
+ StrongNameKeyPair = signingStep.KeyPair,
+#endif
+ WriteSymbols = hasDebugInfo,
+ SymbolWriterProvider = proivder,
+ DeterministicMvid = hasDebugInfo,
+ };
+ asm.Write(patched, parameters);
patched.Position = 0;
}
+
}
finally
{
try
{
- if(Directory.Exists(tempDir))
+ if (Directory.Exists(tempDir))
Directory.Delete(tempDir, true);
}
catch
@@ -79,4 +161,4 @@ public class BuildTasksPatcher
}
}
}
-}
\ No newline at end of file
+}