Skip to content

Commit 3dba0e0

Browse files
committed
Merge pull request #6972 from workgroupengineering/features/Issue_6971
feat: Allow to debug XamlIl Compilation
1 parent 5a4955a commit 3dba0e0

File tree

3 files changed

+48
-13
lines changed

3 files changed

+48
-13
lines changed

packages/Avalonia/AvaloniaBuildTasks.targets

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
<AvaloniaXamlReferencesTemporaryFilePath Condition="'$(AvaloniaXamlReferencesTemporaryFilePath)' == ''">$(IntermediateOutputPath)/Avalonia/references</AvaloniaXamlReferencesTemporaryFilePath>
8989
<AvaloniaXamlOriginalCopyFilePath Condition="'$(AvaloniaXamlOriginalCopyFilePath)' == ''">$(IntermediateOutputPath)/Avalonia/original.dll</AvaloniaXamlOriginalCopyFilePath>
9090
<AvaloniaXamlIlVerifyIl Condition="'$(AvaloniaXamlIlVerifyIl)' == ''">false</AvaloniaXamlIlVerifyIl>
91+
<AvaloniaXamlIlDebuggerLaunch Condition="'$(AvaloniaXamlIlDebuggerLaunch)' == ''">false</AvaloniaXamlIlDebuggerLaunch>
9192
</PropertyGroup>
9293
<WriteLinesToFile
9394
Condition="'$(_AvaloniaForceInternalMSBuild)' != 'true'"
@@ -107,6 +108,7 @@
107108
DelaySign="$(DelaySign)"
108109
EnableComInteropPatching="$(_AvaloniaPatchComInterop)"
109110
SkipXamlCompilation="$(_AvaloniaSkipXamlCompilation)"
111+
DebuggerLaunch="$(AvaloniaXamlIlDebuggerLaunch)"
110112
/>
111113
<Exec
112114
Condition="'$(_AvaloniaUseExternalMSBuild)' == 'true'"

src/Avalonia.Build.Tasks/CompileAvaloniaXamlTask.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
using System;
2-
using System.Diagnostics;
32
using System.IO;
43
using System.Linq;
5-
using System.Reflection;
6-
using System.Threading;
74
using Microsoft.Build.Framework;
85

96
namespace Avalonia.Build.Tasks
@@ -41,7 +38,7 @@ public bool Execute()
4138
File.ReadAllLines(ReferencesFilePath).Where(l => !string.IsNullOrWhiteSpace(l)).ToArray(),
4239
ProjectDirectory, OutputPath, VerifyIl, outputImportance,
4340
(SignAssembly && !DelaySign) ? AssemblyOriginatorKeyFile : null,
44-
EnableComInteropPatching, SkipXamlCompilation);
41+
EnableComInteropPatching, SkipXamlCompilation, DebuggerLaunch);
4542
if (!res.Success)
4643
return false;
4744
if (!res.WrittenFile)
@@ -87,5 +84,7 @@ string GetPdbPath(string p)
8784

8885
public IBuildEngine BuildEngine { get; set; }
8986
public ITaskHost HostObject { get; set; }
87+
88+
public bool DebuggerLaunch { get; set; }
9089
}
9190
}

src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.IO;
43
using System.Linq;
54
using System.Reflection;
6-
using System.Text;
75
using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions;
86
using Microsoft.Build.Framework;
97
using Mono.Cecil;
10-
using Avalonia.Utilities;
118
using Mono.Cecil.Cil;
129
using Mono.Cecil.Rocks;
1310
using XamlX;
@@ -44,16 +41,23 @@ public static CompileResult Compile(IBuildEngine engine, string input, string[]
4441
string projectDirectory,
4542
string output, bool verifyIl, MessageImportance logImportance, string strongNameKey, bool patchCom,
4643
bool skipXamlCompilation)
44+
{
45+
return Compile(engine, input, references, projectDirectory, output, verifyIl, logImportance, strongNameKey, patchCom, skipXamlCompilation, debuggerLaunch:false);
46+
}
47+
48+
internal static CompileResult Compile(IBuildEngine engine, string input, string[] references,
49+
string projectDirectory,
50+
string output, bool verifyIl, MessageImportance logImportance, string strongNameKey, bool patchCom, bool skipXamlCompilation, bool debuggerLaunch)
4751
{
4852
var typeSystem = new CecilTypeSystem(references
4953
.Where(r => !r.ToLowerInvariant().EndsWith("avalonia.build.tasks.dll"))
5054
.Concat(new[] { input }), input);
51-
55+
5256
var asm = typeSystem.TargetAssemblyDefinition;
5357

5458
if (!skipXamlCompilation)
5559
{
56-
var compileRes = CompileCore(engine, typeSystem, projectDirectory, verifyIl, logImportance);
60+
var compileRes = CompileCore(engine, typeSystem, projectDirectory, verifyIl, logImportance, debuggerLaunch);
5761
if (compileRes == null && !patchCom)
5862
return new CompileResult(true);
5963
if (compileRes == false)
@@ -62,21 +66,51 @@ public static CompileResult Compile(IBuildEngine engine, string input, string[]
6266

6367
if (patchCom)
6468
ComInteropHelper.PatchAssembly(asm, typeSystem);
65-
69+
6670
var writerParameters = new WriterParameters { WriteSymbols = asm.MainModule.HasSymbols };
6771
if (!string.IsNullOrWhiteSpace(strongNameKey))
6872
writerParameters.StrongNameKeyBlob = File.ReadAllBytes(strongNameKey);
6973

7074
asm.Write(output, writerParameters);
7175

7276
return new CompileResult(true, true);
73-
77+
7478
}
75-
79+
7680
static bool? CompileCore(IBuildEngine engine, CecilTypeSystem typeSystem,
7781
string projectDirectory, bool verifyIl,
78-
MessageImportance logImportance)
82+
MessageImportance logImportance
83+
, bool debuggerLaunch = false)
7984
{
85+
if (debuggerLaunch)
86+
{
87+
// According this https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.debugger.launch?view=net-6.0#remarks
88+
// documentation, on not windows platform Debugger.Launch() always return true without running a debugger.
89+
if (System.Diagnostics.Debugger.Launch())
90+
{
91+
// Set timeout at 1 minut.
92+
var time = new System.Diagnostics.Stopwatch();
93+
var timeout = TimeSpan.FromMinutes(1);
94+
time.Start();
95+
96+
// wait for the debugger to be attacked or timeout.
97+
while (!System.Diagnostics.Debugger.IsAttached && time.Elapsed < timeout)
98+
{
99+
engine.LogMessage($"[PID:{System.Diagnostics.Process.GetCurrentProcess().Id}] Wating attach debugger. Elapsed {time.Elapsed}...", MessageImportance.High);
100+
System.Threading.Thread.Sleep(100);
101+
}
102+
103+
time.Stop();
104+
if (time.Elapsed >= timeout)
105+
{
106+
engine.LogMessage("Wating attach debugger timeout.", MessageImportance.Normal);
107+
}
108+
}
109+
else
110+
{
111+
engine.LogMessage("Debugging cancelled.", MessageImportance.Normal);
112+
}
113+
}
80114
var asm = typeSystem.TargetAssemblyDefinition;
81115
var emres = new EmbeddedResources(asm);
82116
var avares = new AvaloniaResources(asm, projectDirectory);

0 commit comments

Comments
 (0)