diff --git a/src/IKVM.MSBuild.Tools.runtime.linux-x64/IKVM.MSBuild.Tools.runtime.linux-x64.csproj b/src/IKVM.MSBuild.Tools.runtime.linux-x64/IKVM.MSBuild.Tools.runtime.linux-x64.csproj index ea2a84b6d..51bdea342 100644 --- a/src/IKVM.MSBuild.Tools.runtime.linux-x64/IKVM.MSBuild.Tools.runtime.linux-x64.csproj +++ b/src/IKVM.MSBuild.Tools.runtime.linux-x64/IKVM.MSBuild.Tools.runtime.linux-x64.csproj @@ -15,6 +15,22 @@ + + TargetFramework=net472 + RuntimeIdentifier=linux-x64 + ikvmc\net472\linux-x64 + PreserveNewest + ikvmc\net472\linux-x64 + true + + + TargetFramework=net472 + RuntimeIdentifier=linux-x64 + ikvmstub\net472\linux-x64 + PreserveNewest + ikvmstub\net472\linux-x64 + true + TargetFramework=net8.0 RuntimeIdentifier=linux-x64 diff --git a/src/IKVM.MSBuild.Tools.runtime.linux-x64/buildTransitive/IKVM.MSBuild.Tools.runtime.linux-x64.props b/src/IKVM.MSBuild.Tools.runtime.linux-x64/buildTransitive/IKVM.MSBuild.Tools.runtime.linux-x64.props index 45ca535de..5033dcc6c 100644 --- a/src/IKVM.MSBuild.Tools.runtime.linux-x64/buildTransitive/IKVM.MSBuild.Tools.runtime.linux-x64.props +++ b/src/IKVM.MSBuild.Tools.runtime.linux-x64/buildTransitive/IKVM.MSBuild.Tools.runtime.linux-x64.props @@ -4,7 +4,9 @@ + + diff --git a/src/IKVM.MSBuild.Tools.runtime.osx-arm64/IKVM.MSBuild.Tools.runtime.osx-arm64.csproj b/src/IKVM.MSBuild.Tools.runtime.osx-arm64/IKVM.MSBuild.Tools.runtime.osx-arm64.csproj index e24710001..82765ea41 100644 --- a/src/IKVM.MSBuild.Tools.runtime.osx-arm64/IKVM.MSBuild.Tools.runtime.osx-arm64.csproj +++ b/src/IKVM.MSBuild.Tools.runtime.osx-arm64/IKVM.MSBuild.Tools.runtime.osx-arm64.csproj @@ -15,6 +15,22 @@ + + TargetFramework=net472 + RuntimeIdentifier=osx-arm64 + ikvmc\net472\osx-arm64 + PreserveNewest + ikvmc\net472\osx-arm64 + true + + + TargetFramework=net472 + RuntimeIdentifier=osx-arm64 + ikvmstub\net472\osx-arm64 + PreserveNewest + ikvmstub\net472\osx-arm64 + true + TargetFramework=net8.0 RuntimeIdentifier=osx-arm64 diff --git a/src/IKVM.MSBuild.Tools.runtime.osx-arm64/buildTransitive/IKVM.MSBuild.Tools.runtime.osx-arm64.props b/src/IKVM.MSBuild.Tools.runtime.osx-arm64/buildTransitive/IKVM.MSBuild.Tools.runtime.osx-arm64.props index 1cec4a545..8e3d95910 100644 --- a/src/IKVM.MSBuild.Tools.runtime.osx-arm64/buildTransitive/IKVM.MSBuild.Tools.runtime.osx-arm64.props +++ b/src/IKVM.MSBuild.Tools.runtime.osx-arm64/buildTransitive/IKVM.MSBuild.Tools.runtime.osx-arm64.props @@ -4,7 +4,9 @@ + + diff --git a/src/IKVM.MSBuild.Tools.runtime.osx-x64/IKVM.MSBuild.Tools.runtime.osx-x64.csproj b/src/IKVM.MSBuild.Tools.runtime.osx-x64/IKVM.MSBuild.Tools.runtime.osx-x64.csproj index 99d61a5b7..6651298c7 100644 --- a/src/IKVM.MSBuild.Tools.runtime.osx-x64/IKVM.MSBuild.Tools.runtime.osx-x64.csproj +++ b/src/IKVM.MSBuild.Tools.runtime.osx-x64/IKVM.MSBuild.Tools.runtime.osx-x64.csproj @@ -15,6 +15,22 @@ + + TargetFramework=net472 + RuntimeIdentifier=osx-x64 + ikvmc\net472\osx-x64 + PreserveNewest + ikvmc\net472\osx-x64 + true + + + TargetFramework=net472 + RuntimeIdentifier=osx-x64 + ikvmstub\net472\osx-x64 + PreserveNewest + ikvmstub\net472\osx-x64 + true + TargetFramework=net8.0 RuntimeIdentifier=osx-x64 diff --git a/src/IKVM.MSBuild.Tools.runtime.osx-x64/buildTransitive/IKVM.MSBuild.Tools.runtime.osx-x64.props b/src/IKVM.MSBuild.Tools.runtime.osx-x64/buildTransitive/IKVM.MSBuild.Tools.runtime.osx-x64.props index 8869929d6..64840f706 100644 --- a/src/IKVM.MSBuild.Tools.runtime.osx-x64/buildTransitive/IKVM.MSBuild.Tools.runtime.osx-x64.props +++ b/src/IKVM.MSBuild.Tools.runtime.osx-x64/buildTransitive/IKVM.MSBuild.Tools.runtime.osx-x64.props @@ -4,7 +4,9 @@ + + diff --git a/src/IKVM.Tests.Util/DotNetSdkUtil.cs b/src/IKVM.Tests.Util/DotNetSdkUtil.cs index b93f2b98f..84537b06f 100644 --- a/src/IKVM.Tests.Util/DotNetSdkUtil.cs +++ b/src/IKVM.Tests.Util/DotNetSdkUtil.cs @@ -5,8 +5,6 @@ using System.Reflection.Metadata; using System.Reflection.PortableExecutable; -using Microsoft.Build.Utilities; - namespace IKVM.Tests.Util { @@ -63,11 +61,21 @@ public static string GetCoreLibName(string tfm, string targetFrameworkIdentifier public static IList GetPathToReferenceAssemblies(string tfm, string targetFrameworkIdentifier, string targetFrameworkVersion) { if (targetFrameworkIdentifier == ".NETFramework") - return ToolLocationHelper.GetPathToReferenceAssemblies(targetFrameworkIdentifier, targetFrameworkVersion, ""); + { + var l = new List(); + var dir = Path.Combine(Path.GetDirectoryName(typeof(DotNetSdkUtil).Assembly.Location), "netfxref", tfm); + if (Directory.Exists(dir)) + l.Add(dir); + + return l; + } + if (targetFrameworkIdentifier == ".NETCore") + { return GetCorePathToReferenceAssemblies(tfm, targetFrameworkVersion); + } - throw new InvalidOperationException(); + throw new ArgumentException(nameof(targetFrameworkIdentifier)); } /// diff --git a/src/IKVM.Tests.Util/IKVM.Tests.Util.csproj b/src/IKVM.Tests.Util/IKVM.Tests.Util.csproj index d3ce0e66c..eb3bce65b 100644 --- a/src/IKVM.Tests.Util/IKVM.Tests.Util.csproj +++ b/src/IKVM.Tests.Util/IKVM.Tests.Util.csproj @@ -1,4 +1,6 @@ - + + + net472;net6.0;net7.0;net8.0 @@ -8,5 +10,30 @@ + + + + + + + + IncludeReferenceAssemblies; + $(AssignTargetPathsDependsOn) + + + + + + <__ReferenceAssemblies Include="$(PkgMicrosoft_NETFramework_ReferenceAssemblies_net472)\build\.NETFramework\v4.7.2\*.dll" Framework="net472" /> + <__ReferenceAssemblies Include="$(PkgMicrosoft_NETFramework_ReferenceAssemblies_net472)\build\.NETFramework\v4.7.2\Facades\*.dll" Framework="net472" /> + <__ReferenceAssemblies Include="$(PkgMicrosoft_NETFramework_ReferenceAssemblies_net481)\build\.NETFramework\v4.8.1\*.dll" Framework="net481" /> + <__ReferenceAssemblies Include="$(PkgMicrosoft_NETFramework_ReferenceAssemblies_net481)\build\.NETFramework\v4.8.1\Facades\*.dll" Framework="net481" /> + + netfxref\%(Framework)\%(RecursiveDir)%(Filename)%(Extension) + PreserveNewest + + + + diff --git a/src/IKVM.Tools.Runner/Exporter/IkvmExporterLauncher.cs b/src/IKVM.Tools.Runner/Exporter/IkvmExporterLauncher.cs index 9373176d4..abaddfe81 100644 --- a/src/IKVM.Tools.Runner/Exporter/IkvmExporterLauncher.cs +++ b/src/IKVM.Tools.Runner/Exporter/IkvmExporterLauncher.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Linq; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; @@ -145,30 +146,52 @@ public async Task ExecuteAsync(IkvmExporterOptions options, CancellationTok try { // locate EXE file + string? wrap = null; var exe = GetToolExe(); - if (File.Exists(exe) == false) + if (exe is null || File.Exists(exe) == false) throw new FileNotFoundException($"Could not locate tool at '{exe}'."); - // if we're running on Unix, we might need to set the execute bit on the file, - // since the NuGet package is built on Windows + // executing on Unix requires some considerations if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { - try + // tool executables on Unix need to be invoked through Mono + if (exe.EndsWith(".exe")) { - var psx = Mono.Unix.UnixFileSystemInfo.GetFileSystemEntry(exe); - if (psx.FileAccessPermissions.HasFlag(Mono.Unix.FileAccessPermissions.UserExecute) == false) - psx.FileAccessPermissions |= Mono.Unix.FileAccessPermissions.UserExecute; + wrap = "mono"; } - catch (Exception e) + else { - throw new IkvmToolException($"Could not set user executable bit on '{exe}'.", e); + // else we need to ensure executable bit is set + + try + { + var psx = Mono.Unix.UnixFileSystemInfo.GetFileSystemEntry(exe); + if (psx.FileAccessPermissions.HasFlag(Mono.Unix.FileAccessPermissions.UserExecute) == false) + psx.FileAccessPermissions |= Mono.Unix.FileAccessPermissions.UserExecute; + } + catch (Exception e) + { + throw new IkvmToolException($"Could not set user executable bit on '{exe}'.", e); + } } } - // configure CLI - var cli = Cli.Wrap(exe).WithWorkingDirectory(Environment.CurrentDirectory); + // configure CLI, with wrapper if required + Command cli; + if (wrap != null) + { + cli = Cli.Wrap(wrap); + args.Insert(0, exe); + } + else + cli = Cli.Wrap(exe); + + // set configuration of CLI + cli = cli.WithWorkingDirectory(Environment.CurrentDirectory); cli = cli.WithArguments(args); cli = cli.WithValidation(CommandResultValidation.None); + + // log the command we're about to run await LogEventAsync(IkvmToolDiagnosticEventLevel.Trace, "Executing {0} {1}", [cli.TargetFilePath, cli.Arguments], ctk); // send output to MSBuild (TODO, replace with binary reading) diff --git a/src/IKVM.Tools.Runner/IkvmToolLauncher.cs b/src/IKVM.Tools.Runner/IkvmToolLauncher.cs index 4d2a72c2d..80fcba346 100644 --- a/src/IKVM.Tools.Runner/IkvmToolLauncher.cs +++ b/src/IKVM.Tools.Runner/IkvmToolLauncher.cs @@ -92,44 +92,16 @@ protected IkvmToolDiagnosticEvent ParseEvent(string line) /// /// Gets the path to executable for the given environment. /// - /// - /// /// /// /// - public string GetToolExe(OSPlatform platform, Architecture architecture) + public string? GetToolExe() { - return Path.Combine(toolPath, platform == OSPlatform.Windows ? $"{toolName}.exe" : toolName); - } - - /// - /// Gets the path to executable for the given environment. - /// - /// - /// - /// - public string GetToolExe() - { - return GetToolExe(GetOSPlatform(), RuntimeInformation.OSArchitecture); - } - - /// - /// Gets the current OS platform. - /// - /// - /// - OSPlatform GetOSPlatform() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - return OSPlatform.Windows; - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - return OSPlatform.Linux; - - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - return OSPlatform.OSX; + foreach (var name in (Span)[toolName + ".exe", toolName]) + if (File.Exists(Path.Combine(toolPath, name))) + return Path.Combine(toolPath, name); - throw new PlatformNotSupportedException(); + return null; } } diff --git a/src/IKVM.Tools.Runner/Importer/IkvmImporterLauncher.cs b/src/IKVM.Tools.Runner/Importer/IkvmImporterLauncher.cs index 87d61c515..bd0fd1763 100644 --- a/src/IKVM.Tools.Runner/Importer/IkvmImporterLauncher.cs +++ b/src/IKVM.Tools.Runner/Importer/IkvmImporterLauncher.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; @@ -263,40 +264,62 @@ public async Task ExecuteAsync(IkvmImporterOptions options, CancellationTok try { // create response file - Directory.CreateDirectory(Path.GetDirectoryName(response)); + Directory.CreateDirectory(Path.GetDirectoryName(response) ?? throw new InvalidOperationException()); File.WriteAllText(response, w.ToString()); // locate EXE file + string? wrap = null; var exe = GetToolExe(); - if (File.Exists(exe) == false) + if (exe is null || File.Exists(exe) == false) throw new FileNotFoundException($"Could not locate tool at '{exe}'."); - // if we're running on Linux, we might need to set the execute bit on the file, - // since the NuGet package is built on Windows + // executing on Unix requires some considerations if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { - try + // tool executables on Unix need to be invoked through Mono + if (exe.EndsWith(".exe")) { - var psx = Mono.Unix.UnixFileSystemInfo.GetFileSystemEntry(exe); - var prm = psx.FileAccessPermissions; - prm |= Mono.Unix.FileAccessPermissions.UserExecute; - prm |= Mono.Unix.FileAccessPermissions.GroupExecute; - prm |= Mono.Unix.FileAccessPermissions.OtherExecute; - if (prm != psx.FileAccessPermissions) - psx.FileAccessPermissions = prm; + wrap = "mono"; } - catch (Exception e) + else { - throw new IkvmToolException($"Could not set user executable bit on '{exe}'.", e); + // else we need to ensure executable bit is set + + try + { + var psx = Mono.Unix.UnixFileSystemInfo.GetFileSystemEntry(exe); + if (psx.FileAccessPermissions.HasFlag(Mono.Unix.FileAccessPermissions.UserExecute) == false) + psx.FileAccessPermissions |= Mono.Unix.FileAccessPermissions.UserExecute; + } + catch (Exception e) + { + throw new IkvmToolException($"Could not set user executable bit on '{exe}'.", e); + } } } - // configure CLI - var cli = Cli.Wrap(exe).WithWorkingDirectory(Environment.CurrentDirectory); + // assemble list of args + var args = new List(); + args.Add($"@{response}"); - // execute the contents of the response file - cli = cli.WithArguments([$"@{response}"]); + // configure CLI, with wrapper if required + Command cli; + if (wrap != null) + { + cli = Cli.Wrap(wrap); + args.Insert(0, exe); + } + else + cli = Cli.Wrap(exe); + + // set working directory + cli = cli.WithWorkingDirectory(Environment.CurrentDirectory); + + // set configuration of CLI + cli = cli.WithArguments(args); cli = cli.WithValidation(CommandResultValidation.None); + + // log the command we're about to run await LogEventAsync(IkvmToolDiagnosticEventLevel.Trace, "Executing {0} {1}", [cli.TargetFilePath, cli.Arguments], ctk); // send output to MSBuild (TODO, replace with binary reading) diff --git a/src/IKVM.Tools.Tests/IKVM.Tools.Tests.csproj b/src/IKVM.Tools.Tests/IKVM.Tools.Tests.csproj index 09a083f63..22fb1831d 100644 --- a/src/IKVM.Tools.Tests/IKVM.Tools.Tests.csproj +++ b/src/IKVM.Tools.Tests/IKVM.Tools.Tests.csproj @@ -108,6 +108,19 @@ PreserveNewest + + TargetFramework=net472 + RuntimeIdentifier=linux-x64 + ikvmc\net472\linux-x64 + PreserveNewest + + + TargetFramework=net472 + RuntimeIdentifier=linux-x64 + ikvmstub\net472\linux-x64 + PreserveNewest + + TargetFramework=net8.0 RuntimeIdentifier=linux-x64 @@ -121,6 +134,19 @@ PreserveNewest + + TargetFramework=net472 + RuntimeIdentifier=osx-x64 + ikvmc\net472\osx-x64 + PreserveNewest + + + TargetFramework=net472 + RuntimeIdentifier=osx-x64 + ikvmstub\net472\osx-x64 + PreserveNewest + + TargetFramework=net8.0 RuntimeIdentifier=osx-x64 diff --git a/src/IKVM.Tools.Tests/Runner/Exporter/IkvmExporterLauncherTests.cs b/src/IKVM.Tools.Tests/Runner/Exporter/IkvmExporterLauncherTests.cs index 172aebcaf..aba7e0809 100644 --- a/src/IKVM.Tools.Tests/Runner/Exporter/IkvmExporterLauncherTests.cs +++ b/src/IKVM.Tools.Tests/Runner/Exporter/IkvmExporterLauncherTests.cs @@ -35,11 +35,6 @@ public class IkvmExporterLauncherTests [DataRow("net8.0", "net8.0", "net8.0", ".NETCore", "8.0")] public async System.Threading.Tasks.Task CanExportDll(string toolFramework, string ikvmFramework, string targetFramework, string targetFrameworkIdentifier, string targetFrameworkVersion) { - if (toolFramework == "net472" && RuntimeInformation.IsOSPlatform(OSPlatform.Windows) == false) - return; - if (targetFrameworkIdentifier == ".NETFramework" && RuntimeInformation.IsOSPlatform(OSPlatform.Windows) == false) - return; - var ikvmLibs = Path.Combine(TESTBASE, "lib", ikvmFramework); var refsPath = DotNetSdkUtil.GetPathToReferenceAssemblies(targetFramework, targetFrameworkIdentifier, targetFrameworkVersion) ; @@ -48,26 +43,26 @@ public async System.Threading.Tasks.Task CanExportDll(string toolFramework, stri var d = Path.GetDirectoryName(p); Directory.CreateDirectory(d); - var rid = ""; + var toolRid = ""; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && RuntimeInformation.ProcessArchitecture == Architecture.X64) - rid = "win-x64"; + toolRid = "win-x64"; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && RuntimeInformation.ProcessArchitecture == Architecture.Arm64) - rid = "win-arm64"; + toolRid = "win-arm64"; if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.X64) - rid = "linux-x64"; + toolRid = "linux-x64"; if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.Arm) - rid = "linux-arm"; + toolRid = "linux-arm"; if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.Arm64) - rid = "linux-arm64"; + toolRid = "linux-arm64"; if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && RuntimeInformation.ProcessArchitecture == Architecture.X64) - rid = "osx-x64"; + toolRid = "osx-x64"; if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && RuntimeInformation.ProcessArchitecture == Architecture.Arm64) - rid = "osx-arm64"; - if (string.IsNullOrEmpty(rid)) + toolRid = "osx-arm64"; + if (string.IsNullOrEmpty(toolRid)) return; var e = new List(); - var l = new IkvmExporterLauncher(Path.Combine(Path.GetDirectoryName(typeof(IkvmExporterLauncherTests).Assembly.Location), "ikvmstub", toolFramework, rid), new IkvmToolDelegateDiagnosticListener(evt => { e.Add(evt); TestContext.WriteLine(evt.Message, evt.Args); })); + var l = new IkvmExporterLauncher(Path.Combine(Path.GetDirectoryName(typeof(IkvmExporterLauncherTests).Assembly.Location), "ikvmstub", toolFramework, toolRid), new IkvmToolDelegateDiagnosticListener(evt => { e.Add(evt); TestContext.WriteLine(evt.Message, evt.Args); })); var o = new IkvmExporterOptions() { NoStdLib = true, diff --git a/src/IKVM.Tools.Tests/Runner/Importer/IkvmImporterLauncherTests.cs b/src/IKVM.Tools.Tests/Runner/Importer/IkvmImporterLauncherTests.cs index 82d73374d..65a6f4ea1 100644 --- a/src/IKVM.Tools.Tests/Runner/Importer/IkvmImporterLauncherTests.cs +++ b/src/IKVM.Tools.Tests/Runner/Importer/IkvmImporterLauncherTests.cs @@ -35,11 +35,6 @@ public class IkvmImporterLauncherTests [DataRow("net8.0", "net8.0", "net8.0", ".NETCore", "8.0")] public async System.Threading.Tasks.Task CanImportJar(string toolFramework, string ikvmFramework, string targetFrameworkMoniker, string targetFrameworkIdentifier, string targetFrameworkVersion) { - if (toolFramework == "net472" && RuntimeInformation.IsOSPlatform(OSPlatform.Windows) == false) - return; - if (targetFrameworkIdentifier == ".NETFramework" && RuntimeInformation.IsOSPlatform(OSPlatform.Windows) == false) - return; - var ikvmLibs = Path.Combine(TESTBASE, "lib", ikvmFramework); var refsPath = DotNetSdkUtil.GetPathToReferenceAssemblies(targetFrameworkMoniker, targetFrameworkIdentifier, targetFrameworkVersion); @@ -47,26 +42,26 @@ public async System.Threading.Tasks.Task CanImportJar(string toolFramework, stri var d = Path.GetDirectoryName(p); Directory.CreateDirectory(d); - var rid = ""; + var toolRid = ""; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && RuntimeInformation.ProcessArchitecture == Architecture.X64) - rid = "win-x64"; + toolRid = "win-x64"; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && RuntimeInformation.ProcessArchitecture == Architecture.Arm64) - rid = "win-arm64"; + toolRid = "win-arm64"; if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.X64) - rid = "linux-x64"; + toolRid = "linux-x64"; if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.Arm) - rid = "linux-arm"; + toolRid = "linux-arm"; if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.Arm64) - rid = "linux-arm64"; + toolRid = "linux-arm64"; if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && RuntimeInformation.ProcessArchitecture == Architecture.X64) - rid = "osx-x64"; + toolRid = "osx-x64"; if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && RuntimeInformation.ProcessArchitecture == Architecture.Arm64) - rid = "osx-arm64"; - if (string.IsNullOrEmpty(rid)) + toolRid = "osx-arm64"; + if (string.IsNullOrEmpty(toolRid)) return; var e = new List(); - var l = new IkvmImporterLauncher(Path.Combine(Path.GetDirectoryName(typeof(IkvmImporterLauncherTests).Assembly.Location), "ikvmc", toolFramework, rid), new IkvmToolDelegateDiagnosticListener(evt => { e.Add(evt); TestContext.WriteLine(evt.Message, evt.Args); })); + var l = new IkvmImporterLauncher(Path.Combine(Path.GetDirectoryName(typeof(IkvmImporterLauncherTests).Assembly.Location), "ikvmc", toolFramework, toolRid), new IkvmToolDelegateDiagnosticListener(evt => { e.Add(evt); TestContext.WriteLine(evt.Message, evt.Args); })); var o = new IkvmImporterOptions() { Runtime = Path.Combine(ikvmLibs, "IKVM.Runtime.dll"),