Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable including references in autogenerated csproject #1197

Open
billwert opened this issue Jul 11, 2019 · 7 comments · May be fixed by #2508
Open

Enable including references in autogenerated csproject #1197

billwert opened this issue Jul 11, 2019 · 7 comments · May be fixed by #2508
Assignees
Milestone

Comments

@billwert
Copy link
Member

Today, if a benchmark needs a reference to a Nuget package it goes into the original project (microbenchmarks.csproj, say) and then does not need to be in the auto generated csproj.

I’d like to enable us to remove the requirement that we run .NET Framework tests on VMs / machines that have Visual Studio installed: dotnet/performance#627. The new Microsoft.NetFramework.ReferenceAssemblies package is precisely the answer.

But it fails because the generated project doesn’t include the package reference I added:

[2019/07/11 19:29:39][INFO] $ dotnet run --project C:\dotnetbuild\work\274ec05f-7f6a-45af-b6aa-aa3f40fa2e5d\Payload\src\benchmarks\micro\MicroBenchmarks.csproj --configuration Release --framework net461 --no-restore --no-build -- --anyCategories coreclr corefx --iterationCount 1 --warmupCount 0 --invocationCount 1 --unrollFactor 1 --strategy ColdStart --stopOnFirstError true --partition-count 5 --partition-index 0 --packages C:\dotnetbuild\work\274ec05f-7f6a-45af-b6aa-aa3f40fa2e5d\Payload\artifacts\packages --runtimes net461
[2019/07/11 19:29:42][INFO] // Validating benchmarks:
[2019/07/11 19:29:48][INFO] // ***** BenchmarkRunner: Start   *****
[2019/07/11 19:29:48][INFO] // ***** Found 437 benchmark(s) in total *****
[2019/07/11 19:29:48][INFO] // ***** Building 1 exe(s) in Parallel: Start   *****
[2019/07/11 19:29:50][INFO] // start dotnet restore --packages "C:\dotnetbuild\work\274ec05f-7f6a-45af-b6aa-aa3f40fa2e5d\Payload\artifacts\packages"  /p:UseSharedCompilation=false /p:BuildInParallel=false /m:1 in C:\dotnetbuild\work\274ec05f-7f6a-45af-b6aa-aa3f40fa2e5d\Payload\artifacts\bin\MicroBenchmarks\Release\net461\2397be0f-2eba-4afc-b8e3-34ec43808e6d
[2019/07/11 19:29:52][INFO] // command took 2.7s and exited with 0
[2019/07/11 19:29:52][INFO] // start dotnet build -c Release  --no-restore /p:UseSharedCompilation=false /p:BuildInParallel=false /m:1 in C:\dotnetbuild\work\274ec05f-7f6a-45af-b6aa-aa3f40fa2e5d\Payload\artifacts\bin\MicroBenchmarks\Release\net461\2397be0f-2eba-4afc-b8e3-34ec43808e6d
[2019/07/11 19:29:54][INFO] // command took 1.26s and exited with 1
[2019/07/11 19:29:54][INFO] // start dotnet build -c Release  --no-restore --no-dependencies /p:UseSharedCompilation=false /p:BuildInParallel=false /m:1 in C:\dotnetbuild\work\274ec05f-7f6a-45af-b6aa-aa3f40fa2e5d\Payload\artifacts\bin\MicroBenchmarks\Release\net461\2397be0f-2eba-4afc-b8e3-34ec43808e6d
[2019/07/11 19:29:55][INFO] // command took 1.24s and exited with 1
[2019/07/11 19:29:55][INFO] // ***** Done, took 00:00:06 (6.63 sec)   *****
[2019/07/11 19:29:55][INFO] // Found 1 benchmarks:
[2019/07/11 19:29:55][INFO] //   Burgers.Burgers_0: Job-NTJWUA(Runtime=Clr, Toolchain=net461, InvocationCount=1, IterationCount=1, IterationTime=250.0000 ms, MaxIterationCount=20, MinIterationCount=15, RunStrategy=ColdStart, UnrollFactor=1, WarmupCount=0)
[2019/07/11 19:29:55][INFO] 
[2019/07/11 19:29:55][INFO] // Build Error: Standard output:
[2019/07/11 19:29:55][INFO] 
[2019/07/11 19:29:55][INFO]  Standard error:
[2019/07/11 19:29:55][INFO]  Time Elapsed 00:00:00.78
[2019/07/11 19:29:55][INFO]     1 Error(s)
[2019/07/11 19:29:55][INFO]     0 Warning(s)
[2019/07/11 19:29:55][INFO] C:\dotnetbuild\work\274ec05f-7f6a-45af-b6aa-aa3f40fa2e5d\Payload\tools\dotnet\x64\sdk\2.1.701\Microsoft.Common.CurrentVersion.targets(1175,5): error MSB3644: The reference assemblies for framework ".NETFramework,Version=v4.6.1" were not found. To resolve this, install the SDK or Targeting Pack for this framework version or retarget your application to a version of the framework for which you have the SDK or Targeting Pack installed. Note that assemblies will be resolved from the Global Assembly Cache (GAC) and will be used in place of reference assemblies. Therefore your assembly may not be correctly targeted for the framework you intend. [C:\dotnetbuild\work\274ec05f-7f6a-45af-b6aa-aa3f40fa2e5d\Payload\artifacts\bin\MicroBenchmarks\Release\net461\2397be0f-2eba-4afc-b8e3-34ec43808e6d\BenchmarkDotNet.Autogenerated.csproj]
[2019/07/11 19:29:55][INFO] Build FAILED.
[2019/07/11 19:29:55][INFO] C:\dotnetbuild\work\274ec05f-7f6a-45af-b6aa-aa3f40fa2e5d\Payload\tools\dotnet\x64\sdk\2.1.701\Microsoft.Common.CurrentVersion.targets(1175,5): error MSB3644: The reference assemblies for framework ".NETFramework,Version=v4.6.1" were not found. To resolve this, install the SDK or Targeting Pack for this framework version or retarget your application to a version of the framework for which you have the SDK or Targeting Pack installed. Note that assemblies will be resolved from the Global Assembly Cache (GAC) and will be used in place of reference assemblies. Therefore your assembly may not be correctly targeted for the framework you intend. [C:\dotnetbuild\work\274ec05f-7f6a-45af-b6aa-aa3f40fa2e5d\Payload\artifacts\bin\MicroBenchmarks\Release\net461\2397be0f-2eba-4afc-b8e3-34ec43808e6d\BenchmarkDotNet.Autogenerated.csproj

Interestingly, on my machine the second build (which includes --no-dependencies) works on my machine, probably because it’s using some ambient state at that point.

I see that csproj.txt doesn’t have a parameter for this, so we need some feature to plumb this through.

@billwert
Copy link
Member Author

I thought I could work around this by emitting a Directory.Build.props, but y'all thought of that :)

<ImportDirectoryBuildProps>false</ImportDirectoryBuildProps>
<ImportDirectoryBuildTargets>false</ImportDirectoryBuildTargets>

I definitely understand why this is there, and think it's a good idea. It just prevented the work around I had hoped would be cheap of ensuring that there's a Directory.Build.props in the correct place. As msbuild will stop looking, I can feel confident this is going to have the behavior I wanted. Alas.

@adamsitnik
Copy link
Member

This issue is very similar to #1023 :

  • a project with benchmark A has a reference to package B
  • BenchmarkDotNet generates a new project C that references 'A'
  • the reference to package B is non transitive and BDN fails to build the auto-generated project because it lacks the reference

@ViktorHofer @ericstj @eerhardt would it be possible to make Microsoft.NetFramework.ReferenceAssemblies package transitive? or somehow tell MSBuild to reference in C everything that A references? to solve things like #1023 as well?

@adamsitnik
Copy link
Member

@billwert if I won't be able to find any clean solution the only idea I currently have it to introduce a concept of BenchmarkDotNet.props files that would be always included by the auto-generated project files.

@eerhardt
Copy link
Member

The reason the reference to B isn't included in C is because the reference has PrivateAssets=All on it:

https://github.com/dotnet/performance/pull/627/files#diff-931d1b8d9e5f2892d7f8e001da3bf159R25.

This means that this reference is "private" to A and shouldn't be made transitive.

Possible fixes:

  1. Remove PrivateAssets=All on the reference in the benchmark.csproj (A).
    • I am not sure why marking it as PrivateAssets=All in a benchmark project would be necessary. You don't really expect other projects referencing benchmark projects.
  2. BDN could potentially scan the benchmark .csproj for PrivateAssets=All and copy them to the generated project C.

@adamsitnik
Copy link
Member

@eerhardt thank you!

Remove PrivateAssets=All on the reference in the benchmark.csproj

@billwert could you please give it a try?

@adamsitnik
Copy link
Member

Remove PrivateAssets=All on the reference in the benchmark.csproj

FWIW this does not solve the problem (tested myself)

@kirsan31
Copy link

kirsan31 commented Jul 3, 2022

I've come here from https://stackoverflow.com/questions/58990324/how-to-benchmark-two-different-versions-of-the-same-non-nuget-library-in-benchma
Have the same issue. I need to benchmark some changes in WinForms. For this I manually reference my newly build assembles:

<Project Sdk="Microsoft.NET.Sdk">
	<PropertyGroup>
		<OutputType>Exe</OutputType>
		<TargetFramework>net6.0-windows</TargetFramework>
		<UseWindowsForms>true</UseWindowsForms>
		<ImplicitUsings>enable</ImplicitUsings>
		<Nullable>enable</Nullable>
	</PropertyGroup>

	<ItemGroup>
		<Reference Include="d:\save\projects\winforms\artifacts\bin\System.Windows.Forms\Release\net6.0\System.Windows.Forms.dll" />
		<Reference Include="d:\save\projects\winforms\artifacts\bin\System.Windows.Forms.Primitives\Release\net6.0\System.Windows.Forms.Primitives.dll" />
	</ItemGroup>

	<ItemGroup>
		<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
	</ItemGroup>
</Project>

but System.Windows.Forms.dll and System.Windows.Forms.Primitives.dll simply not copied into autogenerated folder - benchmark uses default assemblies :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants