Browse Source

Merge pull request #10199 from workgroupengineering/fixes/build/task/sourcelink

fix: Sourcelink Avalonia.Build.Tasks
pull/10463/head
Max Katz 4 years ago
committed by GitHub
parent
commit
ebca5d3341
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 104
      nukebuild/BuildTasksPatcher.cs

104
nukebuild/BuildTasksPatcher.cs

@ -4,9 +4,58 @@ using System.IO.Compression;
using System.Linq; using System.Linq;
using ILRepacking; using ILRepacking;
using Mono.Cecil; using Mono.Cecil;
using Mono.Cecil.Cil;
public class BuildTasksPatcher public class BuildTasksPatcher
{ {
/// <summary>
/// This helper class, avoid argument null exception
/// when cecil write AssemblyNameDefinition on MemoryStream.
/// </summary>
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<SourceLinkDebugInformation>()?.FirstOrDefault() is { } sli)
{
return sli.Content;
}
}
}
catch
{
}
return null;
}
public static void PatchBuildTasksInPackage(string packagePath) public static void PatchBuildTasksInPackage(string packagePath)
{ {
using (var archive = new ZipArchive(File.Open(packagePath, FileMode.Open, FileAccess.ReadWrite), 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()); var tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
Directory.CreateDirectory(tempDir); Directory.CreateDirectory(tempDir);
var temp = Path.Combine(tempDir, Guid.NewGuid() + ".dll"); var temp = Path.Combine(tempDir, entry.Name);
var output = temp + ".output"; var output = temp + ".output";
File.Copy(typeof(Microsoft.Build.Framework.ITask).Assembly.GetModules()[0].FullyQualifiedName, File.Copy(typeof(Microsoft.Build.Framework.ITask).Assembly.GetModules()[0].FullyQualifiedName,
Path.Combine(tempDir, "Microsoft.Build.Framework.dll")); Path.Combine(tempDir, "Microsoft.Build.Framework.dll"));
@ -27,41 +76,74 @@ public class BuildTasksPatcher
try try
{ {
entry.ExtractToFile(temp, true); entry.ExtractToFile(temp, true);
// Get Original SourceLinkInfo Content
var sourceLinkInfoContent = GetSourceLinkInfo(temp);
var repack = new ILRepacking.ILRepack(new RepackOptions() var repack = new ILRepacking.ILRepack(new RepackOptions()
{ {
Internalize = true, Internalize = true,
InputAssemblies = new[] InputAssemblies = new[]
{ {
temp, typeof(Mono.Cecil.AssemblyDefinition).Assembly.GetModules()[0] temp,
.FullyQualifiedName, typeof(Mono.Cecil.AssemblyDefinition).Assembly.GetModules()[0].FullyQualifiedName,
typeof(Mono.Cecil.Rocks.MethodBodyRocks).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.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<string>(),
DebugInfo = true, // Allowed read debug info
OutputFile = output OutputFile = output
}); });
repack.Repack(); repack.Repack();
// 'hurr-durr assembly with the same name is already loaded' prevention // 'hurr-durr assembly with the same name is already loaded' prevention
using (var asm = AssemblyDefinition.ReadAssembly(output, 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( asm.Name = new AssemblyNameDefinition(
"Avalonia.Build.Tasks." "Avalonia.Build.Tasks."
+ Guid.NewGuid().ToString().Replace("-", ""), + Guid.NewGuid().ToString().Replace("-", ""),
new Version(0, 0, 0)); 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; patched.Position = 0;
} }
} }
finally finally
{ {
try try
{ {
if(Directory.Exists(tempDir)) if (Directory.Exists(tempDir))
Directory.Delete(tempDir, true); Directory.Delete(tempDir, true);
} }
catch catch
@ -79,4 +161,4 @@ public class BuildTasksPatcher
} }
} }
} }
} }

Loading…
Cancel
Save