|
|
@ -1,13 +1,10 @@ |
|
|
using System; |
|
|
using System; |
|
|
using System.Collections.Generic; |
|
|
|
|
|
using System.IO; |
|
|
using System.IO; |
|
|
using System.Linq; |
|
|
using System.Linq; |
|
|
using System.Reflection; |
|
|
using System.Reflection; |
|
|
using System.Text; |
|
|
|
|
|
using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions; |
|
|
using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions; |
|
|
using Microsoft.Build.Framework; |
|
|
using Microsoft.Build.Framework; |
|
|
using Mono.Cecil; |
|
|
using Mono.Cecil; |
|
|
using Avalonia.Utilities; |
|
|
|
|
|
using Mono.Cecil.Cil; |
|
|
using Mono.Cecil.Cil; |
|
|
using Mono.Cecil.Rocks; |
|
|
using Mono.Cecil.Rocks; |
|
|
using XamlX; |
|
|
using XamlX; |
|
|
@ -44,16 +41,23 @@ namespace Avalonia.Build.Tasks |
|
|
string projectDirectory, |
|
|
string projectDirectory, |
|
|
string output, bool verifyIl, MessageImportance logImportance, string strongNameKey, bool patchCom, |
|
|
string output, bool verifyIl, MessageImportance logImportance, string strongNameKey, bool patchCom, |
|
|
bool skipXamlCompilation) |
|
|
bool skipXamlCompilation) |
|
|
|
|
|
{ |
|
|
|
|
|
return Compile(engine, input, references, projectDirectory, output, verifyIl, logImportance, strongNameKey, patchCom, skipXamlCompilation, debuggerLaunch:false); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
internal static CompileResult Compile(IBuildEngine engine, string input, string[] references, |
|
|
|
|
|
string projectDirectory, |
|
|
|
|
|
string output, bool verifyIl, MessageImportance logImportance, string strongNameKey, bool patchCom, bool skipXamlCompilation, bool debuggerLaunch) |
|
|
{ |
|
|
{ |
|
|
var typeSystem = new CecilTypeSystem(references |
|
|
var typeSystem = new CecilTypeSystem(references |
|
|
.Where(r => !r.ToLowerInvariant().EndsWith("avalonia.build.tasks.dll")) |
|
|
.Where(r => !r.ToLowerInvariant().EndsWith("avalonia.build.tasks.dll")) |
|
|
.Concat(new[] { input }), input); |
|
|
.Concat(new[] { input }), input); |
|
|
|
|
|
|
|
|
var asm = typeSystem.TargetAssemblyDefinition; |
|
|
var asm = typeSystem.TargetAssemblyDefinition; |
|
|
|
|
|
|
|
|
if (!skipXamlCompilation) |
|
|
if (!skipXamlCompilation) |
|
|
{ |
|
|
{ |
|
|
var compileRes = CompileCore(engine, typeSystem, projectDirectory, verifyIl, logImportance); |
|
|
var compileRes = CompileCore(engine, typeSystem, projectDirectory, verifyIl, logImportance, debuggerLaunch); |
|
|
if (compileRes == null && !patchCom) |
|
|
if (compileRes == null && !patchCom) |
|
|
return new CompileResult(true); |
|
|
return new CompileResult(true); |
|
|
if (compileRes == false) |
|
|
if (compileRes == false) |
|
|
@ -62,7 +66,7 @@ namespace Avalonia.Build.Tasks |
|
|
|
|
|
|
|
|
if (patchCom) |
|
|
if (patchCom) |
|
|
ComInteropHelper.PatchAssembly(asm, typeSystem); |
|
|
ComInteropHelper.PatchAssembly(asm, typeSystem); |
|
|
|
|
|
|
|
|
var writerParameters = new WriterParameters { WriteSymbols = asm.MainModule.HasSymbols }; |
|
|
var writerParameters = new WriterParameters { WriteSymbols = asm.MainModule.HasSymbols }; |
|
|
if (!string.IsNullOrWhiteSpace(strongNameKey)) |
|
|
if (!string.IsNullOrWhiteSpace(strongNameKey)) |
|
|
writerParameters.StrongNameKeyBlob = File.ReadAllBytes(strongNameKey); |
|
|
writerParameters.StrongNameKeyBlob = File.ReadAllBytes(strongNameKey); |
|
|
@ -70,13 +74,43 @@ namespace Avalonia.Build.Tasks |
|
|
asm.Write(output, writerParameters); |
|
|
asm.Write(output, writerParameters); |
|
|
|
|
|
|
|
|
return new CompileResult(true, true); |
|
|
return new CompileResult(true, true); |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static bool? CompileCore(IBuildEngine engine, CecilTypeSystem typeSystem, |
|
|
static bool? CompileCore(IBuildEngine engine, CecilTypeSystem typeSystem, |
|
|
string projectDirectory, bool verifyIl, |
|
|
string projectDirectory, bool verifyIl, |
|
|
MessageImportance logImportance) |
|
|
MessageImportance logImportance |
|
|
|
|
|
, bool debuggerLaunch = false) |
|
|
{ |
|
|
{ |
|
|
|
|
|
if (debuggerLaunch) |
|
|
|
|
|
{ |
|
|
|
|
|
// According this https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.debugger.launch?view=net-6.0#remarks
|
|
|
|
|
|
// documentation, on not windows platform Debugger.Launch() always return true without running a debugger.
|
|
|
|
|
|
if (System.Diagnostics.Debugger.Launch()) |
|
|
|
|
|
{ |
|
|
|
|
|
// Set timeout at 1 minut.
|
|
|
|
|
|
var time = new System.Diagnostics.Stopwatch(); |
|
|
|
|
|
var timeout = TimeSpan.FromMinutes(1); |
|
|
|
|
|
time.Start(); |
|
|
|
|
|
|
|
|
|
|
|
// wait for the debugger to be attacked or timeout.
|
|
|
|
|
|
while (!System.Diagnostics.Debugger.IsAttached && time.Elapsed < timeout) |
|
|
|
|
|
{ |
|
|
|
|
|
engine.LogMessage($"[PID:{System.Diagnostics.Process.GetCurrentProcess().Id}] Wating attach debugger. Elapsed {time.Elapsed}...", MessageImportance.High); |
|
|
|
|
|
System.Threading.Thread.Sleep(100); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
time.Stop(); |
|
|
|
|
|
if (time.Elapsed >= timeout) |
|
|
|
|
|
{ |
|
|
|
|
|
engine.LogMessage("Wating attach debugger timeout.", MessageImportance.Normal); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
engine.LogMessage("Debugging cancelled.", MessageImportance.Normal); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
var asm = typeSystem.TargetAssemblyDefinition; |
|
|
var asm = typeSystem.TargetAssemblyDefinition; |
|
|
var emres = new EmbeddedResources(asm); |
|
|
var emres = new EmbeddedResources(asm); |
|
|
var avares = new AvaloniaResources(asm, projectDirectory); |
|
|
var avares = new AvaloniaResources(asm, projectDirectory); |
|
|
|