Conversation
|
@rolfbjarne and @dsplaisted - please take a look. I've made NuGet prefer the global TargetFramework property when set. |
|
Thanks for the review @jonathanpeppers and @rolfbjarne Addressed your feedback. |
|
@rainersigwald Is there a better way to check whether a property is a global property than to do a separate <PropertyGroup>
<_TargetFrameworkBackup>($TargetFramework)</TargetFrameworkBackup>
<TargetFramework>FakeOverriddenValue</TargetFramework>
<TargetFrameworkIsGlobal Condition="'$(TargetFramework)' == '$(TargetFrameworkBackup)'">true</TargetFrameworkIsGlobal>
<TargetFramework>$(_TargetFrameworkBackup)</TargetFramework>
</PropertyGroup> |
There's now (since 16.5) an API that will allow doing it inside a task: dotnet/msbuild#4939. @nkolev92 would that let you do this inside the NuGet tasks themselves?
This does work in simple evaluation, but beware: if you put the same property settings inside a target, it does not work. |
|
That API could work. I think we use it in static graph scenarios already. Right now we only use that to decide which frameworks to run inner builds for. I'd probably have to add an extra task to just get the effective TargetFramework(s). |
| <MSBuild | ||
| BuildInParallel="$(RestoreBuildInParallel)" | ||
| Condition=" '$(TargetFrameworks)' != '' " | ||
| Projects="$(MSBuildThisFileFullPath)" |
There was a problem hiding this comment.
I would put some comments in here that you're "building" NuGet.targets just to detect if a global property is set. More explanation of how this target works would be very helpful.
|
|
||
| // Act | ||
| var additionalArgs = useStaticGraphEvaluation ? "/p:RestoreUseStaticGraphEvaluation=true" : string.Empty; | ||
| var result = _msbuildFixture.RunDotnet(pathContext.SolutionRoot, args: $"restore a.csproj {additionalArgs} /p:TargetFramework=\"net5.0\"", ignoreExitCode: true); |
There was a problem hiding this comment.
The result of this restore will only work for one framework and subsequent builds without a restore would fail right? Is it not possible to just restore a whole project regardless of target framework(s) and just let the build be scoped? We can remove global properties when generating the ProjectSpec items
There was a problem hiding this comment.
Yeah, it'd only restore/build for that specific framework.
When a RID is passed, we simply can't know whether we'd need to include for all or only a specific framework, so we only restore for that framework.
2b04ad9 to
6bf125a
Compare
|
Ready for another look @rolfbjarne @jonathanpeppers @dsplaisted @NuGet/nuget-client |
93ae383 to
8593454
Compare
| IReadOnlyDictionary<string, string> msBuildGlobalProperties = null; | ||
|
|
||
| // MSBuild 16.5 added a new interface, IBuildEngine6, which has a GetGlobalProperties() method. However, we compile against | ||
| // Microsoft.Build.Framework version 4.0 when targeting .NET Framework, so reflection is required since type checking |
There was a problem hiding this comment.
Is there a reason we're building with such an old version of Microsoft.Build.Framework? Does nuget.exe even work without a recent-ish msbuild.exe? Or is it to avoid ilmerging Microsoft.Build.Framework.dll into nuget.exe, since I guess version 4.0 is in the GAC?
| IReadOnlyDictionary<string, string> msBuildGlobalProperties = null; | ||
|
|
||
| // MSBuild 16.5 added a new interface, IBuildEngine6, which has a GetGlobalProperties() method. However, we compile against | ||
| // Microsoft.Build.Framework version 4.0 when targeting .NET Framework, so reflection is required since type checking |
There was a problem hiding this comment.
Is there a reason we're building with such an old version of Microsoft.Build.Framework? Does nuget.exe even work without a recent-ish msbuild.exe? Or is it to avoid ilmerging Microsoft.Build.Framework.dll into nuget.exe, since I guess version 4.0 is in the GAC?
There was a problem hiding this comment.
NuGet.exe uses whichever version of msbuild is available on their machine.
We don't/won't merge msbuild because it is used to discover imports and all that.
There was a problem hiding this comment.
actually, I misunderstood your question.
Not 100% sure if we can update. I can look into it, but we're doing this in a bunch of different places so I just largely followed that logic.
There was a problem hiding this comment.
Yeah, it might be reasonable to rebaseline, since I suspect you don't support running modern nuget.exe against dev11. But I don't think it's urgent.
There was a problem hiding this comment.
you don't support running modern nuget.exe against dev11
NuGet.exe restore help unfortunately lists a lot of msbuild versions.
We don't really explicitly talk about what's supported vs what's not.
It's a ymmv type of thing.
8593454 to
587dd8b
Compare
|
@NuGet/nuget-client Hoping to get some reviews here so I can merge? :) |
zivkan
left a comment
There was a problem hiding this comment.
I'm curious if there's a measurable performance degradation with this change? The PR adds a new target, which calls a C# task. But MSBuild is an interpreted scripting language, so calling targets is a lot more expensive than calling methods in a JITed language, and the task uses reflection.
I hope it's too small to be measurable, but we seem to be concerned about the pdb PR's impact.
It registers as 1ms only. #4587 (comment) Note that this is only called on the commandline and not in VS, so the concerns are lesser. |
jeffkl
left a comment
There was a problem hiding this comment.
There was no CI build for this change so I kicked one off
Bug
Fixes: NuGet/Home#11653
Regression? Last working version:
Description
NuGet/Home#11653 contains details about the scenario at hand, but the gist is that:
does not work because nuget prefers TargetFrameworks over TargetFramework, so it essentially "tries" to do a restore for net6.0-android + ios-arm64 which obviously isn't something that works.
This change allows NuGet to detect the user intent in the scenarios like the above, and only restore for the framework passed on the commandline.
The change boils down to NuGet preferring the
TargetFrameworkwhen it is specified on the commandline, as a global property.While working on this I discovered NuGet/Home#11761, which basically means static graph can't support the equivalent at this point.
Given that this change requires multiple teams to validate it's good enough, I've added a means to disable it in case something does go really wrong while we're attempting that validation.
_DisableNuGetRestoreTargetFrameworksOverride.PR Checklist
PR has a meaningful title
PR has a linked issue.
Described changes
Tests
Documentation