From 4edac272f3025bb9202be236e6c86096c61a00ee Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 22 Jan 2024 20:23:52 -0500 Subject: [PATCH 1/3] =?UTF-8?q?=EF=BB=BFSplit=20builds=20into=202=20steps?= =?UTF-8?q?=20to=20gather=20assembly=20references.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Diagnosers/PerfCollectProfiler.cs | 1 + .../Toolchains/ArtifactsPaths.cs | 5 +- .../Toolchains/CsProj/CsProjGenerator.cs | 51 ++++++++++---- .../Toolchains/DotNetCli/DotNetCliBuilder.cs | 67 ++++++++++++++++--- .../Toolchains/DotNetCli/DotNetCliCommand.cs | 61 ++++++++++------- .../DotNetCli/DotNetCliCommandExecutor.cs | 1 + .../DotNetCli/DotNetCliGenerator.cs | 6 +- .../DotNetCli/DotNetCliPublisher.cs | 29 +++++--- .../Toolchains/GeneratorBase.cs | 8 +++ .../Emit/InProcessEmitArtifactsPath.cs | 1 + .../InProcess/Emit/InProcessEmitGenerator.cs | 1 + .../Toolchains/Mono/MonoPublisher.cs | 34 +++++++--- .../MonoAotLLVM/MonoAotLLVMGenerator.cs | 2 + .../Toolchains/MonoWasm/WasmGenerator.cs | 2 + .../Toolchains/NativeAot/Generator.cs | 14 +++- 15 files changed, 216 insertions(+), 67 deletions(-) diff --git a/src/BenchmarkDotNet/Diagnosers/PerfCollectProfiler.cs b/src/BenchmarkDotNet/Diagnosers/PerfCollectProfiler.cs index f1b584ce09..d99f4c3acd 100644 --- a/src/BenchmarkDotNet/Diagnosers/PerfCollectProfiler.cs +++ b/src/BenchmarkDotNet/Diagnosers/PerfCollectProfiler.cs @@ -229,6 +229,7 @@ private void EnsureSymbolsForNativeRuntime(DiagnoserActionParameters parameters) // We install the tool in a dedicated directory in order to always use latest version and avoid issues with broken existing configs. string toolPath = Path.Combine(Path.GetTempPath(), "BenchmarkDotNet", "symbols"); DotNetCliCommand cliCommand = new ( + projPath: string.Empty, cliPath: cliPath, arguments: $"tool install dotnet-symbol --tool-path \"{toolPath}\"", generateResult: null, diff --git a/src/BenchmarkDotNet/Toolchains/ArtifactsPaths.cs b/src/BenchmarkDotNet/Toolchains/ArtifactsPaths.cs index 0c097f5bb0..e082d126ee 100644 --- a/src/BenchmarkDotNet/Toolchains/ArtifactsPaths.cs +++ b/src/BenchmarkDotNet/Toolchains/ArtifactsPaths.cs @@ -4,7 +4,7 @@ namespace BenchmarkDotNet.Toolchains { public class ArtifactsPaths { - public static readonly ArtifactsPaths Empty = new ArtifactsPaths("", "", "", "", "", "", "", "", "", "", "", ""); + public static readonly ArtifactsPaths Empty = new ("", "", "", "", "", "", "", "", "", "", "", "", ""); [PublicAPI] public string RootArtifactsFolderPath { get; } [PublicAPI] public string BuildArtifactsDirectoryPath { get; } @@ -13,6 +13,7 @@ public class ArtifactsPaths [PublicAPI] public string ProgramCodePath { get; } [PublicAPI] public string AppConfigPath { get; } [PublicAPI] public string NuGetConfigPath { get; } + [PublicAPI] public string BuildForReferencesProjectFilePath { get; } [PublicAPI] public string ProjectFilePath { get; } [PublicAPI] public string BuildScriptFilePath { get; } [PublicAPI] public string ExecutablePath { get; } @@ -27,6 +28,7 @@ public ArtifactsPaths( string programCodePath, string appConfigPath, string nuGetConfigPath, + string buildForReferencesProjectFilePath, string projectFilePath, string buildScriptFilePath, string executablePath, @@ -40,6 +42,7 @@ public ArtifactsPaths( ProgramCodePath = programCodePath; AppConfigPath = appConfigPath; NuGetConfigPath = nuGetConfigPath; + BuildForReferencesProjectFilePath = buildForReferencesProjectFilePath; ProjectFilePath = projectFilePath; BuildScriptFilePath = buildScriptFilePath; ExecutablePath = executablePath; diff --git a/src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs b/src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs index 7e91c36ff4..0f95dea835 100644 --- a/src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs +++ b/src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs @@ -61,6 +61,9 @@ protected override string GetBuildArtifactsDirectoryPath(BuildPartition buildPar protected override string GetProjectFilePath(string buildArtifactsDirectoryPath) => Path.Combine(buildArtifactsDirectoryPath, "BenchmarkDotNet.Autogenerated.csproj"); + protected override string GetProjectFilePathForReferences(string buildArtifactsDirectoryPath) + => Path.Combine(buildArtifactsDirectoryPath, "BenchmarkDotNet.Autogenerated.ForReferences.csproj"); + protected override string GetBinariesDirectoryPath(string buildArtifactsDirectoryPath, string configuration) => Path.Combine(buildArtifactsDirectoryPath, "bin", configuration, TargetFrameworkMoniker); @@ -68,30 +71,54 @@ protected override string GetIntermediateDirectoryPath(string buildArtifactsDire => Path.Combine(buildArtifactsDirectoryPath, "obj", configuration, TargetFrameworkMoniker); [SuppressMessage("ReSharper", "StringLiteralTypo")] // R# complains about $variables$ - protected override void GenerateProject(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, ILogger logger) - { - var benchmark = buildPartition.RepresentativeBenchmarkCase; - var projectFile = GetProjectFilePath(benchmark.Descriptor.Type, logger); - - var xmlDoc = new XmlDocument(); - xmlDoc.Load(projectFile.FullName); - var (customProperties, sdkName) = GetSettingsThatNeedToBeCopied(xmlDoc, projectFile); - - var content = new StringBuilder(ResourceHelper.LoadTemplate("CsProj.txt")) + private string LoadCsProj(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, string projectFile, string customProperties, string sdkName) + => new StringBuilder(ResourceHelper.LoadTemplate("CsProj.txt")) .Replace("$PLATFORM$", buildPartition.Platform.ToConfig()) .Replace("$CODEFILENAME$", Path.GetFileName(artifactsPaths.ProgramCodePath)) - .Replace("$CSPROJPATH$", projectFile.FullName) + .Replace("$CSPROJPATH$", projectFile) .Replace("$TFM$", TargetFrameworkMoniker) .Replace("$PROGRAMNAME$", artifactsPaths.ProgramName) - .Replace("$RUNTIMESETTINGS$", GetRuntimeSettings(benchmark.Job.Environment.Gc, buildPartition.Resolver)) + .Replace("$RUNTIMESETTINGS$", GetRuntimeSettings(buildPartition.RepresentativeBenchmarkCase.Job.Environment.Gc, buildPartition.Resolver)) .Replace("$COPIEDSETTINGS$", customProperties) .Replace("$CONFIGURATIONNAME$", buildPartition.BuildConfiguration) .Replace("$SDKNAME$", sdkName) .ToString(); + protected override void GenerateProject(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, ILogger logger) + { + var projectFile = GetProjectFilePath(buildPartition.RepresentativeBenchmarkCase.Descriptor.Type, logger); + + var xmlDoc = new XmlDocument(); + xmlDoc.Load(projectFile.FullName); + var (customProperties, sdkName) = GetSettingsThatNeedToBeCopied(xmlDoc, projectFile); + + GenerateBuildForReferencesProject(buildPartition, artifactsPaths, projectFile.FullName, customProperties, sdkName); + + var content = LoadCsProj(buildPartition, artifactsPaths, projectFile.FullName, customProperties, sdkName); + File.WriteAllText(artifactsPaths.ProjectFilePath, content); } + protected void GenerateBuildForReferencesProject(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, string projectFile, string customProperties, string sdkName) + { + var content = LoadCsProj(buildPartition, artifactsPaths, projectFile, customProperties, sdkName); + + // We don't include the generated .notcs file when building the reference dlls, only in the final build. + var xmlDoc = new XmlDocument(); + xmlDoc.Load(new StringReader(content)); + XmlElement projectElement = xmlDoc.DocumentElement; + projectElement.RemoveChild(projectElement.SelectSingleNode("ItemGroup/Compile").ParentNode); + + var startupObjectElement = projectElement.SelectSingleNode("PropertyGroup/StartupObject"); + startupObjectElement.ParentNode.RemoveChild(startupObjectElement); + + // We need to change the output type to library since we're only compiling for dlls. + var outputTypeElement = projectElement.SelectSingleNode("PropertyGroup/OutputType"); + outputTypeElement.InnerText = "Library"; + + xmlDoc.Save(artifactsPaths.BuildForReferencesProjectFilePath); + } + /// /// returns an MSBuild string that defines Runtime settings /// diff --git a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliBuilder.cs b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliBuilder.cs index 7a7afc3184..fa8e05e9c7 100644 --- a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliBuilder.cs +++ b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliBuilder.cs @@ -1,4 +1,6 @@ using System; +using System.IO; +using System.Xml; using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Loggers; using BenchmarkDotNet.Running; @@ -25,16 +27,34 @@ public DotNetCliBuilder(string targetFrameworkMoniker, string? customDotNetCliPa public BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger) { - BuildResult buildResult = new DotNetCliCommand( - CustomDotNetCliPath, - string.Empty, - generateResult, - logger, - buildPartition, - Array.Empty(), - buildPartition.Timeout, - logOutput: LogOutput) + var cliCommand = new DotNetCliCommand( + generateResult.ArtifactsPaths.BuildForReferencesProjectFilePath, + CustomDotNetCliPath, + string.Empty, + generateResult, + logger, + buildPartition, + Array.Empty(), + buildPartition.Timeout, + logOutput: LogOutput); + + BuildResult buildResult; + // Integration tests are built without dependencies, so we skip the first step. + if (!buildPartition.ForcedNoDependenciesForIntegrationTests) + { + // We build the original project first to obtain all dlls. + buildResult = cliCommand.RestoreThenBuild(); + + if (!buildResult.IsBuildSuccess) + return buildResult; + + // After the dlls are built, we gather the assembly references, then build the benchmark project. + GatherReferences(generateResult.ArtifactsPaths); + } + + buildResult = cliCommand.WithProjPath(generateResult.ArtifactsPaths.ProjectFilePath) .RestoreThenBuild(); + if (buildResult.IsBuildSuccess && buildPartition.RepresentativeBenchmarkCase.Job.Environment.LargeAddressAware) { @@ -42,5 +62,34 @@ public BuildResult Build(GenerateResult generateResult, BuildPartition buildPart } return buildResult; } + + internal static void GatherReferences(ArtifactsPaths artifactsPaths) + { + var xmlDoc = new XmlDocument(); + xmlDoc.Load(artifactsPaths.ProjectFilePath); + XmlElement projectElement = xmlDoc.DocumentElement; + + // Add reference to every dll. + var itemGroup = xmlDoc.CreateElement("ItemGroup"); + projectElement.AppendChild(itemGroup); + foreach (var assemblyFile in Directory.GetFiles(artifactsPaths.BinariesDirectoryPath, "*.dll")) + { + var assemblyName = Path.GetFileNameWithoutExtension(assemblyFile); + // The dummy csproj was used to build the original project, but it also outputs a dll for itself which we need to ignore because it's not valid. + if (assemblyName == artifactsPaths.ProgramName) + { + continue; + } + var referenceElement = xmlDoc.CreateElement("Reference"); + itemGroup.AppendChild(referenceElement); + referenceElement.SetAttribute("Include", assemblyName); + var hintPath = xmlDoc.CreateElement("HintPath"); + referenceElement.AppendChild(hintPath); + var locationNode = xmlDoc.CreateTextNode(assemblyFile); + hintPath.AppendChild(locationNode); + } + + xmlDoc.Save(artifactsPaths.ProjectFilePath); + } } } diff --git a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliCommand.cs b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliCommand.cs index e9078f293f..9648a86637 100644 --- a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliCommand.cs +++ b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliCommand.cs @@ -16,6 +16,8 @@ namespace BenchmarkDotNet.Toolchains.DotNetCli { public class DotNetCliCommand { + [PublicAPI] public string ProjPath { get; } + [PublicAPI] public string CliPath { get; } [PublicAPI] public string Arguments { get; } @@ -32,9 +34,10 @@ public class DotNetCliCommand [PublicAPI] public bool LogOutput { get; } - public DotNetCliCommand(string cliPath, string arguments, GenerateResult generateResult, ILogger logger, + public DotNetCliCommand(string projPath, string cliPath, string arguments, GenerateResult generateResult, ILogger logger, BuildPartition buildPartition, IReadOnlyList environmentVariables, TimeSpan timeout, bool logOutput = false) { + ProjPath = projPath; CliPath = cliPath ?? DotNetCliCommandExecutor.DefaultDotNetCliPath.Value; Arguments = arguments; GenerateResult = generateResult; @@ -46,10 +49,13 @@ public DotNetCliCommand(string cliPath, string arguments, GenerateResult generat } public DotNetCliCommand WithArguments(string arguments) - => new (CliPath, arguments, GenerateResult, Logger, BuildPartition, EnvironmentVariables, Timeout, logOutput: LogOutput); + => new (ProjPath, CliPath, arguments, GenerateResult, Logger, BuildPartition, EnvironmentVariables, Timeout, logOutput: LogOutput); + + public DotNetCliCommand WithProjPath(string projPath) + => new (projPath, CliPath, Arguments, GenerateResult, Logger, BuildPartition, EnvironmentVariables, Timeout, logOutput: LogOutput); public DotNetCliCommand WithCliPath(string cliPath) - => new (cliPath, Arguments, GenerateResult, Logger, BuildPartition, EnvironmentVariables, Timeout, logOutput: LogOutput); + => new (ProjPath, cliPath, Arguments, GenerateResult, Logger, BuildPartition, EnvironmentVariables, Timeout, logOutput: LogOutput); [PublicAPI] public BuildResult RestoreThenBuild() @@ -71,12 +77,12 @@ public BuildResult RestoreThenBuild() if (BuildPartition.ForcedNoDependenciesForIntegrationTests) { var restoreResult = DotNetCliCommandExecutor.Execute(WithArguments( - GetRestoreCommand(GenerateResult.ArtifactsPaths, BuildPartition, $"{Arguments} --no-dependencies", "restore-no-deps", excludeOutput: true))); + GetRestoreCommand(GenerateResult.ArtifactsPaths, BuildPartition, ProjPath, $"{Arguments} --no-dependencies", "restore-no-deps", excludeOutput: true))); if (!restoreResult.IsSuccess) return BuildResult.Failure(GenerateResult, restoreResult.AllInformation); return DotNetCliCommandExecutor.Execute(WithArguments( - GetBuildCommand(GenerateResult.ArtifactsPaths, BuildPartition, $"{Arguments} --no-restore --no-dependencies", "build-no-restore-no-deps", excludeOutput: true))) + GetBuildCommand(GenerateResult.ArtifactsPaths, BuildPartition, ProjPath, $"{Arguments} --no-restore --no-dependencies", "build-no-restore-no-deps", excludeOutput: true))) .ToBuildResult(GenerateResult); } else @@ -118,7 +124,7 @@ public DotNetCliCommandResult AddPackages() { var executionTime = new TimeSpan(0); var stdOutput = new StringBuilder(); - foreach (var cmd in GetAddPackagesCommands(BuildPartition)) + foreach (var cmd in GetAddPackagesCommands(BuildPartition, ProjPath)) { var result = DotNetCliCommandExecutor.Execute(WithArguments(cmd)); if (!result.IsSuccess) return result; @@ -130,31 +136,32 @@ public DotNetCliCommandResult AddPackages() public DotNetCliCommandResult Restore() => DotNetCliCommandExecutor.Execute(WithArguments( - GetRestoreCommand(GenerateResult.ArtifactsPaths, BuildPartition, Arguments, "restore"))); + GetRestoreCommand(GenerateResult.ArtifactsPaths, BuildPartition, ProjPath, Arguments, "restore"))); public DotNetCliCommandResult Build() => DotNetCliCommandExecutor.Execute(WithArguments( - GetBuildCommand(GenerateResult.ArtifactsPaths, BuildPartition, Arguments, "build"))); + GetBuildCommand(GenerateResult.ArtifactsPaths, BuildPartition, ProjPath, Arguments, "build"))); public DotNetCliCommandResult BuildNoRestore() => DotNetCliCommandExecutor.Execute(WithArguments( - GetBuildCommand(GenerateResult.ArtifactsPaths, BuildPartition, $"{Arguments} --no-restore", "build-no-restore"))); + GetBuildCommand(GenerateResult.ArtifactsPaths, BuildPartition, ProjPath, $"{Arguments} --no-restore", "build-no-restore"))); public DotNetCliCommandResult Publish() => DotNetCliCommandExecutor.Execute(WithArguments( - GetPublishCommand(GenerateResult.ArtifactsPaths, BuildPartition, Arguments, "publish"))); + GetPublishCommand(GenerateResult.ArtifactsPaths, BuildPartition, ProjPath, Arguments, "publish"))); // PublishNoBuildAndNoRestore was removed because we set --output in the build step. We use the implicit build included in the publish command. public DotNetCliCommandResult PublishNoRestore() => DotNetCliCommandExecutor.Execute(WithArguments( - GetPublishCommand(GenerateResult.ArtifactsPaths, BuildPartition, $"{Arguments} --no-restore", "publish-no-restore"))); + GetPublishCommand(GenerateResult.ArtifactsPaths, BuildPartition, ProjPath, $"{Arguments} --no-restore", "publish-no-restore"))); - internal static IEnumerable GetAddPackagesCommands(BuildPartition buildPartition) - => GetNuGetAddPackageCommands(buildPartition.RepresentativeBenchmarkCase, buildPartition.Resolver); + internal static IEnumerable GetAddPackagesCommands(BuildPartition buildPartition, string projPath) + => GetNuGetAddPackageCommands(buildPartition.RepresentativeBenchmarkCase, buildPartition.Resolver, projPath); - internal static string GetRestoreCommand(ArtifactsPaths artifactsPaths, BuildPartition buildPartition, string? extraArguments = null, string? binLogSuffix = null, bool excludeOutput = false) + internal static string GetRestoreCommand(ArtifactsPaths artifactsPaths, BuildPartition buildPartition, string projPath, string? extraArguments = null, string? binLogSuffix = null, bool excludeOutput = false) => new StringBuilder() .AppendArgument("restore") + .AppendArgument(string.IsNullOrEmpty(projPath) ? string.Empty : $"\"{projPath}\"") .AppendArgument(string.IsNullOrEmpty(artifactsPaths.PackagesDirectoryName) ? string.Empty : $"--packages \"{artifactsPaths.PackagesDirectoryName}\"") .AppendArgument(GetCustomMsBuildArguments(buildPartition.RepresentativeBenchmarkCase, buildPartition.Resolver)) .AppendArgument(extraArguments) @@ -163,9 +170,11 @@ internal static string GetRestoreCommand(ArtifactsPaths artifactsPaths, BuildPar .MaybeAppendOutputPaths(artifactsPaths, true, excludeOutput) .ToString(); - internal static string GetBuildCommand(ArtifactsPaths artifactsPaths, BuildPartition buildPartition, string? extraArguments = null, string? binLogSuffix = null, bool excludeOutput = false) + internal static string GetBuildCommand(ArtifactsPaths artifactsPaths, BuildPartition buildPartition, string projPath, string? extraArguments = null, string? binLogSuffix = null, bool excludeOutput = false) => new StringBuilder() - .AppendArgument($"build -c {buildPartition.BuildConfiguration}") // we don't need to specify TFM, our auto-generated project contains always single one + .AppendArgument("build") + .AppendArgument(string.IsNullOrEmpty(projPath) ? string.Empty : $"\"{projPath}\"") + .AppendArgument($"-c {buildPartition.BuildConfiguration}") // we don't need to specify TFM, our auto-generated project contains always single one .AppendArgument(GetCustomMsBuildArguments(buildPartition.RepresentativeBenchmarkCase, buildPartition.Resolver)) .AppendArgument(extraArguments) .AppendArgument(GetMandatoryMsBuildSettings(buildPartition.BuildConfiguration)) @@ -174,9 +183,11 @@ internal static string GetBuildCommand(ArtifactsPaths artifactsPaths, BuildParti .MaybeAppendOutputPaths(artifactsPaths, excludeOutput: excludeOutput) .ToString(); - internal static string GetPublishCommand(ArtifactsPaths artifactsPaths, BuildPartition buildPartition, string? extraArguments = null, string? binLogSuffix = null) + internal static string GetPublishCommand(ArtifactsPaths artifactsPaths, BuildPartition buildPartition, string projPath, string? extraArguments = null, string? binLogSuffix = null) => new StringBuilder() - .AppendArgument($"publish -c {buildPartition.BuildConfiguration}") // we don't need to specify TFM, our auto-generated project contains always single one + .AppendArgument("publish") + .AppendArgument(string.IsNullOrEmpty(projPath) ? string.Empty : $"\"{projPath}\"") + .AppendArgument($"-c {buildPartition.BuildConfiguration}") // we don't need to specify TFM, our auto-generated project contains always single one .AppendArgument(GetCustomMsBuildArguments(buildPartition.RepresentativeBenchmarkCase, buildPartition.Resolver)) .AppendArgument(extraArguments) .AppendArgument(GetMandatoryMsBuildSettings(buildPartition.BuildConfiguration)) @@ -203,14 +214,14 @@ private static string GetCustomMsBuildArguments(BenchmarkCase benchmarkCase, IRe return string.Join(" ", msBuildArguments.Select(arg => arg.TextRepresentation)); } - private static IEnumerable GetNuGetAddPackageCommands(BenchmarkCase benchmarkCase, IResolver resolver) + private static IEnumerable GetNuGetAddPackageCommands(BenchmarkCase benchmarkCase, IResolver resolver, string projPath) { if (!benchmarkCase.Job.HasValue(InfrastructureMode.NuGetReferencesCharacteristic)) return Enumerable.Empty(); var nuGetRefs = benchmarkCase.Job.ResolveValue(InfrastructureMode.NuGetReferencesCharacteristic, resolver); - return nuGetRefs.Select(BuildAddPackageCommand); + return nuGetRefs.Select(nr => BuildAddPackageCommand(nr, projPath)); } private static string GetMandatoryMsBuildSettings(string buildConfiguration) @@ -228,11 +239,13 @@ private static string GetMandatoryMsBuildSettings(string buildConfiguration) return $"{NoMsBuildZombieProcesses} {EnforceOptimizations}"; } - private static string BuildAddPackageCommand(NuGetReference reference) + private static string BuildAddPackageCommand(NuGetReference reference, string projPath) { - var commandBuilder = new StringBuilder(); - commandBuilder.AppendArgument("add package"); - commandBuilder.AppendArgument(reference.PackageName); + var commandBuilder = new StringBuilder() + .AppendArgument("add") + .AppendArgument(string.IsNullOrEmpty(projPath) ? string.Empty : $"\"{projPath}\"") + .AppendArgument("package") + .AppendArgument(reference.PackageName); if (!string.IsNullOrWhiteSpace(reference.PackageVersion)) { commandBuilder.AppendArgument("-v"); diff --git a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliCommandExecutor.cs b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliCommandExecutor.cs index 5cbff89b47..3b12ef84f2 100644 --- a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliCommandExecutor.cs +++ b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliCommandExecutor.cs @@ -158,6 +158,7 @@ private static string GetDefaultDotNetCliPath() internal static string GetSdkPath(string cliPath) { DotNetCliCommand cliCommand = new ( + projPath: string.Empty, cliPath: cliPath, arguments: "--info", generateResult: null, diff --git a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliGenerator.cs b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliGenerator.cs index a432fbf881..ddf609d8df 100644 --- a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliGenerator.cs +++ b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliGenerator.cs @@ -101,8 +101,10 @@ protected override void CopyAllRequiredFiles(ArtifactsPaths artifactsPaths) protected override void GenerateBuildScript(BuildPartition buildPartition, ArtifactsPaths artifactsPaths) { var content = new StringBuilder(300) - .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition)}") - .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetBuildCommand(artifactsPaths, buildPartition)}") + .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, artifactsPaths.BuildForReferencesProjectFilePath)}") + .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetBuildCommand(artifactsPaths, buildPartition, artifactsPaths.BuildForReferencesProjectFilePath)}") + .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, artifactsPaths.ProjectFilePath)}") + .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetBuildCommand(artifactsPaths, buildPartition, artifactsPaths.ProjectFilePath)}") .ToString(); File.WriteAllText(artifactsPaths.BuildScriptFilePath, content); diff --git a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliPublisher.cs b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliPublisher.cs index 83158e0b1e..72dc14aecc 100644 --- a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliPublisher.cs +++ b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliPublisher.cs @@ -25,14 +25,27 @@ public DotNetCliPublisher( private IReadOnlyList? EnvironmentVariables { get; } public BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger) - => new DotNetCliCommand( - CustomDotNetCliPath, - ExtraArguments, - generateResult, - logger, - buildPartition, - EnvironmentVariables, - buildPartition.Timeout) + { + var cliCommand = new DotNetCliCommand( + generateResult.ArtifactsPaths.BuildForReferencesProjectFilePath, + CustomDotNetCliPath, + ExtraArguments, + generateResult, + logger, + buildPartition, + EnvironmentVariables, + buildPartition.Timeout); + + // We build the original project first to obtain all dlls. + var buildResult = cliCommand.RestoreThenBuild(); + + if (!buildResult.IsBuildSuccess) + return buildResult; + + // After the dlls are built, we gather the assembly references, then build the benchmark project. + DotNetCliBuilder.GatherReferences(generateResult.ArtifactsPaths); + return cliCommand.WithProjPath(generateResult.ArtifactsPaths.ProjectFilePath) .RestoreThenBuildThenPublish(); + } } } diff --git a/src/BenchmarkDotNet/Toolchains/GeneratorBase.cs b/src/BenchmarkDotNet/Toolchains/GeneratorBase.cs index 020788cc56..b1cb0f2837 100644 --- a/src/BenchmarkDotNet/Toolchains/GeneratorBase.cs +++ b/src/BenchmarkDotNet/Toolchains/GeneratorBase.cs @@ -69,6 +69,13 @@ [PublicAPI] protected virtual string GetExecutableExtension() [PublicAPI] protected virtual string GetProjectFilePath(string buildArtifactsDirectoryPath) => string.Empty; + /// + /// returns a path to the auto-generated .csproj file that is used to build the reference dlls + /// + [PublicAPI] + protected virtual string GetProjectFilePathForReferences(string buildArtifactsDirectoryPath) + => string.Empty; + /// /// returns a list of artifacts that should be removed after running the benchmarks /// @@ -143,6 +150,7 @@ private ArtifactsPaths GetArtifactsPaths(BuildPartition buildPartition, string r appConfigPath: $"{executablePath}.config", nuGetConfigPath: Path.Combine(buildArtifactsDirectoryPath, "NuGet.config"), projectFilePath: GetProjectFilePath(buildArtifactsDirectoryPath), + buildForReferencesProjectFilePath: GetProjectFilePathForReferences(buildArtifactsDirectoryPath), buildScriptFilePath: Path.Combine(buildArtifactsDirectoryPath, $"{programName}{OsDetector.ScriptFileExtension}"), executablePath: executablePath, programName: programName, diff --git a/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitArtifactsPath.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitArtifactsPath.cs index 0686a322ac..9a32366989 100644 --- a/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitArtifactsPath.cs +++ b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitArtifactsPath.cs @@ -17,6 +17,7 @@ public InProcessEmitArtifactsPath( baseArtifacts.AppConfigPath, baseArtifacts.NuGetConfigPath, baseArtifacts.ProjectFilePath, + baseArtifacts.BuildForReferencesProjectFilePath, baseArtifacts.BuildScriptFilePath, baseArtifacts.ExecutablePath, baseArtifacts.ProgramName, diff --git a/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitGenerator.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitGenerator.cs index 18734fcf46..f4cd5bcc23 100644 --- a/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitGenerator.cs +++ b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitGenerator.cs @@ -52,6 +52,7 @@ private ArtifactsPaths GetArtifactsPaths(BuildPartition buildPartition, string r appConfigPath: null, nuGetConfigPath: null, projectFilePath: null, + buildForReferencesProjectFilePath: null, buildScriptFilePath: null, executablePath: executablePath, programName: programName, diff --git a/src/BenchmarkDotNet/Toolchains/Mono/MonoPublisher.cs b/src/BenchmarkDotNet/Toolchains/Mono/MonoPublisher.cs index ff98540cbf..9ee3b54e82 100644 --- a/src/BenchmarkDotNet/Toolchains/Mono/MonoPublisher.cs +++ b/src/BenchmarkDotNet/Toolchains/Mono/MonoPublisher.cs @@ -25,14 +25,30 @@ public MonoPublisher(string customDotNetCliPath) private IReadOnlyList EnvironmentVariables { get; } public BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger) - => new DotNetCliCommand( - CustomDotNetCliPath, - ExtraArguments, - generateResult, - logger, - buildPartition, - EnvironmentVariables, - buildPartition.Timeout) - .Publish().ToBuildResult(generateResult); + { + var cliCommand = new DotNetCliCommand( + generateResult.ArtifactsPaths.BuildForReferencesProjectFilePath, + CustomDotNetCliPath, + string.Empty, + generateResult, + logger, + buildPartition, + EnvironmentVariables, + buildPartition.Timeout); + + // We build the original project first to obtain all dlls. + var buildResult = cliCommand.RestoreThenBuild(); + + if (!buildResult.IsBuildSuccess) + return buildResult; + + // After the dlls are built, we gather the assembly references, then build the benchmark project. + DotNetCliBuilder.GatherReferences(generateResult.ArtifactsPaths); + return cliCommand + .WithArguments(ExtraArguments) + .WithProjPath(generateResult.ArtifactsPaths.ProjectFilePath) + .Publish() + .ToBuildResult(generateResult); + } } } diff --git a/src/BenchmarkDotNet/Toolchains/MonoAotLLVM/MonoAotLLVMGenerator.cs b/src/BenchmarkDotNet/Toolchains/MonoAotLLVM/MonoAotLLVMGenerator.cs index de3cef53d3..e12e83f049 100644 --- a/src/BenchmarkDotNet/Toolchains/MonoAotLLVM/MonoAotLLVMGenerator.cs +++ b/src/BenchmarkDotNet/Toolchains/MonoAotLLVM/MonoAotLLVMGenerator.cs @@ -36,6 +36,8 @@ protected override void GenerateProject(BuildPartition buildPartition, Artifacts xmlDoc.Load(projectFile.FullName); var (customProperties, sdkName) = GetSettingsThatNeedToBeCopied(xmlDoc, projectFile); + GenerateBuildForReferencesProject(buildPartition, artifactsPaths, projectFile.FullName, customProperties, sdkName); + string content = new StringBuilder(ResourceHelper.LoadTemplate("MonoAOTLLVMCsProj.txt")) .Replace("$PLATFORM$", buildPartition.Platform.ToConfig()) .Replace("$CODEFILENAME$", Path.GetFileName(artifactsPaths.ProgramCodePath)) diff --git a/src/BenchmarkDotNet/Toolchains/MonoWasm/WasmGenerator.cs b/src/BenchmarkDotNet/Toolchains/MonoWasm/WasmGenerator.cs index 7c9aa8826f..3e138c94fc 100644 --- a/src/BenchmarkDotNet/Toolchains/MonoWasm/WasmGenerator.cs +++ b/src/BenchmarkDotNet/Toolchains/MonoWasm/WasmGenerator.cs @@ -49,6 +49,8 @@ protected void GenerateProjectFile(BuildPartition buildPartition, ArtifactsPaths xmlDoc.Load(projectFile.FullName); var (customProperties, sdkName) = GetSettingsThatNeedToBeCopied(xmlDoc, projectFile); + GenerateBuildForReferencesProject(buildPartition, artifactsPaths, projectFile.FullName, customProperties, sdkName); + string content = new StringBuilder(ResourceHelper.LoadTemplate("WasmCsProj.txt")) .Replace("$PLATFORM$", buildPartition.Platform.ToConfig()) .Replace("$CODEFILENAME$", Path.GetFileName(artifactsPaths.ProgramCodePath)) diff --git a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs index 061b64a9a8..43d2a9e027 100644 --- a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs +++ b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs @@ -74,8 +74,10 @@ protected override void GenerateBuildScript(BuildPartition buildPartition, Artif string extraArguments = NativeAotToolchain.GetExtraArguments(runtimeIdentifier); var content = new StringBuilder(300) - .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, extraArguments)}") - .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetPublishCommand(artifactsPaths, buildPartition, extraArguments)}") + .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, artifactsPaths.BuildForReferencesProjectFilePath, extraArguments)}") + .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetPublishCommand(artifactsPaths, buildPartition, artifactsPaths.BuildForReferencesProjectFilePath, extraArguments)}") + .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, artifactsPaths.ProjectFilePath, extraArguments)}") + .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetPublishCommand(artifactsPaths, buildPartition, artifactsPaths.ProjectFilePath, extraArguments)}") .ToString(); File.WriteAllText(artifactsPaths.BuildScriptFilePath, content); @@ -112,6 +114,14 @@ protected override void GenerateNuGetConfig(ArtifactsPaths artifactsPaths) protected override void GenerateProject(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, ILogger logger) { + var projectFile = GetProjectFilePath(buildPartition.RepresentativeBenchmarkCase.Descriptor.Type, logger); + + var xmlDoc = new XmlDocument(); + xmlDoc.Load(projectFile.FullName); + var (customProperties, sdkName) = GetSettingsThatNeedToBeCopied(xmlDoc, projectFile); + + GenerateBuildForReferencesProject(buildPartition, artifactsPaths, projectFile.FullName, customProperties, sdkName); + File.WriteAllText(artifactsPaths.ProjectFilePath, GenerateProjectForNuGetBuild(buildPartition, artifactsPaths, logger)); GenerateReflectionFile(artifactsPaths); } From f1bc9fad7570d0eaa6a0bac589d888dda83f526e Mon Sep 17 00:00:00 2001 From: Tim Date: Sat, 21 Dec 2024 22:47:18 -0500 Subject: [PATCH 2/3] Use a build traversal project template instead of copying csproj template. --- .../Templates/BuildTraversalProj.txt | 9 ++++ .../Toolchains/ArtifactsPaths.cs | 6 +-- .../Toolchains/CsProj/CsProjGenerator.cs | 44 +++++++++---------- .../Toolchains/DotNetCli/DotNetCliBuilder.cs | 7 +-- .../DotNetCli/DotNetCliGenerator.cs | 4 +- .../DotNetCli/DotNetCliPublisher.cs | 2 +- .../Toolchains/GeneratorBase.cs | 2 +- .../Emit/InProcessEmitArtifactsPath.cs | 2 +- .../InProcess/Emit/InProcessEmitGenerator.cs | 2 +- .../Toolchains/Mono/MonoPublisher.cs | 2 +- .../MonoAotLLVM/MonoAotLLVMGenerator.cs | 4 +- .../Toolchains/MonoWasm/WasmGenerator.cs | 4 +- .../Toolchains/NativeAot/Generator.cs | 10 ++--- 13 files changed, 49 insertions(+), 49 deletions(-) create mode 100644 src/BenchmarkDotNet/Templates/BuildTraversalProj.txt diff --git a/src/BenchmarkDotNet/Templates/BuildTraversalProj.txt b/src/BenchmarkDotNet/Templates/BuildTraversalProj.txt new file mode 100644 index 0000000000..7526ff15ff --- /dev/null +++ b/src/BenchmarkDotNet/Templates/BuildTraversalProj.txt @@ -0,0 +1,9 @@ + + + + + TargetFramework=$TFM$ + + + + diff --git a/src/BenchmarkDotNet/Toolchains/ArtifactsPaths.cs b/src/BenchmarkDotNet/Toolchains/ArtifactsPaths.cs index e082d126ee..0e1756d825 100644 --- a/src/BenchmarkDotNet/Toolchains/ArtifactsPaths.cs +++ b/src/BenchmarkDotNet/Toolchains/ArtifactsPaths.cs @@ -13,7 +13,7 @@ public class ArtifactsPaths [PublicAPI] public string ProgramCodePath { get; } [PublicAPI] public string AppConfigPath { get; } [PublicAPI] public string NuGetConfigPath { get; } - [PublicAPI] public string BuildForReferencesProjectFilePath { get; } + [PublicAPI] public string BuildTraversalProjectFilePath { get; } [PublicAPI] public string ProjectFilePath { get; } [PublicAPI] public string BuildScriptFilePath { get; } [PublicAPI] public string ExecutablePath { get; } @@ -28,7 +28,7 @@ public ArtifactsPaths( string programCodePath, string appConfigPath, string nuGetConfigPath, - string buildForReferencesProjectFilePath, + string buildTraversalProjectFilePath, string projectFilePath, string buildScriptFilePath, string executablePath, @@ -42,7 +42,7 @@ public ArtifactsPaths( ProgramCodePath = programCodePath; AppConfigPath = appConfigPath; NuGetConfigPath = nuGetConfigPath; - BuildForReferencesProjectFilePath = buildForReferencesProjectFilePath; + BuildTraversalProjectFilePath = buildTraversalProjectFilePath; ProjectFilePath = projectFilePath; BuildScriptFilePath = buildScriptFilePath; ExecutablePath = executablePath; diff --git a/src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs b/src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs index 0f95dea835..9d6bf7eabf 100644 --- a/src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs +++ b/src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs @@ -62,7 +62,7 @@ protected override string GetProjectFilePath(string buildArtifactsDirectoryPath) => Path.Combine(buildArtifactsDirectoryPath, "BenchmarkDotNet.Autogenerated.csproj"); protected override string GetProjectFilePathForReferences(string buildArtifactsDirectoryPath) - => Path.Combine(buildArtifactsDirectoryPath, "BenchmarkDotNet.Autogenerated.ForReferences.csproj"); + => Path.Combine(buildArtifactsDirectoryPath, "BuildTraversal.buildproj"); protected override string GetBinariesDirectoryPath(string buildArtifactsDirectoryPath, string configuration) => Path.Combine(buildArtifactsDirectoryPath, "bin", configuration, TargetFrameworkMoniker); @@ -71,8 +71,8 @@ protected override string GetIntermediateDirectoryPath(string buildArtifactsDire => Path.Combine(buildArtifactsDirectoryPath, "obj", configuration, TargetFrameworkMoniker); [SuppressMessage("ReSharper", "StringLiteralTypo")] // R# complains about $variables$ - private string LoadCsProj(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, string projectFile, string customProperties, string sdkName) - => new StringBuilder(ResourceHelper.LoadTemplate("CsProj.txt")) + private string LoadCsProj(string template, BuildPartition buildPartition, ArtifactsPaths artifactsPaths, string projectFile, string customProperties, string sdkName) + => new StringBuilder(ResourceHelper.LoadTemplate(template)) .Replace("$PLATFORM$", buildPartition.Platform.ToConfig()) .Replace("$CODEFILENAME$", Path.GetFileName(artifactsPaths.ProgramCodePath)) .Replace("$CSPROJPATH$", projectFile) @@ -88,35 +88,35 @@ protected override void GenerateProject(BuildPartition buildPartition, Artifacts { var projectFile = GetProjectFilePath(buildPartition.RepresentativeBenchmarkCase.Descriptor.Type, logger); + GenerateBuildTraversalProject(artifactsPaths, projectFile.FullName); + var xmlDoc = new XmlDocument(); xmlDoc.Load(projectFile.FullName); var (customProperties, sdkName) = GetSettingsThatNeedToBeCopied(xmlDoc, projectFile); - GenerateBuildForReferencesProject(buildPartition, artifactsPaths, projectFile.FullName, customProperties, sdkName); - - var content = LoadCsProj(buildPartition, artifactsPaths, projectFile.FullName, customProperties, sdkName); + var content = new StringBuilder(ResourceHelper.LoadTemplate("CsProj.txt")) + .Replace("$PLATFORM$", buildPartition.Platform.ToConfig()) + .Replace("$CODEFILENAME$", Path.GetFileName(artifactsPaths.ProgramCodePath)) + .Replace("$CSPROJPATH$", projectFile.FullName) + .Replace("$TFM$", TargetFrameworkMoniker) + .Replace("$PROGRAMNAME$", artifactsPaths.ProgramName) + .Replace("$RUNTIMESETTINGS$", GetRuntimeSettings(buildPartition.RepresentativeBenchmarkCase.Job.Environment.Gc, buildPartition.Resolver)) + .Replace("$COPIEDSETTINGS$", customProperties) + .Replace("$CONFIGURATIONNAME$", buildPartition.BuildConfiguration) + .Replace("$SDKNAME$", sdkName) + .ToString(); File.WriteAllText(artifactsPaths.ProjectFilePath, content); } - protected void GenerateBuildForReferencesProject(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, string projectFile, string customProperties, string sdkName) + protected void GenerateBuildTraversalProject(ArtifactsPaths artifactsPaths, string projectFilePath) { - var content = LoadCsProj(buildPartition, artifactsPaths, projectFile, customProperties, sdkName); - - // We don't include the generated .notcs file when building the reference dlls, only in the final build. - var xmlDoc = new XmlDocument(); - xmlDoc.Load(new StringReader(content)); - XmlElement projectElement = xmlDoc.DocumentElement; - projectElement.RemoveChild(projectElement.SelectSingleNode("ItemGroup/Compile").ParentNode); - - var startupObjectElement = projectElement.SelectSingleNode("PropertyGroup/StartupObject"); - startupObjectElement.ParentNode.RemoveChild(startupObjectElement); - - // We need to change the output type to library since we're only compiling for dlls. - var outputTypeElement = projectElement.SelectSingleNode("PropertyGroup/OutputType"); - outputTypeElement.InnerText = "Library"; + var content = new StringBuilder(ResourceHelper.LoadTemplate("BuildTraversalProj.txt")) + .Replace("$CSPROJPATH$", projectFilePath) + .Replace("$TFM$", TargetFrameworkMoniker) + .ToString(); - xmlDoc.Save(artifactsPaths.BuildForReferencesProjectFilePath); + File.WriteAllText(artifactsPaths.BuildTraversalProjectFilePath, content); } /// diff --git a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliBuilder.cs b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliBuilder.cs index fa8e05e9c7..67a6e27b67 100644 --- a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliBuilder.cs +++ b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliBuilder.cs @@ -28,7 +28,7 @@ public DotNetCliBuilder(string targetFrameworkMoniker, string? customDotNetCliPa public BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger) { var cliCommand = new DotNetCliCommand( - generateResult.ArtifactsPaths.BuildForReferencesProjectFilePath, + generateResult.ArtifactsPaths.BuildTraversalProjectFilePath, CustomDotNetCliPath, string.Empty, generateResult, @@ -75,11 +75,6 @@ internal static void GatherReferences(ArtifactsPaths artifactsPaths) foreach (var assemblyFile in Directory.GetFiles(artifactsPaths.BinariesDirectoryPath, "*.dll")) { var assemblyName = Path.GetFileNameWithoutExtension(assemblyFile); - // The dummy csproj was used to build the original project, but it also outputs a dll for itself which we need to ignore because it's not valid. - if (assemblyName == artifactsPaths.ProgramName) - { - continue; - } var referenceElement = xmlDoc.CreateElement("Reference"); itemGroup.AppendChild(referenceElement); referenceElement.SetAttribute("Include", assemblyName); diff --git a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliGenerator.cs b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliGenerator.cs index ddf609d8df..2b31468574 100644 --- a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliGenerator.cs +++ b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliGenerator.cs @@ -101,8 +101,8 @@ protected override void CopyAllRequiredFiles(ArtifactsPaths artifactsPaths) protected override void GenerateBuildScript(BuildPartition buildPartition, ArtifactsPaths artifactsPaths) { var content = new StringBuilder(300) - .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, artifactsPaths.BuildForReferencesProjectFilePath)}") - .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetBuildCommand(artifactsPaths, buildPartition, artifactsPaths.BuildForReferencesProjectFilePath)}") + .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, artifactsPaths.BuildTraversalProjectFilePath)}") + .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetBuildCommand(artifactsPaths, buildPartition, artifactsPaths.BuildTraversalProjectFilePath)}") .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, artifactsPaths.ProjectFilePath)}") .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetBuildCommand(artifactsPaths, buildPartition, artifactsPaths.ProjectFilePath)}") .ToString(); diff --git a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliPublisher.cs b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliPublisher.cs index 72dc14aecc..4cfb346a9a 100644 --- a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliPublisher.cs +++ b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliPublisher.cs @@ -27,7 +27,7 @@ public DotNetCliPublisher( public BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger) { var cliCommand = new DotNetCliCommand( - generateResult.ArtifactsPaths.BuildForReferencesProjectFilePath, + generateResult.ArtifactsPaths.BuildTraversalProjectFilePath, CustomDotNetCliPath, ExtraArguments, generateResult, diff --git a/src/BenchmarkDotNet/Toolchains/GeneratorBase.cs b/src/BenchmarkDotNet/Toolchains/GeneratorBase.cs index b1cb0f2837..5ee59759f0 100644 --- a/src/BenchmarkDotNet/Toolchains/GeneratorBase.cs +++ b/src/BenchmarkDotNet/Toolchains/GeneratorBase.cs @@ -150,7 +150,7 @@ private ArtifactsPaths GetArtifactsPaths(BuildPartition buildPartition, string r appConfigPath: $"{executablePath}.config", nuGetConfigPath: Path.Combine(buildArtifactsDirectoryPath, "NuGet.config"), projectFilePath: GetProjectFilePath(buildArtifactsDirectoryPath), - buildForReferencesProjectFilePath: GetProjectFilePathForReferences(buildArtifactsDirectoryPath), + buildTraversalProjectFilePath: GetProjectFilePathForReferences(buildArtifactsDirectoryPath), buildScriptFilePath: Path.Combine(buildArtifactsDirectoryPath, $"{programName}{OsDetector.ScriptFileExtension}"), executablePath: executablePath, programName: programName, diff --git a/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitArtifactsPath.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitArtifactsPath.cs index 9a32366989..49e83eb45f 100644 --- a/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitArtifactsPath.cs +++ b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitArtifactsPath.cs @@ -17,7 +17,7 @@ public InProcessEmitArtifactsPath( baseArtifacts.AppConfigPath, baseArtifacts.NuGetConfigPath, baseArtifacts.ProjectFilePath, - baseArtifacts.BuildForReferencesProjectFilePath, + baseArtifacts.BuildTraversalProjectFilePath, baseArtifacts.BuildScriptFilePath, baseArtifacts.ExecutablePath, baseArtifacts.ProgramName, diff --git a/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitGenerator.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitGenerator.cs index f4cd5bcc23..d0a6ce9444 100644 --- a/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitGenerator.cs +++ b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitGenerator.cs @@ -52,7 +52,7 @@ private ArtifactsPaths GetArtifactsPaths(BuildPartition buildPartition, string r appConfigPath: null, nuGetConfigPath: null, projectFilePath: null, - buildForReferencesProjectFilePath: null, + buildTraversalProjectFilePath: null, buildScriptFilePath: null, executablePath: executablePath, programName: programName, diff --git a/src/BenchmarkDotNet/Toolchains/Mono/MonoPublisher.cs b/src/BenchmarkDotNet/Toolchains/Mono/MonoPublisher.cs index 9ee3b54e82..8634f0e0e8 100644 --- a/src/BenchmarkDotNet/Toolchains/Mono/MonoPublisher.cs +++ b/src/BenchmarkDotNet/Toolchains/Mono/MonoPublisher.cs @@ -27,7 +27,7 @@ public MonoPublisher(string customDotNetCliPath) public BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger) { var cliCommand = new DotNetCliCommand( - generateResult.ArtifactsPaths.BuildForReferencesProjectFilePath, + generateResult.ArtifactsPaths.BuildTraversalProjectFilePath, CustomDotNetCliPath, string.Empty, generateResult, diff --git a/src/BenchmarkDotNet/Toolchains/MonoAotLLVM/MonoAotLLVMGenerator.cs b/src/BenchmarkDotNet/Toolchains/MonoAotLLVM/MonoAotLLVMGenerator.cs index e12e83f049..c990759b44 100644 --- a/src/BenchmarkDotNet/Toolchains/MonoAotLLVM/MonoAotLLVMGenerator.cs +++ b/src/BenchmarkDotNet/Toolchains/MonoAotLLVM/MonoAotLLVMGenerator.cs @@ -30,14 +30,14 @@ protected override void GenerateProject(BuildPartition buildPartition, Artifacts BenchmarkCase benchmark = buildPartition.RepresentativeBenchmarkCase; var projectFile = GetProjectFilePath(benchmark.Descriptor.Type, logger); + GenerateBuildTraversalProject(artifactsPaths, projectFile.FullName); + string useLLVM = AotCompilerMode == MonoAotCompilerMode.llvm ? "true" : "false"; var xmlDoc = new XmlDocument(); xmlDoc.Load(projectFile.FullName); var (customProperties, sdkName) = GetSettingsThatNeedToBeCopied(xmlDoc, projectFile); - GenerateBuildForReferencesProject(buildPartition, artifactsPaths, projectFile.FullName, customProperties, sdkName); - string content = new StringBuilder(ResourceHelper.LoadTemplate("MonoAOTLLVMCsProj.txt")) .Replace("$PLATFORM$", buildPartition.Platform.ToConfig()) .Replace("$CODEFILENAME$", Path.GetFileName(artifactsPaths.ProgramCodePath)) diff --git a/src/BenchmarkDotNet/Toolchains/MonoWasm/WasmGenerator.cs b/src/BenchmarkDotNet/Toolchains/MonoWasm/WasmGenerator.cs index 3e138c94fc..b4ca5e58ed 100644 --- a/src/BenchmarkDotNet/Toolchains/MonoWasm/WasmGenerator.cs +++ b/src/BenchmarkDotNet/Toolchains/MonoWasm/WasmGenerator.cs @@ -43,14 +43,14 @@ protected void GenerateProjectFile(BuildPartition buildPartition, ArtifactsPaths BenchmarkCase benchmark = buildPartition.RepresentativeBenchmarkCase; var projectFile = GetProjectFilePath(benchmark.Descriptor.Type, logger); + GenerateBuildTraversalProject(artifactsPaths, projectFile.FullName); + WasmRuntime runtime = (WasmRuntime) buildPartition.Runtime; var xmlDoc = new XmlDocument(); xmlDoc.Load(projectFile.FullName); var (customProperties, sdkName) = GetSettingsThatNeedToBeCopied(xmlDoc, projectFile); - GenerateBuildForReferencesProject(buildPartition, artifactsPaths, projectFile.FullName, customProperties, sdkName); - string content = new StringBuilder(ResourceHelper.LoadTemplate("WasmCsProj.txt")) .Replace("$PLATFORM$", buildPartition.Platform.ToConfig()) .Replace("$CODEFILENAME$", Path.GetFileName(artifactsPaths.ProgramCodePath)) diff --git a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs index 43d2a9e027..eb31df539a 100644 --- a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs +++ b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs @@ -74,8 +74,8 @@ protected override void GenerateBuildScript(BuildPartition buildPartition, Artif string extraArguments = NativeAotToolchain.GetExtraArguments(runtimeIdentifier); var content = new StringBuilder(300) - .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, artifactsPaths.BuildForReferencesProjectFilePath, extraArguments)}") - .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetPublishCommand(artifactsPaths, buildPartition, artifactsPaths.BuildForReferencesProjectFilePath, extraArguments)}") + .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, artifactsPaths.BuildTraversalProjectFilePath, extraArguments)}") + .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetPublishCommand(artifactsPaths, buildPartition, artifactsPaths.BuildTraversalProjectFilePath, extraArguments)}") .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, artifactsPaths.ProjectFilePath, extraArguments)}") .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetPublishCommand(artifactsPaths, buildPartition, artifactsPaths.ProjectFilePath, extraArguments)}") .ToString(); @@ -116,11 +116,7 @@ protected override void GenerateProject(BuildPartition buildPartition, Artifacts { var projectFile = GetProjectFilePath(buildPartition.RepresentativeBenchmarkCase.Descriptor.Type, logger); - var xmlDoc = new XmlDocument(); - xmlDoc.Load(projectFile.FullName); - var (customProperties, sdkName) = GetSettingsThatNeedToBeCopied(xmlDoc, projectFile); - - GenerateBuildForReferencesProject(buildPartition, artifactsPaths, projectFile.FullName, customProperties, sdkName); + GenerateBuildTraversalProject(artifactsPaths, projectFile.FullName); File.WriteAllText(artifactsPaths.ProjectFilePath, GenerateProjectForNuGetBuild(buildPartition, artifactsPaths, logger)); GenerateReflectionFile(artifactsPaths); From 9202503fd6c66425769ba5a63dcc512728704ac8 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 2 Jan 2025 06:19:21 -0500 Subject: [PATCH 3/3] Revert "Use a build traversal project template instead of copying csproj template." This reverts commit f1bc9fad7570d0eaa6a0bac589d888dda83f526e. --- .../Templates/BuildTraversalProj.txt | 9 ---- .../Toolchains/ArtifactsPaths.cs | 6 +-- .../Toolchains/CsProj/CsProjGenerator.cs | 44 +++++++++---------- .../Toolchains/DotNetCli/DotNetCliBuilder.cs | 7 ++- .../DotNetCli/DotNetCliGenerator.cs | 4 +- .../DotNetCli/DotNetCliPublisher.cs | 2 +- .../Toolchains/GeneratorBase.cs | 2 +- .../Emit/InProcessEmitArtifactsPath.cs | 2 +- .../InProcess/Emit/InProcessEmitGenerator.cs | 2 +- .../Toolchains/Mono/MonoPublisher.cs | 2 +- .../MonoAotLLVM/MonoAotLLVMGenerator.cs | 4 +- .../Toolchains/MonoWasm/WasmGenerator.cs | 4 +- .../Toolchains/NativeAot/Generator.cs | 10 +++-- 13 files changed, 49 insertions(+), 49 deletions(-) delete mode 100644 src/BenchmarkDotNet/Templates/BuildTraversalProj.txt diff --git a/src/BenchmarkDotNet/Templates/BuildTraversalProj.txt b/src/BenchmarkDotNet/Templates/BuildTraversalProj.txt deleted file mode 100644 index 7526ff15ff..0000000000 --- a/src/BenchmarkDotNet/Templates/BuildTraversalProj.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - TargetFramework=$TFM$ - - - - diff --git a/src/BenchmarkDotNet/Toolchains/ArtifactsPaths.cs b/src/BenchmarkDotNet/Toolchains/ArtifactsPaths.cs index 0e1756d825..e082d126ee 100644 --- a/src/BenchmarkDotNet/Toolchains/ArtifactsPaths.cs +++ b/src/BenchmarkDotNet/Toolchains/ArtifactsPaths.cs @@ -13,7 +13,7 @@ public class ArtifactsPaths [PublicAPI] public string ProgramCodePath { get; } [PublicAPI] public string AppConfigPath { get; } [PublicAPI] public string NuGetConfigPath { get; } - [PublicAPI] public string BuildTraversalProjectFilePath { get; } + [PublicAPI] public string BuildForReferencesProjectFilePath { get; } [PublicAPI] public string ProjectFilePath { get; } [PublicAPI] public string BuildScriptFilePath { get; } [PublicAPI] public string ExecutablePath { get; } @@ -28,7 +28,7 @@ public ArtifactsPaths( string programCodePath, string appConfigPath, string nuGetConfigPath, - string buildTraversalProjectFilePath, + string buildForReferencesProjectFilePath, string projectFilePath, string buildScriptFilePath, string executablePath, @@ -42,7 +42,7 @@ public ArtifactsPaths( ProgramCodePath = programCodePath; AppConfigPath = appConfigPath; NuGetConfigPath = nuGetConfigPath; - BuildTraversalProjectFilePath = buildTraversalProjectFilePath; + BuildForReferencesProjectFilePath = buildForReferencesProjectFilePath; ProjectFilePath = projectFilePath; BuildScriptFilePath = buildScriptFilePath; ExecutablePath = executablePath; diff --git a/src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs b/src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs index 9d6bf7eabf..0f95dea835 100644 --- a/src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs +++ b/src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs @@ -62,7 +62,7 @@ protected override string GetProjectFilePath(string buildArtifactsDirectoryPath) => Path.Combine(buildArtifactsDirectoryPath, "BenchmarkDotNet.Autogenerated.csproj"); protected override string GetProjectFilePathForReferences(string buildArtifactsDirectoryPath) - => Path.Combine(buildArtifactsDirectoryPath, "BuildTraversal.buildproj"); + => Path.Combine(buildArtifactsDirectoryPath, "BenchmarkDotNet.Autogenerated.ForReferences.csproj"); protected override string GetBinariesDirectoryPath(string buildArtifactsDirectoryPath, string configuration) => Path.Combine(buildArtifactsDirectoryPath, "bin", configuration, TargetFrameworkMoniker); @@ -71,8 +71,8 @@ protected override string GetIntermediateDirectoryPath(string buildArtifactsDire => Path.Combine(buildArtifactsDirectoryPath, "obj", configuration, TargetFrameworkMoniker); [SuppressMessage("ReSharper", "StringLiteralTypo")] // R# complains about $variables$ - private string LoadCsProj(string template, BuildPartition buildPartition, ArtifactsPaths artifactsPaths, string projectFile, string customProperties, string sdkName) - => new StringBuilder(ResourceHelper.LoadTemplate(template)) + private string LoadCsProj(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, string projectFile, string customProperties, string sdkName) + => new StringBuilder(ResourceHelper.LoadTemplate("CsProj.txt")) .Replace("$PLATFORM$", buildPartition.Platform.ToConfig()) .Replace("$CODEFILENAME$", Path.GetFileName(artifactsPaths.ProgramCodePath)) .Replace("$CSPROJPATH$", projectFile) @@ -88,35 +88,35 @@ protected override void GenerateProject(BuildPartition buildPartition, Artifacts { var projectFile = GetProjectFilePath(buildPartition.RepresentativeBenchmarkCase.Descriptor.Type, logger); - GenerateBuildTraversalProject(artifactsPaths, projectFile.FullName); - var xmlDoc = new XmlDocument(); xmlDoc.Load(projectFile.FullName); var (customProperties, sdkName) = GetSettingsThatNeedToBeCopied(xmlDoc, projectFile); - var content = new StringBuilder(ResourceHelper.LoadTemplate("CsProj.txt")) - .Replace("$PLATFORM$", buildPartition.Platform.ToConfig()) - .Replace("$CODEFILENAME$", Path.GetFileName(artifactsPaths.ProgramCodePath)) - .Replace("$CSPROJPATH$", projectFile.FullName) - .Replace("$TFM$", TargetFrameworkMoniker) - .Replace("$PROGRAMNAME$", artifactsPaths.ProgramName) - .Replace("$RUNTIMESETTINGS$", GetRuntimeSettings(buildPartition.RepresentativeBenchmarkCase.Job.Environment.Gc, buildPartition.Resolver)) - .Replace("$COPIEDSETTINGS$", customProperties) - .Replace("$CONFIGURATIONNAME$", buildPartition.BuildConfiguration) - .Replace("$SDKNAME$", sdkName) - .ToString(); + GenerateBuildForReferencesProject(buildPartition, artifactsPaths, projectFile.FullName, customProperties, sdkName); + + var content = LoadCsProj(buildPartition, artifactsPaths, projectFile.FullName, customProperties, sdkName); File.WriteAllText(artifactsPaths.ProjectFilePath, content); } - protected void GenerateBuildTraversalProject(ArtifactsPaths artifactsPaths, string projectFilePath) + protected void GenerateBuildForReferencesProject(BuildPartition buildPartition, ArtifactsPaths artifactsPaths, string projectFile, string customProperties, string sdkName) { - var content = new StringBuilder(ResourceHelper.LoadTemplate("BuildTraversalProj.txt")) - .Replace("$CSPROJPATH$", projectFilePath) - .Replace("$TFM$", TargetFrameworkMoniker) - .ToString(); + var content = LoadCsProj(buildPartition, artifactsPaths, projectFile, customProperties, sdkName); + + // We don't include the generated .notcs file when building the reference dlls, only in the final build. + var xmlDoc = new XmlDocument(); + xmlDoc.Load(new StringReader(content)); + XmlElement projectElement = xmlDoc.DocumentElement; + projectElement.RemoveChild(projectElement.SelectSingleNode("ItemGroup/Compile").ParentNode); + + var startupObjectElement = projectElement.SelectSingleNode("PropertyGroup/StartupObject"); + startupObjectElement.ParentNode.RemoveChild(startupObjectElement); + + // We need to change the output type to library since we're only compiling for dlls. + var outputTypeElement = projectElement.SelectSingleNode("PropertyGroup/OutputType"); + outputTypeElement.InnerText = "Library"; - File.WriteAllText(artifactsPaths.BuildTraversalProjectFilePath, content); + xmlDoc.Save(artifactsPaths.BuildForReferencesProjectFilePath); } /// diff --git a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliBuilder.cs b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliBuilder.cs index 67a6e27b67..fa8e05e9c7 100644 --- a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliBuilder.cs +++ b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliBuilder.cs @@ -28,7 +28,7 @@ public DotNetCliBuilder(string targetFrameworkMoniker, string? customDotNetCliPa public BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger) { var cliCommand = new DotNetCliCommand( - generateResult.ArtifactsPaths.BuildTraversalProjectFilePath, + generateResult.ArtifactsPaths.BuildForReferencesProjectFilePath, CustomDotNetCliPath, string.Empty, generateResult, @@ -75,6 +75,11 @@ internal static void GatherReferences(ArtifactsPaths artifactsPaths) foreach (var assemblyFile in Directory.GetFiles(artifactsPaths.BinariesDirectoryPath, "*.dll")) { var assemblyName = Path.GetFileNameWithoutExtension(assemblyFile); + // The dummy csproj was used to build the original project, but it also outputs a dll for itself which we need to ignore because it's not valid. + if (assemblyName == artifactsPaths.ProgramName) + { + continue; + } var referenceElement = xmlDoc.CreateElement("Reference"); itemGroup.AppendChild(referenceElement); referenceElement.SetAttribute("Include", assemblyName); diff --git a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliGenerator.cs b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliGenerator.cs index 2b31468574..ddf609d8df 100644 --- a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliGenerator.cs +++ b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliGenerator.cs @@ -101,8 +101,8 @@ protected override void CopyAllRequiredFiles(ArtifactsPaths artifactsPaths) protected override void GenerateBuildScript(BuildPartition buildPartition, ArtifactsPaths artifactsPaths) { var content = new StringBuilder(300) - .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, artifactsPaths.BuildTraversalProjectFilePath)}") - .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetBuildCommand(artifactsPaths, buildPartition, artifactsPaths.BuildTraversalProjectFilePath)}") + .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, artifactsPaths.BuildForReferencesProjectFilePath)}") + .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetBuildCommand(artifactsPaths, buildPartition, artifactsPaths.BuildForReferencesProjectFilePath)}") .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, artifactsPaths.ProjectFilePath)}") .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetBuildCommand(artifactsPaths, buildPartition, artifactsPaths.ProjectFilePath)}") .ToString(); diff --git a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliPublisher.cs b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliPublisher.cs index 4cfb346a9a..72dc14aecc 100644 --- a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliPublisher.cs +++ b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliPublisher.cs @@ -27,7 +27,7 @@ public DotNetCliPublisher( public BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger) { var cliCommand = new DotNetCliCommand( - generateResult.ArtifactsPaths.BuildTraversalProjectFilePath, + generateResult.ArtifactsPaths.BuildForReferencesProjectFilePath, CustomDotNetCliPath, ExtraArguments, generateResult, diff --git a/src/BenchmarkDotNet/Toolchains/GeneratorBase.cs b/src/BenchmarkDotNet/Toolchains/GeneratorBase.cs index 5ee59759f0..b1cb0f2837 100644 --- a/src/BenchmarkDotNet/Toolchains/GeneratorBase.cs +++ b/src/BenchmarkDotNet/Toolchains/GeneratorBase.cs @@ -150,7 +150,7 @@ private ArtifactsPaths GetArtifactsPaths(BuildPartition buildPartition, string r appConfigPath: $"{executablePath}.config", nuGetConfigPath: Path.Combine(buildArtifactsDirectoryPath, "NuGet.config"), projectFilePath: GetProjectFilePath(buildArtifactsDirectoryPath), - buildTraversalProjectFilePath: GetProjectFilePathForReferences(buildArtifactsDirectoryPath), + buildForReferencesProjectFilePath: GetProjectFilePathForReferences(buildArtifactsDirectoryPath), buildScriptFilePath: Path.Combine(buildArtifactsDirectoryPath, $"{programName}{OsDetector.ScriptFileExtension}"), executablePath: executablePath, programName: programName, diff --git a/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitArtifactsPath.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitArtifactsPath.cs index 49e83eb45f..9a32366989 100644 --- a/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitArtifactsPath.cs +++ b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitArtifactsPath.cs @@ -17,7 +17,7 @@ public InProcessEmitArtifactsPath( baseArtifacts.AppConfigPath, baseArtifacts.NuGetConfigPath, baseArtifacts.ProjectFilePath, - baseArtifacts.BuildTraversalProjectFilePath, + baseArtifacts.BuildForReferencesProjectFilePath, baseArtifacts.BuildScriptFilePath, baseArtifacts.ExecutablePath, baseArtifacts.ProgramName, diff --git a/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitGenerator.cs b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitGenerator.cs index d0a6ce9444..f4cd5bcc23 100644 --- a/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitGenerator.cs +++ b/src/BenchmarkDotNet/Toolchains/InProcess/Emit/InProcessEmitGenerator.cs @@ -52,7 +52,7 @@ private ArtifactsPaths GetArtifactsPaths(BuildPartition buildPartition, string r appConfigPath: null, nuGetConfigPath: null, projectFilePath: null, - buildTraversalProjectFilePath: null, + buildForReferencesProjectFilePath: null, buildScriptFilePath: null, executablePath: executablePath, programName: programName, diff --git a/src/BenchmarkDotNet/Toolchains/Mono/MonoPublisher.cs b/src/BenchmarkDotNet/Toolchains/Mono/MonoPublisher.cs index 8634f0e0e8..9ee3b54e82 100644 --- a/src/BenchmarkDotNet/Toolchains/Mono/MonoPublisher.cs +++ b/src/BenchmarkDotNet/Toolchains/Mono/MonoPublisher.cs @@ -27,7 +27,7 @@ public MonoPublisher(string customDotNetCliPath) public BuildResult Build(GenerateResult generateResult, BuildPartition buildPartition, ILogger logger) { var cliCommand = new DotNetCliCommand( - generateResult.ArtifactsPaths.BuildTraversalProjectFilePath, + generateResult.ArtifactsPaths.BuildForReferencesProjectFilePath, CustomDotNetCliPath, string.Empty, generateResult, diff --git a/src/BenchmarkDotNet/Toolchains/MonoAotLLVM/MonoAotLLVMGenerator.cs b/src/BenchmarkDotNet/Toolchains/MonoAotLLVM/MonoAotLLVMGenerator.cs index c990759b44..e12e83f049 100644 --- a/src/BenchmarkDotNet/Toolchains/MonoAotLLVM/MonoAotLLVMGenerator.cs +++ b/src/BenchmarkDotNet/Toolchains/MonoAotLLVM/MonoAotLLVMGenerator.cs @@ -30,14 +30,14 @@ protected override void GenerateProject(BuildPartition buildPartition, Artifacts BenchmarkCase benchmark = buildPartition.RepresentativeBenchmarkCase; var projectFile = GetProjectFilePath(benchmark.Descriptor.Type, logger); - GenerateBuildTraversalProject(artifactsPaths, projectFile.FullName); - string useLLVM = AotCompilerMode == MonoAotCompilerMode.llvm ? "true" : "false"; var xmlDoc = new XmlDocument(); xmlDoc.Load(projectFile.FullName); var (customProperties, sdkName) = GetSettingsThatNeedToBeCopied(xmlDoc, projectFile); + GenerateBuildForReferencesProject(buildPartition, artifactsPaths, projectFile.FullName, customProperties, sdkName); + string content = new StringBuilder(ResourceHelper.LoadTemplate("MonoAOTLLVMCsProj.txt")) .Replace("$PLATFORM$", buildPartition.Platform.ToConfig()) .Replace("$CODEFILENAME$", Path.GetFileName(artifactsPaths.ProgramCodePath)) diff --git a/src/BenchmarkDotNet/Toolchains/MonoWasm/WasmGenerator.cs b/src/BenchmarkDotNet/Toolchains/MonoWasm/WasmGenerator.cs index b4ca5e58ed..3e138c94fc 100644 --- a/src/BenchmarkDotNet/Toolchains/MonoWasm/WasmGenerator.cs +++ b/src/BenchmarkDotNet/Toolchains/MonoWasm/WasmGenerator.cs @@ -43,14 +43,14 @@ protected void GenerateProjectFile(BuildPartition buildPartition, ArtifactsPaths BenchmarkCase benchmark = buildPartition.RepresentativeBenchmarkCase; var projectFile = GetProjectFilePath(benchmark.Descriptor.Type, logger); - GenerateBuildTraversalProject(artifactsPaths, projectFile.FullName); - WasmRuntime runtime = (WasmRuntime) buildPartition.Runtime; var xmlDoc = new XmlDocument(); xmlDoc.Load(projectFile.FullName); var (customProperties, sdkName) = GetSettingsThatNeedToBeCopied(xmlDoc, projectFile); + GenerateBuildForReferencesProject(buildPartition, artifactsPaths, projectFile.FullName, customProperties, sdkName); + string content = new StringBuilder(ResourceHelper.LoadTemplate("WasmCsProj.txt")) .Replace("$PLATFORM$", buildPartition.Platform.ToConfig()) .Replace("$CODEFILENAME$", Path.GetFileName(artifactsPaths.ProgramCodePath)) diff --git a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs index eb31df539a..43d2a9e027 100644 --- a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs +++ b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs @@ -74,8 +74,8 @@ protected override void GenerateBuildScript(BuildPartition buildPartition, Artif string extraArguments = NativeAotToolchain.GetExtraArguments(runtimeIdentifier); var content = new StringBuilder(300) - .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, artifactsPaths.BuildTraversalProjectFilePath, extraArguments)}") - .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetPublishCommand(artifactsPaths, buildPartition, artifactsPaths.BuildTraversalProjectFilePath, extraArguments)}") + .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, artifactsPaths.BuildForReferencesProjectFilePath, extraArguments)}") + .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetPublishCommand(artifactsPaths, buildPartition, artifactsPaths.BuildForReferencesProjectFilePath, extraArguments)}") .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetRestoreCommand(artifactsPaths, buildPartition, artifactsPaths.ProjectFilePath, extraArguments)}") .AppendLine($"call {CliPath ?? "dotnet"} {DotNetCliCommand.GetPublishCommand(artifactsPaths, buildPartition, artifactsPaths.ProjectFilePath, extraArguments)}") .ToString(); @@ -116,7 +116,11 @@ protected override void GenerateProject(BuildPartition buildPartition, Artifacts { var projectFile = GetProjectFilePath(buildPartition.RepresentativeBenchmarkCase.Descriptor.Type, logger); - GenerateBuildTraversalProject(artifactsPaths, projectFile.FullName); + var xmlDoc = new XmlDocument(); + xmlDoc.Load(projectFile.FullName); + var (customProperties, sdkName) = GetSettingsThatNeedToBeCopied(xmlDoc, projectFile); + + GenerateBuildForReferencesProject(buildPartition, artifactsPaths, projectFile.FullName, customProperties, sdkName); File.WriteAllText(artifactsPaths.ProjectFilePath, GenerateProjectForNuGetBuild(buildPartition, artifactsPaths, logger)); GenerateReflectionFile(artifactsPaths);