-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Issue Description
Solution wide target specified in Directory.Solution.targets produces the error MSB4057 despite the use of the MSBuild.SkipNonexistentTargets property. It only happens when the solution file captures interproject dependencies.
Steps to Reproduce
Consider the following trivial project layout:
C:\work\msbuild_sln_bug> dir
Directory: C:\work\msbuild_sln_bug
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 11/22/2024 9:01 PM 136 a.csproj
-a--- 11/22/2024 8:57 PM 1432 a.sln
-a--- 11/22/2024 9:01 PM 136 b.csproj
-a--- 11/22/2024 8:58 PM 1587 b.sln
-a--- 11/22/2024 8:54 PM 501 Directory.Solution.targets
C:\work\msbuild_sln_bug>
Where:
a.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
</Project>b.csproj is identical to a.csproj
C:\work\msbuild_sln_bug> fc.exe .\a.csproj .\b.csproj
Comparing files .\a.csproj and .\B.CSPROJ
FC: no differences encountered
C:\work\msbuild_sln_bug>
a.sln
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "a", "a.csproj", "{2DC00580-0BCC-4CD9-A25C-72FE3F093BBB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "b", "b.csproj", "{DCACBC11-AC42-45EC-BD9C-90B776F3424F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2DC00580-0BCC-4CD9-A25C-72FE3F093BBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2DC00580-0BCC-4CD9-A25C-72FE3F093BBB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2DC00580-0BCC-4CD9-A25C-72FE3F093BBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2DC00580-0BCC-4CD9-A25C-72FE3F093BBB}.Release|Any CPU.Build.0 = Release|Any CPU
{DCACBC11-AC42-45EC-BD9C-90B776F3424F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DCACBC11-AC42-45EC-BD9C-90B776F3424F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DCACBC11-AC42-45EC-BD9C-90B776F3424F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DCACBC11-AC42-45EC-BD9C-90B776F3424F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
b.sln
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "a", "a.csproj", "{2DC00580-0BCC-4CD9-A25C-72FE3F093BBB}"
ProjectSection(ProjectDependencies) = postProject
{DCACBC11-AC42-45EC-BD9C-90B776F3424F} = {DCACBC11-AC42-45EC-BD9C-90B776F3424F}
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "b", "b.csproj", "{DCACBC11-AC42-45EC-BD9C-90B776F3424F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2DC00580-0BCC-4CD9-A25C-72FE3F093BBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2DC00580-0BCC-4CD9-A25C-72FE3F093BBB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2DC00580-0BCC-4CD9-A25C-72FE3F093BBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2DC00580-0BCC-4CD9-A25C-72FE3F093BBB}.Release|Any CPU.Build.0 = Release|Any CPU
{DCACBC11-AC42-45EC-BD9C-90B776F3424F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DCACBC11-AC42-45EC-BD9C-90B776F3424F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DCACBC11-AC42-45EC-BD9C-90B776F3424F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DCACBC11-AC42-45EC-BD9C-90B776F3424F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
Directory.Solution.targets
<Project>
<Target Name="xyz">
<MSBuild Targets="xyz"
BuildInParallel="True"
SkipNonexistentTargets="True"
Projects="@(ProjectReference)"
Properties="BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" />
</Target>
</Project>Notice that the b.sln file is a copy of the a.sln, except that one project is made to depend on the other project inside the solution file b.sln:
C:\work\msbuild_sln_bug> fc.exe .\a.sln .\b.sln
Comparing files .\a.sln and .\B.SLN
***** .\a.sln
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "a", "a.csproj", "{2DC00580-0BCC-4CD9-A25C-72FE3F093BBB}"
EndProject
***** .\B.SLN
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "a", "a.csproj", "{2DC00580-0BCC-4CD9-A25C-72FE3F093BBB}"
ProjectSection(ProjectDependencies) = postProject
{DCACBC11-AC42-45EC-BD9C-90B776F3424F} = {DCACBC11-AC42-45EC-BD9C-90B776F3424F}
EndProjectSection
EndProject
*****
C:\work\msbuild_sln_bug>
Now let us build the xyz target through the a.sln solution:
C:\work\msbuild_sln_bug> dotnet build .\a.sln /t:xyz
Determining projects to restore...
Restored C:\work\msbuild_sln_bug\b.csproj (in 111 ms).
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:03.28
Workload updates are available. Run `dotnet workload list` for more information.
C:\work\msbuild_sln_bug>
And now using the solution b.sln:
C:\work\msbuild_sln_bug> dotnet build .\b.sln /t:xyz
Determining projects to restore...
All projects are up-to-date for restore.
C:\work\msbuild_sln_bug\a.csproj : error MSB4057: The target "xyz" does not exist in the project.
Build FAILED.
C:\work\msbuild_sln_bug\a.csproj : error MSB4057: The target "xyz" does not exist in the project.
0 Warning(s)
1 Error(s)
Time Elapsed 00:00:00.89
Workload updates are available. Run `dotnet workload list` for more information.
C:\work\msbuild_sln_bug>
Expected Behavior
Both solutions build the xyz target in exactly the same fashion - no errors on the non existing target xyz.
Actual Behavior
The solution with the interproject dependencies fails.
Analysis
When there are interproject dependencies extra metaproj msbuild files are created in addition to the one corresponding to the solution itself. These extra metaproj files replicate the xyz solution wide target, but omit the SkipNonexistentTargets property found in the original Directory.Solution.targets file.
Versions & Configurations
C:\work\msbuild_sln_bug> msbuild -version
MSBuild version 17.11.9+a69bbaaf5 for .NET Framework
17.11.9.46202
C:\work\msbuild_sln_bug>