dotnet / msbuild

The Microsoft Build Engine (MSBuild) is the build platform for .NET and Visual Studio.
https://docs.microsoft.com/visualstudio/msbuild/msbuild
MIT License
5.21k stars 1.35k forks source link

[Bug]: Internal MSBuild Error: Targets cannot be reset once set. #9838

Open xtmq opened 7 months ago

xtmq commented 7 months ago

Issue Description

Hello MSBuild Team! As you may know Rider uses MSBuild API to load and build projects. Some time ago we faced a new issue with project loading:

Microsoft.Build.Framework.InternalErrorException: MSB0001: Internal MSBuild Error: Targets cannot be reset once set.
   at Microsoft.Build.Shared.ErrorUtilities.ThrowInternalError(String message, Exception innerException, Object[] args)
   at Microsoft.Build.BackEnd.BuildRequestConfiguration.set_ProjectTargets(HashSet`1 value)
   at Microsoft.Build.BackEnd.BuildRequestConfiguration.SetProjectBasedState(ProjectInstance project)
   at Microsoft.Build.BackEnd.BuildRequestConfiguration.set_Project(Pro[1936226.TestSolution.msbuild-task.zip](1936226.TestSolution.msbuild-task.zip)jectInstance value)
   at Microsoft.Build.Execution.BuildManager.CreateConfiguration(Project project, BuildRequestConfiguration existingConfiguration)
   at Microsoft.Build.BackEnd.ConfigCache.GetMatchingConfiguration(ConfigurationMetadata configMetadata, ConfigCreateCallback callback, Boolean loadProject)
   at Microsoft.Build.Execution.BuildManager.GetProjectInstanceForBuild(Project project)

We get this exception from time to time (but very seldom) when Rider has to load lots of tiny projects on solution opening. Our code looks like this simplified example:

var buildManager = new BuildManager();
var projectCollection = new ProjectCollection();
var context = EvaluationContext.Create(EvaluationContext.SharingPolicy.Shared);

Parallel.ForEach(paths, new ParallelOptions { MaxDegreeOfParallelism = 4}, path => {

var xml = ProjectRootElement.Open(path, projectCollection, preserveFormatting: true);
var project = Project.FromProjectRootElement(xml, new ProjectOptions
        {
          GlobalProperties = ...,
          ProjectCollection = projectCollection,
          LoadSettings = ...,
          EvaluationContext = context 
        });
var projectInstance = buildManager.GetProjectInstanceForBuild(project); // Exception here

});

This starts to happening on Linux in this SDK: dotnet-sdk-8.0.100-linux-x64-c4c95f56 Looks like something was changed inside ProjectInstance creating and not it is not thread-safe anymore?

Steps to Reproduce

We don't have exact steps now. But it is not obvious what was broken in the last SDK we can try to make a repro.

Expected Behavior

no exception

Actual Behavior

exception

Analysis

No response

Versions & Configurations

dotnet-sdk-8.0.100-linux-x64-c4c95f56

AR-May commented 6 months ago

@GangWang01 let's see if we can repro this

GangWang01 commented 6 months ago

I couldn't reproduce with nuget package Microsoft.Build 17.9.5.

@xtmq Can you share the following information for helping to reproduce? Thank you!

xtmq commented 6 months ago

I can not reproduce it also. It fails on our CI/CD server like once per week or once per 200-300 builds. The solution - 300 class library projects with single file inside.

rwx788 commented 4 months ago

Hi! Sorry for the delay, here is the project where this error occurs. Last failures we got were with msbuild from dotnet 8.0.300 Mmg300-20231224.zip

As it's stated above, problem occurs quite rarely, but and is visible from our CI only. Please let us know which additional information we can provide.

xtmq commented 1 month ago

Now we observe the same exception, but from build:

Microsoft.Build.Framework.InternalErrorException: MSB0001: Internal MSBuild Error: Targets cannot be reset once set.
   at Microsoft.Build.Shared.ErrorUtilities.ThrowInternalError(String message, Exception innerException, Object[] args)
   at Microsoft.Build.BackEnd.BuildRequestConfiguration.set_ProjectTargets(HashSet`1 value)
   at Microsoft.Build.BackEnd.BuildRequestConfiguration.SetProjectBasedState(ProjectInstance project)
   at Microsoft.Build.BackEnd.BuildRequestConfiguration.set_Project(ProjectInstance value)
   at Microsoft.Build.Execution.BuildManager.ResolveConfiguration(BuildRequestConfiguration unresolvedConfiguration, BuildRequestConfiguration matchingConfigurationFromCache, Boolean replaceProjectInstance)
   at Microsoft.Build.Execution.BuildManager.ExecuteSubmission(BuildSubmission submission, Boolean allowMainThreadBuild)
GangWang01 commented 1 month ago

@xtmq do you use to Microsoft.Build.Locator to register the instance of .NET SDK.? From the code snippet in the issue description, I couldn't know about it. And what's the version of MSBuild packages as well as .NET SDK?

xtmq commented 1 month ago

I use msbuild from this SDK: dotnet-sdk-8.0.300-linux-x64-04722663, we don't call locator and assume MSBuild knows about it's own SDK

GangWang01 commented 1 month ago

@xtmq To get MSBuild work, besides MSBuild assemblies it also requires importing necessary props and targets files from SDK. Can you provide a minimal project that includes how it references MSBuild assemblies and imports props and targets files from SDK? So that we can try to reproduce the issue.

rwx788 commented 1 month ago

@xtmq To get MSBuild work, besides MSBuild assemblies it also requires importing necessary props and targets files from SDK. Can you provide a minimal project that includes how it references MSBuild assemblies and imports props and targets files from SDK? So that we can try to reproduce the issue.

Hi @GangWang01 ! Thanks for your help with the investigation. It's actually the same project we use in tests which I have pasted above in the issue. There is nothing specific except of having 300 synthetic library projects all of which target net8.0. And problem appears while loading some of them once in a while. Loading is done as per that code snippet above. That should help reproducing the issue. Please, let us know if further details are needed. Cheers!

GangWang01 commented 1 month ago

@rwx788 Thanks for quick response!

To get MSBuild work, besides MSBuild assemblies it also requires importing necessary props and targets files from SDK. Can you provide a minimal project that includes how it references MSBuild assemblies and imports props and targets files from SDK? So that we can try to reproduce the issue.

Here the project is the one that has the code snippet above loading the test projects. It helps to understand if necessary props and targets files from SDK are imported correctly.