diff --git a/src/IKVM.MSBuild.Tasks/IkvmCompiler.cs b/src/IKVM.MSBuild.Tasks/IkvmCompiler.cs index c9cd734161..38cf9f4fda 100644 --- a/src/IKVM.MSBuild.Tasks/IkvmCompiler.cs +++ b/src/IKVM.MSBuild.Tasks/IkvmCompiler.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Threading; @@ -135,6 +136,8 @@ public class IkvmCompiler : IkvmToolExecTask public string Remap { get; set; } + string GetAbsolutePathIfNotNull(string path) => path != null ? Path.GetFullPath(path) : null; + protected override async Task ExecuteAsync(IkvmToolTaskDiagnosticWriter writer, CancellationToken cancellationToken) { if (Debug && RuntimeInformation.IsOSPlatform(OSPlatform.Windows) == false) @@ -144,8 +147,8 @@ protected override async Task ExecuteAsync(IkvmToolTaskDiagnosticWriter wr } var options = new IkvmCompilerOptions(); - options.ResponseFile = ResponseFile; - options.Output = Output; + options.ResponseFile = GetAbsolutePathIfNotNull(ResponseFile); + options.Output = GetAbsolutePathIfNotNull(Output); options.Assembly = Assembly; options.Version = Version; @@ -171,14 +174,14 @@ protected override async Task ExecuteAsync(IkvmToolTaskDiagnosticWriter wr _ => throw new NotImplementedException(), }; - options.KeyFile = KeyFile; + options.KeyFile = GetAbsolutePathIfNotNull(KeyFile); options.Key = Key; options.DelaySign = DelaySign; if (References is not null) - foreach (var reference in References) - if (options.References.Contains(reference.ItemSpec) == false) - options.References.Add(reference.ItemSpec); + foreach (var reference in References.Select(i => GetAbsolutePathIfNotNull(i.ItemSpec))) + if (options.References.Contains(reference) == false) + options.References.Add(reference); if (Recurse is not null) foreach (var recurse in Recurse) @@ -191,11 +194,11 @@ protected override async Task ExecuteAsync(IkvmToolTaskDiagnosticWriter wr if (Resources is not null) foreach (var resource in Resources) - options.Resources.Add(new IkvmCompilerResourceItem(resource.ItemSpec, resource.GetMetadata("ResourcePath"))); + options.Resources.Add(new IkvmCompilerResourceItem(GetAbsolutePathIfNotNull(resource.ItemSpec), resource.GetMetadata("ResourcePath"))); if (ExternalResources is not null) foreach (var resource in ExternalResources) - options.ExternalResources.Add(new IkvmCompilerExternalResourceItem(resource.ItemSpec, resource.GetMetadata("ResourcePath"))); + options.ExternalResources.Add(new IkvmCompilerExternalResourceItem(GetAbsolutePathIfNotNull(resource.ItemSpec), resource.GetMetadata("ResourcePath"))); options.CompressResources = CompressResources; options.Debug = Debug; @@ -248,7 +251,7 @@ protected override async Task ExecuteAsync(IkvmToolTaskDiagnosticWriter wr if (Lib is not null) foreach (var i in Lib) - options.Lib.Add(i.ItemSpec); + options.Lib.Add(GetAbsolutePathIfNotNull(i.ItemSpec)); options.HighEntropyVA = HighEntropyVA; options.Static = Static; @@ -257,17 +260,17 @@ protected override async Task ExecuteAsync(IkvmToolTaskDiagnosticWriter wr foreach (var i in AssemblyAttributes) options.AssemblyAttributes.Add(i.ItemSpec); - options.Runtime = Runtime; + options.Runtime = GetAbsolutePathIfNotNull(Runtime); if (options.WarningLevel is not null) options.WarningLevel = int.Parse(WarningLevel); options.NoParameterReflection = NoParameterReflection; - options.Remap = Remap; + options.Remap = GetAbsolutePathIfNotNull(Remap); if (Input != null) foreach (var i in Input) - options.Input.Add(i.ItemSpec); + options.Input.Add(GetAbsolutePathIfNotNull(i.ItemSpec)); // kick off the launcher with the configured options return await new IkvmCompilerLauncher(ToolPath, writer).ExecuteAsync(options, cancellationToken) == 0; diff --git a/src/IKVM.MSBuild.Tasks/IkvmToolExecTask.cs b/src/IKVM.MSBuild.Tasks/IkvmToolExecTask.cs index a3530daf3a..5ebbd20137 100644 --- a/src/IKVM.MSBuild.Tasks/IkvmToolExecTask.cs +++ b/src/IKVM.MSBuild.Tasks/IkvmToolExecTask.cs @@ -72,7 +72,7 @@ public override bool Execute() log = new StreamWriter(File.OpenWrite(LogFile)); // kick off the launcher with the configured options - var run = System.Threading.Tasks.Task.Run(() => ExecuteAsync(new IkvmToolTaskDiagnosticWriter(Log, log), CancellationToken.None)); + var run = ExecuteAsync(new IkvmToolTaskDiagnosticWriter(Log, log), CancellationToken.None); // yield and wait for the task to complete BuildEngine3.Yield(); diff --git a/src/IKVM.MSBuild.Tasks/IkvmToolTaskDiagnosticWriter.cs b/src/IKVM.MSBuild.Tasks/IkvmToolTaskDiagnosticWriter.cs index ba32667f87..66bad6ec2b 100644 --- a/src/IKVM.MSBuild.Tasks/IkvmToolTaskDiagnosticWriter.cs +++ b/src/IKVM.MSBuild.Tasks/IkvmToolTaskDiagnosticWriter.cs @@ -35,28 +35,34 @@ public IkvmToolTaskDiagnosticWriter(Microsoft.Build.Utilities.TaskLoggingHelper /// public Task ReceiveAsync(IkvmToolDiagnosticEvent @event) { - switch (@event.Level) + if (@event == null) + return Task.CompletedTask; + + try + { + switch (@event.Level) + { + case IkvmToolDiagnosticEventLevel.Debug: + logger.LogMessage(Microsoft.Build.Framework.MessageImportance.Low, @event.Message, @event.MessageArgs); + writer?.WriteLine("DEBUG: " + @event.Message, @event.MessageArgs); + break; + case IkvmToolDiagnosticEventLevel.Information: + logger.LogMessage(Microsoft.Build.Framework.MessageImportance.Normal, @event.Message, @event.MessageArgs); + writer?.WriteLine("INFO: " + @event.Message, @event.MessageArgs); + break; + case IkvmToolDiagnosticEventLevel.Warning: + logger.LogWarning(@event.Message, @event.MessageArgs); + writer?.WriteLine("WARN: " + @event.Message, @event.MessageArgs); + break; + case IkvmToolDiagnosticEventLevel.Error: + logger.LogWarning(@event.Message, @event.MessageArgs); + writer?.WriteLine("ERROR: " + @event.Message, @event.MessageArgs); + break; + } + } + catch (Exception e) { - case IkvmToolDiagnosticEventLevel.Debug: - logger.LogMessage(Microsoft.Build.Framework.MessageImportance.Low, @event.Message, @event.MessageArgs); - if (writer != null) - writer.WriteLine("DEBUG: " + @event.Message, @event.MessageArgs); - break; - case IkvmToolDiagnosticEventLevel.Information: - logger.LogMessage(Microsoft.Build.Framework.MessageImportance.Normal, @event.Message, @event.MessageArgs); - if (writer != null) - writer.WriteLine("INFO: " + @event.Message, @event.MessageArgs); - break; - case IkvmToolDiagnosticEventLevel.Warning: - logger.LogWarning(@event.Message, @event.MessageArgs); - if (writer != null) - writer.WriteLine("WARN: " + @event.Message, @event.MessageArgs); - break; - case IkvmToolDiagnosticEventLevel.Error: - logger.LogWarning(@event.Message, @event.MessageArgs); - if (writer != null) - writer.WriteLine("ERROR: " + @event.Message, @event.MessageArgs); - break; + // ignore failure to log, not much we can do } return Task.CompletedTask; diff --git a/src/IKVM.Tools.Runner/Compiler/IkvmCompilerLauncher.cs b/src/IKVM.Tools.Runner/Compiler/IkvmCompilerLauncher.cs index 939b424bca..3b9c13e761 100644 --- a/src/IKVM.Tools.Runner/Compiler/IkvmCompilerLauncher.cs +++ b/src/IKVM.Tools.Runner/Compiler/IkvmCompilerLauncher.cs @@ -58,7 +58,6 @@ public IkvmCompilerLauncher(string toolPath) : /// /// /// - /// public async Task ExecuteAsync(IkvmCompilerOptions options, CancellationToken cancellationToken = default) { if (options is null) @@ -248,15 +247,17 @@ public async Task ExecuteAsync(IkvmCompilerOptions options, CancellationTok foreach (var i in options.Input) w.WriteLine(i); - // path to the temporary response file - var response = (string)null; + // prepare path to response file + var response = string.IsNullOrWhiteSpace(options.ResponseFile) == false ? Path.GetFullPath(options.ResponseFile) : Path.GetTempFileName(); + + // to cancel the executable var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, new CancellationToken()); try { // create response file - response = options.ResponseFile ?? Path.GetTempFileName(); - File.WriteAllText(response, w.ToString()); + Directory.CreateDirectory(Path.GetDirectoryName(response)); + File.WriteAllText(options.ResponseFile, w.ToString()); // locate EXE file var exe = GetToolExe();