diff --git a/src/IKVM.MSBuild.Tasks/IkvmCompiler.cs b/src/IKVM.MSBuild.Tasks/IkvmCompiler.cs
index 5258b160b8..1c84a19ea7 100644
--- a/src/IKVM.MSBuild.Tasks/IkvmCompiler.cs
+++ b/src/IKVM.MSBuild.Tasks/IkvmCompiler.cs
@@ -35,30 +35,63 @@ public class IkvmCompiler : IkvmToolExecTask
[Required]
public string Output { get; set; }
+ ///
+ /// Name of the assembly to output.
+ ///
public string Assembly { get; set; }
+ ///
+ /// Version of the assembly to output.
+ ///
public string Version { get; set; }
+ ///
+ /// Target type of the assembly to output.
+ ///
public string Target { get; set; }
+ ///
+ /// Platform of the assembly to output.
+ ///
public string Platform { get; set; }
+ ///
+ /// Key file with which to strong name the generated assembly.
+ ///
public string KeyFile { get; set; }
+ ///
+ /// Key with which to strong name the generated assembly.
+ ///
public string Key { get; set; }
public bool DelaySign { get; set; }
+ ///
+ /// References to use when compiling.
+ ///
public ITaskItem[] References { get; set; }
public ITaskItem[] Recurse { get; set; }
+ ///
+ /// Path to class exclusion file.
+ ///
public string Exclude { get; set; }
+ ///
+ /// File version of assembly to output.
+ ///
public string FileVersion { get; set; }
+ ///
+ /// Path to the Win32 icon file.
+ ///
public string Win32Icon { get; set; }
+ ///
+ /// Path to the Win32 manifest file.
+ ///
public string Win32Manifest { get; set; }
public ITaskItem[] Resources { get; set; }
@@ -123,19 +156,88 @@ public class IkvmCompiler : IkvmToolExecTask
public bool Static { get; set; }
+ ///
+ /// Paths to the assembly attributes file.
+ ///
public ITaskItem[] AssemblyAttributes { get; set; }
+ ///
+ /// Path to the IKVM.Runtime assembly to incorporate.
+ ///
public string Runtime { get; set; }
- public string JNI { get; set; }
-
public string WarningLevel { get; set; }
public bool NoParameterReflection { get; set; }
+ ///
+ /// Path to the map.xml file to use.
+ ///
public string Remap { get; set; }
- string GetAbsolutePathIfNotNull(string path) => path != null ? Path.GetFullPath(path) : null;
+ public override bool Execute()
+ {
+ if (ResponseFile != null)
+ ResponseFile = Path.GetFullPath(ResponseFile);
+
+ if (Output != null)
+ Output = Path.GetFullPath(Output);
+
+ if (KeyFile != null)
+ KeyFile = Path.GetFullPath(KeyFile);
+
+ if (References != null)
+ foreach (var reference in References)
+ if (reference.ItemSpec != null)
+ reference.ItemSpec = Path.GetFullPath(reference.ItemSpec);
+
+ if (Lib != null)
+ foreach (var lib in Lib)
+ if (lib.ItemSpec != null)
+ lib.ItemSpec = Path.GetFullPath(lib.ItemSpec);
+
+ if (Resources != null)
+ foreach (var i in Resources)
+ if (i.ItemSpec != null)
+ i.ItemSpec = Path.GetFullPath(i.ItemSpec);
+
+ if (ExternalResources != null)
+ foreach (var i in ExternalResources)
+ if (i.ItemSpec != null)
+ i.ItemSpec = Path.GetFullPath(i.ItemSpec);
+
+ if (AssemblyAttributes != null)
+ foreach (var i in AssemblyAttributes)
+ if (i.ItemSpec != null)
+ i.ItemSpec = Path.GetFullPath(i.ItemSpec);
+
+ if (Runtime != null)
+ Runtime = Path.GetFullPath(Runtime);
+
+ if (Remap != null)
+ Remap = Path.GetFullPath(Remap);
+
+ if (Input != null)
+ foreach (var i in Input)
+ if (i.ItemSpec != null)
+ i.ItemSpec = Path.GetFullPath(i.ItemSpec);
+
+ if (Recurse != null)
+ foreach (var i in Recurse)
+ if (i.ItemSpec != null)
+ i.ItemSpec = Path.GetFullPath(i.ItemSpec);
+
+ if (Exclude != null)
+ Exclude = Path.GetFullPath(Exclude);
+
+ if (Win32Icon != null)
+ Win32Icon = Path.GetFullPath(Win32Icon);
+
+ if (Win32Manifest != null)
+ Win32Manifest = Path.GetFullPath(Win32Manifest);
+
+ return base.Execute();
+ }
protected override async Task ExecuteAsync(IkvmToolTaskDiagnosticWriter writer, CancellationToken cancellationToken)
{
@@ -146,8 +248,8 @@ protected override async Task ExecuteAsync(IkvmToolTaskDiagnosticWriter wr
}
var options = new IkvmImporterOptions();
- options.ResponseFile = GetAbsolutePathIfNotNull(ResponseFile);
- options.Output = GetAbsolutePathIfNotNull(Output);
+ options.ResponseFile = ResponseFile;
+ options.Output = Output;
options.Assembly = Assembly;
options.Version = Version;
@@ -173,16 +275,16 @@ protected override async Task ExecuteAsync(IkvmToolTaskDiagnosticWriter wr
_ => throw new NotImplementedException(),
};
- options.KeyFile = GetAbsolutePathIfNotNull(KeyFile);
+ options.KeyFile = KeyFile;
options.Key = Key;
options.DelaySign = DelaySign;
- if (References is not null)
- foreach (var reference in References.Select(i => GetAbsolutePathIfNotNull(i.ItemSpec)))
- if (options.References.Contains(reference) == false)
- options.References.Add(reference);
+ if (References != null)
+ foreach (var reference in References)
+ if (options.References.Contains(reference.ItemSpec) == false)
+ options.References.Add(reference.ItemSpec);
- if (Recurse is not null)
+ if (Recurse != null)
foreach (var recurse in Recurse)
options.Recurse.Add(recurse.ItemSpec);
@@ -193,11 +295,11 @@ protected override async Task ExecuteAsync(IkvmToolTaskDiagnosticWriter wr
if (Resources is not null)
foreach (var resource in Resources)
- options.Resources.Add(new IkvmImporterResourceItem(GetAbsolutePathIfNotNull(resource.ItemSpec), resource.GetMetadata("ResourcePath")));
+ options.Resources.Add(new IkvmImporterResourceItem(resource.ItemSpec, resource.GetMetadata("ResourcePath")));
if (ExternalResources is not null)
foreach (var resource in ExternalResources)
- options.ExternalResources.Add(new IkvmImporterExternalResourceItem(GetAbsolutePathIfNotNull(resource.ItemSpec), resource.GetMetadata("ResourcePath")));
+ options.ExternalResources.Add(new IkvmImporterExternalResourceItem(resource.ItemSpec, resource.GetMetadata("ResourcePath")));
options.CompressResources = CompressResources;
options.Debug = Debug;
@@ -208,13 +310,13 @@ protected override async Task ExecuteAsync(IkvmToolTaskDiagnosticWriter wr
options.RemoveAssertions = RemoveAssertions;
options.StrictFinalFieldSemantics = StrictFinalFieldSemantics;
- if (NoWarn is not null)
+ if (NoWarn != null)
foreach (var i in NoWarn.Split(';'))
options.NoWarn.Add(i);
options.WarnAsError = WarnAsError;
- if (WarnAsErrorWarnings is not null)
+ if (WarnAsErrorWarnings != null)
foreach (var i in WarnAsErrorWarnings.Split(';'))
options.WarnAsErrorWarnings.Add(i);
@@ -223,21 +325,21 @@ protected override async Task ExecuteAsync(IkvmToolTaskDiagnosticWriter wr
options.SrcPath = SrcPath;
options.Apartment = Apartment;
- if (SetProperties is not null)
+ if (SetProperties != null)
foreach (var p in SetProperties.Split(new[] { ';' }).Select(i => i.Split(new[] { '=' }, 2)))
options.SetProperties[p[0]] = p.Length == 2 ? p[1] : "";
options.NoStackTraceInfo = NoStackTraceInfo;
- if (XTrace is not null)
+ if (XTrace != null)
foreach (var i in XTrace.Split(';'))
options.XTrace.Add(i);
- if (XMethodTrace is not null)
+ if (XMethodTrace != null)
foreach (var i in XMethodTrace.Split(';'))
options.XMethodTrace.Add(i);
- if (PrivatePackages is not null)
+ if (PrivatePackages != null)
foreach (var i in PrivatePackages.Split(';'))
options.PrivatePackages.Add(i);
@@ -248,29 +350,29 @@ protected override async Task ExecuteAsync(IkvmToolTaskDiagnosticWriter wr
options.NoPeerCrossReference = NoPeerCrossReference;
options.NoStdLib = NoStdLib;
- if (Lib is not null)
+ if (Lib != null)
foreach (var i in Lib)
- options.Lib.Add(GetAbsolutePathIfNotNull(i.ItemSpec));
+ options.Lib.Add(i.ItemSpec);
options.HighEntropyVA = HighEntropyVA;
options.Static = Static;
- if (AssemblyAttributes is not null)
+ if (AssemblyAttributes != null)
foreach (var i in AssemblyAttributes)
options.AssemblyAttributes.Add(i.ItemSpec);
- options.Runtime = GetAbsolutePathIfNotNull(Runtime);
+ options.Runtime = Runtime;
- if (options.WarningLevel is not null)
+ if (options.WarningLevel != null)
options.WarningLevel = int.Parse(WarningLevel);
options.NoParameterReflection = NoParameterReflection;
- options.Remap = GetAbsolutePathIfNotNull(Remap);
+ options.Remap = Remap;
options.NoLogo = true;
if (Input != null)
foreach (var i in Input)
- options.Input.Add(GetAbsolutePathIfNotNull(i.ItemSpec));
+ options.Input.Add(i.ItemSpec);
// kick off the launcher with the configured options
return await new IkvmImporterLauncher(ToolPath, writer).ExecuteAsync(options, cancellationToken) == 0;
diff --git a/src/IKVM.MSBuild.Tasks/IkvmExporter.cs b/src/IKVM.MSBuild.Tasks/IkvmExporter.cs
index 33728f5753..bb9b87754b 100644
--- a/src/IKVM.MSBuild.Tasks/IkvmExporter.cs
+++ b/src/IKVM.MSBuild.Tasks/IkvmExporter.cs
@@ -1,4 +1,5 @@
-using System.Threading;
+using System.IO;
+using System.Threading;
using System.Threading.Tasks;
using IKVM.Tools.Runner.Exporter;
@@ -59,6 +60,27 @@ public class IkvmExporter : IkvmToolExecTask
public bool Bootstrap { get; set; }
+ public override bool Execute()
+ {
+ if (Input != null)
+ Input = Path.GetFullPath(Input);
+
+ if (Output != null)
+ Output = Path.GetFullPath(Output);
+
+ if (References != null)
+ foreach (var i in References)
+ if (i.ItemSpec != null)
+ i.ItemSpec = Path.GetFullPath(i.ItemSpec);
+
+ if (Lib != null)
+ foreach (var i in Lib)
+ if (i.ItemSpec != null)
+ i.ItemSpec = Path.GetFullPath(i.ItemSpec);
+
+ return base.Execute();
+ }
+
protected override async Task ExecuteAsync(IkvmToolTaskDiagnosticWriter writer, CancellationToken cancellationToken)
{
var options = new IkvmExporterOptions();
diff --git a/src/IKVM.MSBuild.Tasks/IkvmJavaCompiler.cs b/src/IKVM.MSBuild.Tasks/IkvmJavaCompiler.cs
index 094de33f70..26e17b25e0 100644
--- a/src/IKVM.MSBuild.Tasks/IkvmJavaCompiler.cs
+++ b/src/IKVM.MSBuild.Tasks/IkvmJavaCompiler.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading;
using com.sun.tools.javac.util;
@@ -19,31 +20,182 @@ namespace IKVM.MSBuild.Tasks
///
/// Executes the Java compiler.
///
- public class IkvmJavaCompiler : Microsoft.Build.Utilities.Task
+ public class IkvmJavaCompiler : Task
{
+ ///
+ /// Implements .
+ ///
+ class MSBuildDiagnosticListener : DiagnosticListener
+ {
+
+ readonly TaskLoggingHelper log;
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ public MSBuildDiagnosticListener(TaskLoggingHelper log)
+ {
+ this.log = log ?? throw new ArgumentNullException(nameof(log));
+ }
+
+ public void report(Diagnostic diagnostic)
+ {
+ var kind = diagnostic.getKind();
+ var code = diagnostic.getCode();
+ var source = diagnostic.getSource() is DiagnosticSource f ? f.getFile().toUri().getPath() : null;
+ var startPosition = (int)diagnostic.getStartPosition();
+ var columnNumber = (int)diagnostic.getColumnNumber();
+ var endPosition = (int)diagnostic.getEndPosition();
+ var message = diagnostic.getMessage(Locale.getDefault()) ?? "unknown";
+
+ if (kind == Diagnostic.Kind.ERROR)
+ log.LogError(null, code, null, source, startPosition, columnNumber, endPosition, -1, message);
+ else if (kind == Diagnostic.Kind.WARNING || kind == Diagnostic.Kind.MANDATORY_WARNING)
+ log.LogWarning(null, code, null, source, startPosition, columnNumber, endPosition, -1, message);
+ else
+ log.LogMessage(null, code, null, source, startPosition, columnNumber, endPosition, -1, MessageImportance.Normal, message);
+ }
+
+ }
+
+ readonly CancellationTokenSource cts;
+
+ ///
+ /// Initializes a new instance.
+ ///
+ public IkvmJavaCompiler()
+ {
+ cts = new CancellationTokenSource();
+ }
+
+ ///
+ /// Classpath for compiler.
+ ///
[Required]
public ITaskItem[] Classpath { get; set; }
+ ///
+ /// Source files to compile.
+ ///
[Required]
public ITaskItem[] Sources { get; set; }
+ ///
+ /// Path to place the generated class files.
+ ///
[Required]
public string Destination { get; set; }
+ ///
+ /// Path to place the generated JNI header files.
+ ///
public string HeaderDestination { get; set; }
+ ///
+ /// Whether to enable debug output of the compiler.
+ ///
public string Debug { get; set; }
+ ///
+ /// If true disables warning messages.
+ ///
public bool NoWarn { get; set; }
+ ///
+ /// Whether to enable verbose output of the compiler.
+ ///
public bool Verbose { get; set; }
+ ///
+ /// Source version.
+ ///
public string Source { get; set; }
+ ///
+ /// Target version.
+ ///
public string Target { get; set; }
+ ///
+ /// Executes the Java compiler.
+ ///
+ ///
public override bool Execute()
+ {
+ if (Classpath != null)
+ foreach (var i in Classpath)
+ if (i.ItemSpec != null)
+ i.ItemSpec = System.IO.Path.GetFullPath(i.ItemSpec);
+
+ if (Sources != null)
+ foreach (var i in Sources)
+ if (i.ItemSpec != null)
+ i.ItemSpec = System.IO.Path.GetFullPath(i.ItemSpec);
+
+ if (Destination != null)
+ Destination = System.IO.Path.GetFullPath(Destination);
+
+ if (HeaderDestination != null)
+ HeaderDestination = System.IO.Path.GetFullPath(HeaderDestination);
+
+ if (cts.IsCancellationRequested)
+ return false;
+
+ // wait for result, and ensure we reacquire in case of return value or exception
+ System.Threading.Tasks.Task run;
+
+ try
+ {
+ // kick off the launcher with the configured options
+ run = ExecuteAsync(cts.Token);
+ if (run.IsCompleted)
+ return run.GetAwaiter().GetResult();
+ }
+ catch (OperationCanceledException)
+ {
+ return false;
+ }
+
+ // yield and wait for the task to complete
+ BuildEngine3.Yield();
+
+ var result = false;
+ try
+ {
+ result = run.GetAwaiter().GetResult();
+ }
+ catch (OperationCanceledException)
+ {
+ return false;
+ }
+ finally
+ {
+ BuildEngine3.Reacquire();
+ }
+
+ // check that we exited successfully
+ return result;
+ }
+
+ ///
+ /// Execute the Java compiler in a separate thread.
+ ///
+ ///
+ ///
+ public System.Threading.Tasks.Task ExecuteAsync(CancellationToken cancellationToken)
+ {
+ return System.Threading.Tasks.Task.Run(Compile);
+ }
+
+ ///
+ /// Executes the compiler.
+ ///
+ ///
+ ///
+ bool Compile()
{
var diagnostics = new MSBuildDiagnosticListener(Log);
var javacArgLog = new List();
@@ -60,7 +212,7 @@ public override bool Execute()
throw new IkvmTaskException("Invalid destination.");
// create destination directory
- var destination = new File(System.IO.Path.GetFullPath(Destination));
+ var destination = new File(Destination);
destination.mkdirs();
// set output path
@@ -71,7 +223,7 @@ public override bool Execute()
if (string.IsNullOrWhiteSpace(HeaderDestination) == false)
{
// create destination directory
- var headerDestination = new File(System.IO.Path.GetFullPath(HeaderDestination));
+ var headerDestination = new File(HeaderDestination);
headerDestination.mkdirs();
// set header output path
@@ -81,7 +233,7 @@ public override bool Execute()
}
// get set of source items to compile
- var compilationUnits = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(Sources.Select(i => new File(System.IO.Path.GetFullPath(i.ItemSpec))).Cast