From f4e8de384461e87be7afef62e3797ef6ddb09bcc Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Tue, 26 Apr 2022 20:56:13 +0200 Subject: [PATCH] Update NativeAOT docs, fix the support for local NativeAOT builds (#1997) * fix local NativeAOT builds benchmarking * update the docs * Apply suggestions from code review Co-authored-by: Andrii Kurdiumov Co-authored-by: Jan Kotas Co-authored-by: Andrii Kurdiumov Co-authored-by: Jan Kotas --- docs/articles/configs/toolchains.md | 141 ++++++++++++++---- .../ConsoleArguments/CommandLineOptions.cs | 4 +- .../ConsoleArguments/ConfigParser.cs | 8 +- .../Toolchains/NativeAot/Generator.cs | 59 +------- .../NativeAot/NativeAotToolchain.cs | 16 +- .../NativeAot/NativeAotToolchainBuilder.cs | 18 +-- .../LocalNativeAotToolchainTests.cs | 4 +- .../ConfigParserTests.cs | 5 +- 8 files changed, 140 insertions(+), 115 deletions(-) diff --git a/docs/articles/configs/toolchains.md b/docs/articles/configs/toolchains.md index 6b2e508c57..f9cc925693 100644 --- a/docs/articles/configs/toolchains.md +++ b/docs/articles/configs/toolchains.md @@ -190,14 +190,21 @@ Example: `dotnet run -c Release -- --coreRun "C:\Projects\corefx\bin\testhost\ne ## NativeAOT -BenchmarkDotNet supports [NativeAOT](https://github.com/dotnet/runtime/tree/main/src/coreclr/nativeaot/docs)! However, you might want to know how it works to get a better understanding of the results that you get. +BenchmarkDotNet supports [NativeAOT](https://github.com/dotnet/runtime/tree/main/src/coreclr/nativeaot)! However, you might want to know how it works to get a better understanding of the results that you get. -* NativeAOT is a flavor of .NET Core. Which means that: - * you have to target .NET Core to be able to build NativeAOT benchmarks (example: `net7.0` in the .csproj file) - * you have to specify the NativeAOT runtime in an explicit way, either by using `[SimpleJob]` attribute or by using the fluent Job config API `Job.ShortRun.With(NativeAotRuntime.$version)` or console line arguments `--runtimes nativeaot7.0` - * to run NativeAOT benchmark you run the app as a .NET Core/.NET process (example: `dotnet run -c Release -f net5.01`) and BenchmarkDotNet does all the NativeAOT compilation for you. If you want to check what files are generated you need to apply `[KeepBenchmarkFiles]` attribute to the class which defines benchmarks. +As every AOT solution, NativeAOT has some [limitations](https://github.com/dotnet/runtime/blob/main/src/coreclr/nativeaot/docs/limitations.md) like limited reflection support or lack of dynamic assembly loading. Because of that, the host process (what you run from command line) is never an AOT process, but just a regular .NET process. This process (called Host process) uses reflection to read benchmarks metadata (find all `[Benchmark]` methods etc), generates a new project that references the benchmarks and compiles it using ILCompiler. Such compilation produces a native executable, which is later started by the Host process. This process (called Benchmark or Child process) performs the actual benchmarking and reports the results back to the Host process. By default BenchmarkDotNet uses the latest version of `Microsoft.DotNet.ILCompiler` to build the NativeAOT benchmark according to [this instructions](https://github.com/dotnet/runtime/blob/main/src/coreclr/nativeaot/docs/compiling.md). -By default BenchmarkDotNet uses the latest version of `Microsoft.DotNet.ILCompiler` to build the NativeAOT benchmark according to [this instructions](https://github.com/dotnet/runtime/blob/main/src/coreclr/nativeaot/docs/compiling.md). +This is why you need to: +- install [pre-requisites](https://github.com/dotnet/runtime/blob/main/src/coreclr/nativeaot/docs/prerequisites.md) required by NativeAOT compiler +- target .NET to be able to run NativeAOT benchmarks (example: `net7.0` in the .csproj file) +- run the app as a .NET process (example: `dotnet run -c Release -f net7.0`). +- specify the NativeAOT runtime in an explicit way, either by using console line arguments `--runtimes nativeaot7.0` (the recommended approach), or by using`[SimpleJob]` attribute or by using the fluent Job config API `Job.ShortRun.With(NativeAotRuntime.Net70)`: + +```cmd +dotnet run -c Release -f net7.0 --runtimes nativeaot7.0 +``` + +or: ```cs var config = DefaultConfig.Instance @@ -208,6 +215,8 @@ BenchmarkSwitcher .Run(args, config); ``` +or: + ```cs [SimpleJob(RuntimeMoniker.NativeAot70)] // compiles the benchmarks as net7.0 and uses the latest NativeAOT to build a native app public class TheTypeWithBenchmarks @@ -216,7 +225,7 @@ public class TheTypeWithBenchmarks } ``` -**Note**: BenchmarkDotNet is going to run `dotnet restore` on the auto-generated project. The first time it does so, it's going to take a **LOT** of time to download all the dependencies (few minutes). Just give it some time and don't press `Ctrl+C` too fast ;) +### Customization If you want to benchmark some particular version of NativeAOT (or from a different NuGet feed) you have to specify it in an explicit way: @@ -228,45 +237,119 @@ var config = DefaultConfig.Instance microsoftDotNetILCompilerVersion: "7.0.0-*", // the version goes here nuGetFeedUrl: "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet7/nuget/v3/index.json") // this address might change over time .DisplayName("NativeAOT NuGet") - .TargetFrameworkMoniker("net5.0") + .TargetFrameworkMoniker("net7.0") .ToToolchain())); ``` +The builder allows to configure more settings: +- specify packages restore path by using `PackagesRestorePath($path)` +- rooting all application assemblies by using `RootAllApplicationAssemblies($bool)`. This is disabled by default. +- generating complete type metadata by using `IlcGenerateCompleteTypeMetadata($bool)`. This option is enabled by default. +- generating stack trace metadata by using `IlcGenerateStackTraceData($bool)`. This option is enabled by default. +- set optimization preference by using `IlcOptimizationPreference($value)`. The default is `Speed`, you can configure it to `Size` or nothing +- set instruction set for the target OS, architecture and hardware by using `IlcInstructionSet($value)`. By default BDN recognizes most of the instruction sets on your machine and enables them. + +BenchmarkDotNet supports [rd.xml](https://github.com/dotnet/runtime/blob/main/src/coreclr/nativeaot/docs/rd-xml-format.md) files. To get given file respected by BenchmarkDotNet you need to place it in the same folder as the project that defines benchmarks and name it `rd.xml` or in case of multiple files give them `.rd.xml` extension. The alternative to `rd.xml` files is annotating types with [DynamicallyAccessedMembers](https://devblogs.microsoft.com/dotnet/app-trimming-in-net-5/) attribute. + +If given benchmark is not supported by NativeAOT, you need to apply `[AotFilter]` attribute for it. Example: + +```cs +[Benchmark] +[AotFilter("Not supported by design.")] +public object CreateInstanceNames() => System.Activator.CreateInstance(_assemblyName, _typeName); +``` + +### Generated files + +By default BenchmarkDotNet removes the generates files after finishing the run. To keep them on the disk you need to pass `--keepFiles true` command line argument or apply `[KeepBenchmarkFiles]` attribute to the class which defines benchmark(s). Then, read the folder from the tool output. In the example below it's `D:\projects\performance\artifacts\bin\MicroBenchmarks\Release\net7.0\Job-KRLVKQ`: + +```log +// ***** Building 1 exe(s) in Parallel: Start ***** +// start dotnet restore -r win-x64 /p:UseSharedCompilation=false /p:BuildInParallel=false /m:1 /p:Deterministic=true /p:Optimize=true in D:\projects\performance\artifacts\bin\MicroBenchmarks\Release\net7.0\Job-KRLVKQ +// command took 2.74s and exited with 0 +// start dotnet build -c Release -r win-x64 --no-restore /p:UseSharedCompilation=false /p:BuildInParallel=false /m:1 /p:Deterministic=true /p:Optimize=true in D:\projects\performance\artifacts\bin\MicroBenchmarks\Release\net7.0\Job-KRLVKQ +// command took 3.82s and exited with 0 +``` + +If you go to `D:\projects\performance\artifacts\bin\MicroBenchmarks\Release\net7.0\Job-KRLVKQ`, you can see the generated project file (named `BenchmarkDotNet.Autogenerated.csproj`), code (file name ends with `.notcs`) and find the native executable (in the `bin\**\native` subfolder). Example: + +```cmd +cd D:\projects\performance\artifacts\bin\MicroBenchmarks\Release\net7.0\Job-KRLVKQ +cat .\BenchmarkDotNet.Autogenerated.csproj +``` + +```log + + + false + false + Exe + net7.0 + win-x64 + + Job-KRLVKQ + Job-KRLVKQ + true + x64 + False + false + false + true + false + Speed + linklink + True + True + false + false + + + false + true + + + + + + + + + + + + + + + +``` + ### Compiling source to native code using the ILCompiler you built -If you are a NativeAOT contributor and you want to benchmark your local build of NativeAOT you have to provide necessary info (IlcPath): +If you are a NativeAOT contributor and you want to benchmark your local build of NativeAOT you have to provide necessary info (path to shipping packages). + +You can do that from command line: + +```cmd +dotnet run -c Release -f net7.0 --runtimes nativeaot7.0 --ilcPackages D:\projects\runtime\artifacts\packages\Release\Shipping\ +``` + +or explicitly in the code: + ```cs var config = DefaultConfig.Instance .With(Job.ShortRun .With(NativeAotToolchain.CreateBuilder() - .UseLocalBuild(@"C:\Projects\corert\bin\Windows_NT.x64.Release") // IlcPath + .UseLocalBuild(@"C:\Projects\runtime\artifacts\packages\Release\Shipping\") .DisplayName("NativeAOT local build") .TargetFrameworkMoniker("net7.0") .ToToolchain())); ``` -BenchmarkDotNet is going to follow [these instructrions](https://github.com/dotnet/corert/blob/7f902d4d8b1c3280e60f5e06c71951a60da173fb/Documentation/how-to-build-and-run-ilcompiler-in-console-shell-prompt.md#compiling-source-to-native-code-using-the-ilcompiler-you-built) to get it working for you. - -### Using CPP Code Generator - -> This approach uses transpiler to convert IL to C++, and then uses platform specific C++ compiler and linker for compiling/linking the application. The transpiler is a lot less mature than the RyuJIT path. If you came here to give CoreRT a try on your .NET Core program, use the RyuJIT option above. +BenchmarkDotNet is going to follow [these instructrions](https://github.com/dotnet/runtime/blob/main/docs/workflow/building/coreclr/nativeaot.md#building) to get it working for you. -If you want to test [CPP Code Generator](https://github.com/dotnet/corert/blob/7f902d4d8b1c3280e60f5e06c71951a60da173fb/Documentation/how-to-build-and-run-ilcompiler-in-console-shell-prompt.md#using-cpp-code-generator) you have to use `UseCppCodeGenerator` method: - -```cs -var config = DefaultConfig.Instance - .With(Job.Default - .With( - NativeAotToolchain.CreateBuilder() - .UseLocalBuild(@"C:\Projects\corert\bin\Windows_NT.x64.Release") // IlcPath - .UseCppCodeGenerator() // ENABLE IT - .TargetFrameworkMoniker("net7.0") - .DisplayName("CPP") - .ToToolchain())); -``` +**Note**: BenchmarkDotNet is going to run `dotnet restore` on the auto-generated project and restore the packages to a temporary folder. It might take some time, but the next time you rebuild dotnet/runtime repo and run the same command BenchmarkDotNet is going to use the new ILCompiler package. -**Note**: You might get some `The method or operation is not implemented.` errors as of today if the code that you are trying to benchmark is using some features that are not implemented by NativeAOT/transpiler yet... ## Wasm diff --git a/src/BenchmarkDotNet/ConsoleArguments/CommandLineOptions.cs b/src/BenchmarkDotNet/ConsoleArguments/CommandLineOptions.cs index 7b28dda19f..c7ba9ad0b7 100644 --- a/src/BenchmarkDotNet/ConsoleArguments/CommandLineOptions.cs +++ b/src/BenchmarkDotNet/ConsoleArguments/CommandLineOptions.cs @@ -97,8 +97,8 @@ public class CommandLineOptions [Option("ilCompilerVersion", Required = false, HelpText = "Optional version of Microsoft.DotNet.ILCompiler which should be used to run with NativeAOT. Example: \"7.0.0-preview.3.22123.2\"")] public string ILCompilerVersion { get; set; } - [Option("ilcPath", Required = false, HelpText = "Optional IlcPath which should be used to run with private NativeAOT build.")] - public DirectoryInfo IlcPath { get; set; } + [Option("ilcPackages", Required = false, HelpText = @"Optional path to shipping packages produced by local dotnet/runtime build. Example: 'D:\projects\runtime\artifacts\packages\Release\Shipping\'")] + public DirectoryInfo IlcPackages { get; set; } [Option("launchCount", Required = false, HelpText = "How many times we should launch process with target benchmark. The default is 1.")] public int? LaunchCount { get; set; } diff --git a/src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs b/src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs index 3a0bd1db02..0d5bd65506 100644 --- a/src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs +++ b/src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs @@ -157,9 +157,9 @@ private static bool Validate(CommandLineOptions options, ILogger logger) return false; } - if (options.IlcPath.IsNotNullButDoesNotExist()) + if (options.IlcPackages.IsNotNullButDoesNotExist()) { - logger.WriteLineError($"The provided {nameof(options.IlcPath)} \"{options.IlcPath}\" does NOT exist."); + logger.WriteLineError($"The provided {nameof(options.IlcPackages)} \"{options.IlcPackages}\" does NOT exist."); return false; } @@ -395,8 +395,8 @@ private static Job CreateAotJob(Job baseJob, CommandLineOptions options, Runtime if (options.RestorePath != null) builder.PackagesRestorePath(options.RestorePath.FullName); - if (options.IlcPath != null) - builder.UseLocalBuild(options.IlcPath.FullName); + if (options.IlcPackages != null) + builder.UseLocalBuild(options.IlcPackages); else if (!string.IsNullOrEmpty(options.ILCompilerVersion)) builder.UseNuGet(options.ILCompilerVersion, nuGetFeedUrl); else diff --git a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs index 7d3ae01082..c582103755 100644 --- a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs +++ b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs @@ -33,9 +33,8 @@ public class Generator : CsProjGenerator : base(targetFrameworkMoniker, cliPath, GetPackagesDirectoryPath(useTempFolderForRestore, packagesRestorePath), runtimeFrameworkVersion) { this.ilCompilerVersion = ilCompilerVersion; - this.targetFrameworkMoniker = targetFrameworkMoniker; this.runtimeIdentifier = runtimeIdentifier; - this.feeds = feeds; + this.Feeds = feeds; this.useNuGetClearTag = useNuGetClearTag; this.useTempFolderForRestore = useTempFolderForRestore; this.rootAllApplicationAssemblies = rootAllApplicationAssemblies; @@ -45,11 +44,9 @@ public class Generator : CsProjGenerator this.ilcInstructionSet = ilcInstructionSet; } + internal readonly IReadOnlyDictionary Feeds; private readonly string ilCompilerVersion; - [SuppressMessage("ReSharper", "NotAccessedField.Local")] - private readonly string targetFrameworkMoniker; private readonly string runtimeIdentifier; - private readonly IReadOnlyDictionary feeds; private readonly bool useNuGetClearTag; private readonly bool useTempFolderForRestore; private readonly bool rootAllApplicationAssemblies; @@ -58,8 +55,6 @@ public class Generator : CsProjGenerator private readonly string ilcOptimizationPreference; private readonly string ilcInstructionSet; - private bool IsNuGet => feeds.ContainsKey(NativeAotNuGetFeed) && !string.IsNullOrWhiteSpace(ilCompilerVersion); - protected override string GetExecutableExtension() => RuntimeInformation.ExecutableExtension; protected override string GetBuildArtifactsDirectoryPath(BuildPartition buildPartition, string programName) @@ -97,7 +92,7 @@ protected override string[] GetArtifactsToCleanup(ArtifactsPaths artifactsPaths) protected override void GenerateNuGetConfig(ArtifactsPaths artifactsPaths) { - if (!feeds.Any()) + if (!Feeds.Any()) return; string content = @@ -105,7 +100,7 @@ protected override void GenerateNuGetConfig(ArtifactsPaths artifactsPaths) {(useNuGetClearTag ? "" : string.Empty)} - {string.Join(Environment.NewLine + " ", feeds.Select(feed => $""))} + {string.Join(Environment.NewLine + " ", Feeds.Select(feed => $""))} "; @@ -114,11 +109,7 @@ protected override void GenerateNuGetConfig(ArtifactsPaths artifactsPaths) protected override void GenerateProject(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, ILogger logger) { - File.WriteAllText(artifactsPaths.ProjectFilePath, - IsNuGet - ? GenerateProjectForNuGetBuild(buildPartition, artifactsPaths, logger) - : GenerateProjectForLocalBuild(buildPartition, artifactsPaths, logger)); - + File.WriteAllText(artifactsPaths.ProjectFilePath, GenerateProjectForNuGetBuild(buildPartition, artifactsPaths, logger)); GenerateReflectionFile(artifactsPaths); } @@ -163,46 +154,6 @@ protected override void GenerateProject(BuildPartition buildPartition, Artifacts "; - private string GenerateProjectForLocalBuild(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, ILogger logger) => $@" - - - - Exe - {TargetFrameworkMoniker} - {runtimeIdentifier} - {RuntimeFrameworkVersion} - {artifactsPaths.ProgramName} - {artifactsPaths.ProgramName} - true - {buildPartition.Platform.ToConfig()} - False - false - false - true - false - {ilcOptimizationPreference} - {GetTrimmingSettings()} - {ilcGenerateCompleteTypeMetadata} - {ilcGenerateStackTraceData} - false - - - - {GetRuntimeSettings(buildPartition.RepresentativeBenchmarkCase.Job.Environment.Gc, buildPartition.Resolver)} - - - - - - - - {string.Join(Environment.NewLine, GetRdXmlFiles(buildPartition.RepresentativeBenchmarkCase.Descriptor.Type, logger).Select(file => $""))} - - - {GetInstructionSetSettings(buildPartition)} - -"; - private string GetTrimmingSettings() => rootAllApplicationAssemblies ? "" // use the defaults diff --git a/src/BenchmarkDotNet/Toolchains/NativeAot/NativeAotToolchain.cs b/src/BenchmarkDotNet/Toolchains/NativeAot/NativeAotToolchain.cs index ec390fca83..e795d95a63 100644 --- a/src/BenchmarkDotNet/Toolchains/NativeAot/NativeAotToolchain.cs +++ b/src/BenchmarkDotNet/Toolchains/NativeAot/NativeAotToolchain.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using BenchmarkDotNet.Jobs; +using System.Collections.Generic; using BenchmarkDotNet.Toolchains.DotNetCli; namespace BenchmarkDotNet.Toolchains.NativeAot @@ -24,7 +22,7 @@ public class NativeAotToolchain : Toolchain .ToToolchain(); internal NativeAotToolchain(string displayName, - string ilCompilerVersion, string ilcPath, + string ilCompilerVersion, string runtimeFrameworkVersion, string targetFrameworkMoniker, string runtimeIdentifier, string customDotNetCliPath, string packagesRestorePath, Dictionary feeds, bool useNuGetClearTag, bool useTempFolderForRestore, @@ -35,21 +33,13 @@ public class NativeAotToolchain : Toolchain runtimeIdentifier, feeds, useNuGetClearTag, useTempFolderForRestore, packagesRestorePath, rootAllApplicationAssemblies, ilcGenerateCompleteTypeMetadata, ilcGenerateStackTraceData, ilcOptimizationPreference, ilcInstructionSet), - new DotNetCliPublisher(customDotNetCliPath, GetExtraArguments(runtimeIdentifier), GetEnvironmentVariables(ilcPath)), + new DotNetCliPublisher(customDotNetCliPath, GetExtraArguments(runtimeIdentifier)), new Executor()) { - IlcPath = ilcPath; } - public string IlcPath { get; } - public static NativeAotToolchainBuilder CreateBuilder() => NativeAotToolchainBuilder.Create(); public static string GetExtraArguments(string runtimeIdentifier) => $"-r {runtimeIdentifier}"; - - // https://github.com/dotnet/corert/blob/7f902d4d8b1c3280e60f5e06c71951a60da173fb/Documentation/how-to-build-and-run-ilcompiler-in-console-shell-prompt.md#compiling-source-to-native-code-using-the-ilcompiler-you-built - // we have to pass IlcPath env var to get it working - private static IReadOnlyList GetEnvironmentVariables(string ilcPath) - => ilcPath == null ? Array.Empty() : new[] { new EnvironmentVariable("IlcPath", ilcPath) }; } } diff --git a/src/BenchmarkDotNet/Toolchains/NativeAot/NativeAotToolchainBuilder.cs b/src/BenchmarkDotNet/Toolchains/NativeAot/NativeAotToolchainBuilder.cs index 7d83b72e99..07c4e7d5fc 100644 --- a/src/BenchmarkDotNet/Toolchains/NativeAot/NativeAotToolchainBuilder.cs +++ b/src/BenchmarkDotNet/Toolchains/NativeAot/NativeAotToolchainBuilder.cs @@ -11,7 +11,6 @@ public class NativeAotToolchainBuilder : CustomDotNetCliToolchainBuilder public static NativeAotToolchainBuilder Create() => new NativeAotToolchainBuilder(); private string ilCompilerVersion; - private string ilcPath; private string packagesRestorePath; // we set those default values on purpose https://github.com/dotnet/BenchmarkDotNet/pull/1057#issuecomment-461832612 private bool rootAllApplicationAssemblies; @@ -41,17 +40,19 @@ public NativeAotToolchainBuilder UseNuGet(string microsoftDotNetILCompilerVersio } /// - /// creates a Native toolchain targeting local build of ILCompiler - /// Based on https://github.com/dotnet/corert/blob/7f902d4d8b1c3280e60f5e06c71951a60da173fb/Documentation/how-to-build-and-run-ilcompiler-in-console-shell-prompt.md#compiling-source-to-native-code-using-the-ilcompiler-you-built + /// creates a NativeAOT toolchain targeting local build of ILCompiler + /// Based on https://github.com/dotnet/runtime/blob/main/docs/workflow/building/coreclr/nativeaot.md /// - /// the ilcPath, an example: "C:\Projects\corert\bin\Windows_NT.x64.Release" + /// the path to shipping packages, example: "C:\runtime\artifacts\packages\Release\Shipping" [PublicAPI] - public NativeAotToolchainBuilder UseLocalBuild(string newIlcPath) + public NativeAotToolchainBuilder UseLocalBuild(DirectoryInfo ilcPackages) { - if (newIlcPath == null) throw new ArgumentNullException(nameof(newIlcPath)); - if (!Directory.Exists(newIlcPath)) throw new DirectoryNotFoundException($"{newIlcPath} provided as {nameof(newIlcPath)} does NOT exist"); + if (ilcPackages == null) throw new ArgumentNullException(nameof(ilcPackages)); + if (!ilcPackages.Exists) throw new DirectoryNotFoundException($"{ilcPackages} provided as {nameof(ilcPackages)} does NOT exist"); - ilcPath = newIlcPath; + Feeds["local"] = ilcPackages.FullName; + ilCompilerVersion = "7.0.0-dev"; + Feeds["dotnet7"] = "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet7/nuget/v3/index.json"; useTempFolderForRestore = true; isIlCompilerConfigured = true; @@ -149,7 +150,6 @@ public override IToolchain ToToolchain() return new NativeAotToolchain( displayName: displayName ?? (ilCompilerVersion != null ? $"ILCompiler {ilCompilerVersion}" : "local ILCompiler build"), ilCompilerVersion: ilCompilerVersion, - ilcPath: ilcPath, runtimeFrameworkVersion: runtimeFrameworkVersion, targetFrameworkMoniker: GetTargetFrameworkMoniker(), runtimeIdentifier: runtimeIdentifier ?? GetPortableRuntimeIdentifier(), diff --git a/tests/BenchmarkDotNet.IntegrationTests.ManualRunning/LocalNativeAotToolchainTests.cs b/tests/BenchmarkDotNet.IntegrationTests.ManualRunning/LocalNativeAotToolchainTests.cs index e41dfe2575..c8740a3829 100644 --- a/tests/BenchmarkDotNet.IntegrationTests.ManualRunning/LocalNativeAotToolchainTests.cs +++ b/tests/BenchmarkDotNet.IntegrationTests.ManualRunning/LocalNativeAotToolchainTests.cs @@ -20,7 +20,7 @@ namespace BenchmarkDotNet.IntegrationTests.ManualRunning /// public class LocalNativeAotToolchainTests : BenchmarkTestExecutor { - private const string IlcPath = @"C:\Projects\corert\bin\Windows_NT.x64.Release"; + private const string IlcPath = @"D:\projects\runtime\artifacts\packages\Release\Shipping"; public LocalNativeAotToolchainTests(ITestOutputHelper output) : base(output) { } @@ -32,7 +32,7 @@ public void CanBenchmarkLocalBuildUsingRyuJit() .WithRuntime(NativeAotRuntime.Net60) .WithToolchain( NativeAotToolchain.CreateBuilder() - .UseLocalBuild(IlcPath) + .UseLocalBuild(new System.IO.DirectoryInfo(IlcPath)) .ToToolchain())); CanExecute(config); diff --git a/tests/BenchmarkDotNet.Tests/ConfigParserTests.cs b/tests/BenchmarkDotNet.Tests/ConfigParserTests.cs index 30b0c72d27..dd79fea837 100644 --- a/tests/BenchmarkDotNet.Tests/ConfigParserTests.cs +++ b/tests/BenchmarkDotNet.Tests/ConfigParserTests.cs @@ -207,12 +207,13 @@ public void ClrVersionParsedCorrectly() public void IlCompilerPathParsedCorrectly() { var fakePath = new FileInfo(typeof(ConfigParserTests).Assembly.Location).Directory; - var config = ConfigParser.Parse(new[] { "-r", "nativeaot60", "--ilcPath", fakePath.FullName }, new OutputLogger(Output)).config; + var config = ConfigParser.Parse(new[] { "-r", "nativeaot60", "--ilcPackages", fakePath.FullName }, new OutputLogger(Output)).config; Assert.Single(config.GetJobs()); NativeAotToolchain toolchain = config.GetJobs().Single().GetToolchain() as NativeAotToolchain; Assert.NotNull(toolchain); - Assert.Equal(fakePath.FullName, toolchain.IlcPath); + Generator generator = (Generator)toolchain.Generator; + Assert.Equal(fakePath.FullName, generator.Feeds["local"]); } [Theory]