44using System . Linq ;
55using System . Text ;
66using BenchmarkDotNet . Characteristics ;
7+ using BenchmarkDotNet . Environments ;
78using BenchmarkDotNet . Extensions ;
89using BenchmarkDotNet . Jobs ;
910using BenchmarkDotNet . Loggers ;
@@ -71,12 +72,12 @@ public BuildResult RestoreThenBuild()
7172 if ( BuildPartition . ForcedNoDependenciesForIntegrationTests )
7273 {
7374 var restoreResult = DotNetCliCommandExecutor . Execute ( WithArguments (
74- GetRestoreCommand ( GenerateResult . ArtifactsPaths , BuildPartition , $ "{ Arguments } --no-dependencies", "restore-no-deps" , excludeOutput : true ) ) ) ;
75+ GetRestoreCommand ( GenerateResult . ArtifactsPaths , BuildPartition , GetWithArtifactsPath ( ) , $ "{ Arguments } --no-dependencies", "restore-no-deps" , excludeOutput : true ) ) ) ;
7576 if ( ! restoreResult . IsSuccess )
7677 return BuildResult . Failure ( GenerateResult , restoreResult . AllInformation ) ;
7778
7879 return DotNetCliCommandExecutor . Execute ( WithArguments (
79- GetBuildCommand ( GenerateResult . ArtifactsPaths , BuildPartition , $ "{ Arguments } --no-restore --no-dependencies", "build-no-restore-no-deps" , excludeOutput : true ) ) )
80+ GetBuildCommand ( GenerateResult . ArtifactsPaths , BuildPartition , GetWithArtifactsPath ( ) , $ "{ Arguments } --no-restore --no-dependencies", "build-no-restore-no-deps" , excludeOutput : true ) ) )
8081 . ToBuildResult ( GenerateResult ) ;
8182 }
8283 else
@@ -128,61 +129,66 @@ public DotNetCliCommandResult AddPackages()
128129 return DotNetCliCommandResult . Success ( executionTime , stdOutput . ToString ( ) ) ;
129130 }
130131
132+ private bool GetWithArtifactsPath ( ) => DotNetCliCommandExecutor . DotNetSdkSupportsArtifactsPath ( CliPath ) ;
133+
131134 public DotNetCliCommandResult Restore ( )
132135 => DotNetCliCommandExecutor . Execute ( WithArguments (
133- GetRestoreCommand ( GenerateResult . ArtifactsPaths , BuildPartition , Arguments , "restore" ) ) ) ;
136+ GetRestoreCommand ( GenerateResult . ArtifactsPaths , BuildPartition , GetWithArtifactsPath ( ) , Arguments , "restore" ) ) ) ;
134137
135138 public DotNetCliCommandResult Build ( )
136139 => DotNetCliCommandExecutor . Execute ( WithArguments (
137- GetBuildCommand ( GenerateResult . ArtifactsPaths , BuildPartition , Arguments , "build" ) ) ) ;
140+ GetBuildCommand ( GenerateResult . ArtifactsPaths , BuildPartition , GetWithArtifactsPath ( ) , Arguments , "build" ) ) ) ;
138141
139142 public DotNetCliCommandResult BuildNoRestore ( )
140143 => DotNetCliCommandExecutor . Execute ( WithArguments (
141- GetBuildCommand ( GenerateResult . ArtifactsPaths , BuildPartition , $ "{ Arguments } --no-restore", "build-no-restore" ) ) ) ;
144+ GetBuildCommand ( GenerateResult . ArtifactsPaths , BuildPartition , GetWithArtifactsPath ( ) , $ "{ Arguments } --no-restore", "build-no-restore" ) ) ) ;
142145
143146 public DotNetCliCommandResult Publish ( )
144147 => DotNetCliCommandExecutor . Execute ( WithArguments (
145- GetPublishCommand ( GenerateResult . ArtifactsPaths , BuildPartition , Arguments , "publish" ) ) ) ;
148+ GetPublishCommand ( GenerateResult . ArtifactsPaths , BuildPartition , GetWithArtifactsPath ( ) , Arguments , "publish" ) ) ) ;
146149
147150 // PublishNoBuildAndNoRestore was removed because we set --output in the build step. We use the implicit build included in the publish command.
148151 public DotNetCliCommandResult PublishNoRestore ( )
149152 => DotNetCliCommandExecutor . Execute ( WithArguments (
150- GetPublishCommand ( GenerateResult . ArtifactsPaths , BuildPartition , $ "{ Arguments } --no-restore", "publish-no-restore" ) ) ) ;
153+ GetPublishCommand ( GenerateResult . ArtifactsPaths , BuildPartition , GetWithArtifactsPath ( ) , $ "{ Arguments } --no-restore", "publish-no-restore" ) ) ) ;
151154
152155 internal static IEnumerable < string > GetAddPackagesCommands ( BuildPartition buildPartition )
153156 => GetNuGetAddPackageCommands ( buildPartition . RepresentativeBenchmarkCase , buildPartition . Resolver ) ;
154157
155- internal static string GetRestoreCommand ( ArtifactsPaths artifactsPaths , BuildPartition buildPartition , string ? extraArguments = null , string ? binLogSuffix = null , bool excludeOutput = false )
158+ internal static string GetRestoreCommand ( ArtifactsPaths artifactsPaths , BuildPartition buildPartition ,
159+ bool withArtifactsPath , string ? extraArguments = null , string ? binLogSuffix = null , bool excludeOutput = false )
156160 => new StringBuilder ( )
157161 . AppendArgument ( "restore" )
158162 . AppendArgument ( string . IsNullOrEmpty ( artifactsPaths . PackagesDirectoryName ) ? string . Empty : $ "--packages \" { artifactsPaths . PackagesDirectoryName } \" ")
159163 . AppendArgument ( GetCustomMsBuildArguments ( buildPartition . RepresentativeBenchmarkCase , buildPartition . Resolver ) )
160164 . AppendArgument ( extraArguments )
161165 . AppendArgument ( GetMandatoryMsBuildSettings ( buildPartition . BuildConfiguration ) )
162166 . AppendArgument ( GetMsBuildBinLogArgument ( buildPartition , binLogSuffix ) )
163- . MaybeAppendOutputPaths ( artifactsPaths , true , excludeOutput )
167+ . MaybeAppendOutputPaths ( artifactsPaths , withArtifactsPath , true , excludeOutput )
164168 . ToString ( ) ;
165169
166- internal static string GetBuildCommand ( ArtifactsPaths artifactsPaths , BuildPartition buildPartition , string ? extraArguments = null , string ? binLogSuffix = null , bool excludeOutput = false )
170+ internal static string GetBuildCommand ( ArtifactsPaths artifactsPaths , BuildPartition buildPartition ,
171+ bool withArtifactsPath , string ? extraArguments = null , string ? binLogSuffix = null , bool excludeOutput = false )
167172 => new StringBuilder ( )
168173 . AppendArgument ( $ "build -c { buildPartition . BuildConfiguration } ") // we don't need to specify TFM, our auto-generated project contains always single one
169174 . AppendArgument ( GetCustomMsBuildArguments ( buildPartition . RepresentativeBenchmarkCase , buildPartition . Resolver ) )
170175 . AppendArgument ( extraArguments )
171176 . AppendArgument ( GetMandatoryMsBuildSettings ( buildPartition . BuildConfiguration ) )
172177 . AppendArgument ( string . IsNullOrEmpty ( artifactsPaths . PackagesDirectoryName ) ? string . Empty : $ "/p:NuGetPackageRoot=\" { artifactsPaths . PackagesDirectoryName } \" ")
173178 . AppendArgument ( GetMsBuildBinLogArgument ( buildPartition , binLogSuffix ) )
174- . MaybeAppendOutputPaths ( artifactsPaths , excludeOutput : excludeOutput )
179+ . MaybeAppendOutputPaths ( artifactsPaths , withArtifactsPath , excludeOutput : excludeOutput )
175180 . ToString ( ) ;
176181
177- internal static string GetPublishCommand ( ArtifactsPaths artifactsPaths , BuildPartition buildPartition , string ? extraArguments = null , string ? binLogSuffix = null )
182+ internal static string GetPublishCommand ( ArtifactsPaths artifactsPaths , BuildPartition buildPartition ,
183+ bool withArtifactsPath , string ? extraArguments = null , string ? binLogSuffix = null )
178184 => new StringBuilder ( )
179185 . AppendArgument ( $ "publish -c { buildPartition . BuildConfiguration } ") // we don't need to specify TFM, our auto-generated project contains always single one
180186 . AppendArgument ( GetCustomMsBuildArguments ( buildPartition . RepresentativeBenchmarkCase , buildPartition . Resolver ) )
181187 . AppendArgument ( extraArguments )
182188 . AppendArgument ( GetMandatoryMsBuildSettings ( buildPartition . BuildConfiguration ) )
183189 . AppendArgument ( string . IsNullOrEmpty ( artifactsPaths . PackagesDirectoryName ) ? string . Empty : $ "/p:NuGetPackageRoot=\" { artifactsPaths . PackagesDirectoryName } \" ")
184190 . AppendArgument ( GetMsBuildBinLogArgument ( buildPartition , binLogSuffix ) )
185- . MaybeAppendOutputPaths ( artifactsPaths )
191+ . MaybeAppendOutputPaths ( artifactsPaths , withArtifactsPath )
186192 . ToString ( ) ;
187193
188194 private static string GetMsBuildBinLogArgument ( BuildPartition buildPartition , string suffix )
@@ -257,7 +263,7 @@ internal static class DotNetCliCommandExtensions
257263 // We force the project to output binaries to a new directory.
258264 // Specifying --output and --no-dependencies breaks the build (because the previous build was not done using the custom output path),
259265 // so we don't include it if we're building no-deps (only supported for integration tests).
260- internal static StringBuilder MaybeAppendOutputPaths ( this StringBuilder stringBuilder , ArtifactsPaths artifactsPaths , bool isRestore = false , bool excludeOutput = false )
266+ internal static StringBuilder MaybeAppendOutputPaths ( this StringBuilder stringBuilder , ArtifactsPaths artifactsPaths , bool withArtifactsPath , bool isRestore = false , bool excludeOutput = false )
261267 => excludeOutput
262268 ? stringBuilder
263269 : stringBuilder
@@ -266,6 +272,8 @@ internal static StringBuilder MaybeAppendOutputPaths(this StringBuilder stringBu
266272 . AppendArgument ( $ "/p:OutDir=\" { artifactsPaths . BinariesDirectoryPath } { Path . AltDirectorySeparatorChar } \" ")
267273 // OutputPath is legacy, per-project version of OutDir. We set both just in case. https://github.com/dotnet/msbuild/issues/87
268274 . AppendArgument ( $ "/p:OutputPath=\" { artifactsPaths . BinariesDirectoryPath } { Path . AltDirectorySeparatorChar } \" ")
269- . AppendArgument ( isRestore ? string . Empty : $ "--output \" { artifactsPaths . BinariesDirectoryPath } { Path . AltDirectorySeparatorChar } \" ") ;
275+ . AppendArgument ( isRestore ? string . Empty : $ "--output \" { artifactsPaths . BinariesDirectoryPath } { Path . AltDirectorySeparatorChar } \" ")
276+ // We set ArtifactsPath to support parallel builds (requires dotnet sdk 8+). #2425
277+ . AppendArgument ( ! withArtifactsPath ? string . Empty : $ "/p:ArtifactsPath=\" { artifactsPaths . BuildArtifactsDirectoryPath } { Path . AltDirectorySeparatorChar } \" ") ;
270278 }
271279}
0 commit comments