diff --git a/ref/Microsoft.Build/net/Microsoft.Build.cs b/ref/Microsoft.Build/net/Microsoft.Build.cs index df63aa205be..532c5d6f37f 100644 --- a/ref/Microsoft.Build/net/Microsoft.Build.cs +++ b/ref/Microsoft.Build/net/Microsoft.Build.cs @@ -772,6 +772,7 @@ public enum ProjectLoadSettings DoNotEvaluateElementsWithFalseCondition = 32, IgnoreInvalidImports = 64, ProfileEvaluation = 128, + FailOnUnresolvedSdk = 256, } public partial class ProjectMetadata : System.IEquatable { @@ -1047,6 +1048,8 @@ public enum BuildRequestDataFlags SkipNonexistentTargets = 16, ProvideSubsetOfStateAfterBuild = 32, IgnoreMissingEmptyAndInvalidImports = 64, + SkipNonexistentNonTopLevelTargets = 128, + FailOnUnresolvedSdk = 256, } public partial class BuildResult { @@ -1566,8 +1569,8 @@ protected GraphBuildOptions(Microsoft.Build.Graph.GraphBuildOptions original) { public virtual bool Equals(Microsoft.Build.Graph.GraphBuildOptions other) { throw null; } public override bool Equals(object obj) { throw null; } public override int GetHashCode() { throw null; } - public static bool operator ==(Microsoft.Build.Graph.GraphBuildOptions r1, Microsoft.Build.Graph.GraphBuildOptions r2) { throw null; } - public static bool operator !=(Microsoft.Build.Graph.GraphBuildOptions r1, Microsoft.Build.Graph.GraphBuildOptions r2) { throw null; } + public static bool operator ==(Microsoft.Build.Graph.GraphBuildOptions left, Microsoft.Build.Graph.GraphBuildOptions right) { throw null; } + public static bool operator !=(Microsoft.Build.Graph.GraphBuildOptions left, Microsoft.Build.Graph.GraphBuildOptions right) { throw null; } protected virtual bool PrintMembers(System.Text.StringBuilder builder) { throw null; } public override string ToString() { throw null; } public virtual Microsoft.Build.Graph.GraphBuildOptions $() { throw null; } diff --git a/ref/Microsoft.Build/netstandard/Microsoft.Build.cs b/ref/Microsoft.Build/netstandard/Microsoft.Build.cs index 2e945e6c024..0d3e03e6172 100644 --- a/ref/Microsoft.Build/netstandard/Microsoft.Build.cs +++ b/ref/Microsoft.Build/netstandard/Microsoft.Build.cs @@ -772,6 +772,7 @@ public enum ProjectLoadSettings DoNotEvaluateElementsWithFalseCondition = 32, IgnoreInvalidImports = 64, ProfileEvaluation = 128, + FailOnUnresolvedSdk = 256, } public partial class ProjectMetadata : System.IEquatable { @@ -1042,6 +1043,8 @@ public enum BuildRequestDataFlags SkipNonexistentTargets = 16, ProvideSubsetOfStateAfterBuild = 32, IgnoreMissingEmptyAndInvalidImports = 64, + SkipNonexistentNonTopLevelTargets = 128, + FailOnUnresolvedSdk = 256, } public partial class BuildResult { @@ -1560,8 +1563,8 @@ protected GraphBuildOptions(Microsoft.Build.Graph.GraphBuildOptions original) { public virtual bool Equals(Microsoft.Build.Graph.GraphBuildOptions other) { throw null; } public override bool Equals(object obj) { throw null; } public override int GetHashCode() { throw null; } - public static bool operator ==(Microsoft.Build.Graph.GraphBuildOptions r1, Microsoft.Build.Graph.GraphBuildOptions r2) { throw null; } - public static bool operator !=(Microsoft.Build.Graph.GraphBuildOptions r1, Microsoft.Build.Graph.GraphBuildOptions r2) { throw null; } + public static bool operator ==(Microsoft.Build.Graph.GraphBuildOptions left, Microsoft.Build.Graph.GraphBuildOptions right) { throw null; } + public static bool operator !=(Microsoft.Build.Graph.GraphBuildOptions left, Microsoft.Build.Graph.GraphBuildOptions right) { throw null; } protected virtual bool PrintMembers(System.Text.StringBuilder builder) { throw null; } public override string ToString() { throw null; } public virtual Microsoft.Build.Graph.GraphBuildOptions $() { throw null; } diff --git a/src/Build/BackEnd/BuildManager/BuildManager.cs b/src/Build/BackEnd/BuildManager/BuildManager.cs index 559d426e357..f5caca9ae84 100644 --- a/src/Build/BackEnd/BuildManager/BuildManager.cs +++ b/src/Build/BackEnd/BuildManager/BuildManager.cs @@ -1702,6 +1702,11 @@ private void ExecuteGraphBuildScheduler(GraphBuildSubmission submission) projectLoadSettings |= ProjectLoadSettings.IgnoreMissingImports | ProjectLoadSettings.IgnoreInvalidImports | ProjectLoadSettings.IgnoreEmptyImports; } + if (submission.BuildRequestData.Flags.HasFlag(BuildRequestDataFlags.FailOnUnresolvedSdk)) + { + projectLoadSettings |= ProjectLoadSettings.FailOnUnresolvedSdk; + } + return new ProjectInstance( path, properties, diff --git a/src/Build/BackEnd/BuildManager/BuildRequestData.cs b/src/Build/BackEnd/BuildManager/BuildRequestData.cs index 4123d7e0922..c189ff6a00e 100644 --- a/src/Build/BackEnd/BuildManager/BuildRequestData.cs +++ b/src/Build/BackEnd/BuildManager/BuildRequestData.cs @@ -75,6 +75,15 @@ public enum BuildRequestDataFlags /// This is especially useful during a restore since some imports might come from packages that haven't been restored yet. /// IgnoreMissingEmptyAndInvalidImports = 1 << 6, + + /// + /// When this flag is present, the top level target(s) in the build request will be skipped if those targets + /// are not defined in the Project to build. This only applies to this build request (if another target calls + /// the "missing target" at any other point this will still result in an error). + /// + SkipNonexistentNonTopLevelTargets = 1 << 7, + + FailOnUnresolvedSdk = 1 << 8, } /// diff --git a/src/Build/BackEnd/Components/RequestBuilder/TargetBuilder.cs b/src/Build/BackEnd/Components/RequestBuilder/TargetBuilder.cs index 79142963436..d220bd94175 100644 --- a/src/Build/BackEnd/Components/RequestBuilder/TargetBuilder.cs +++ b/src/Build/BackEnd/Components/RequestBuilder/TargetBuilder.cs @@ -143,10 +143,12 @@ public async Task BuildTargets(ProjectLoggingContext loggingContext foreach (string targetName in targetNames) { var targetExists = _projectInstance.Targets.TryGetValue(targetName, out ProjectTargetInstance targetInstance); - if (!targetExists && entry.Request.BuildRequestDataFlags.HasFlag(BuildRequestDataFlags.SkipNonexistentTargets)) + if (!targetExists + && entry.Request.BuildRequestDataFlags.HasFlag(BuildRequestDataFlags.SkipNonexistentTargets) + || entry.Request.BuildRequestDataFlags.HasFlag(BuildRequestDataFlags.SkipNonexistentNonTopLevelTargets) && !entry.Request.Targets.Contains(targetName)) { _projectLoggingContext.LogComment(Framework.MessageImportance.Low, - "TargetSkippedWhenSkipNonexistentTargets", targetName); + "TargetSkippedWhenSkipNonexistentTargets", targetName); } else { diff --git a/src/Build/BackEnd/Shared/BuildRequestConfiguration.cs b/src/Build/BackEnd/Shared/BuildRequestConfiguration.cs index 97f9531e074..8398cb68479 100644 --- a/src/Build/BackEnd/Shared/BuildRequestConfiguration.cs +++ b/src/Build/BackEnd/Shared/BuildRequestConfiguration.cs @@ -466,6 +466,11 @@ internal void LoadProjectIntoConfiguration( projectLoadSettings |= ProjectLoadSettings.IgnoreMissingImports | ProjectLoadSettings.IgnoreInvalidImports | ProjectLoadSettings.IgnoreEmptyImports; } + if (buildRequestDataFlags.HasFlag(buildRequestDataFlags & BuildRequestDataFlags.FailOnUnresolvedSdk)) + { + projectLoadSettings |= ProjectLoadSettings.FailOnUnresolvedSdk; + } + return new ProjectInstance( ProjectFullPath, globalProperties, diff --git a/src/Build/Definition/ProjectLoadSettings.cs b/src/Build/Definition/ProjectLoadSettings.cs index 7f1c9ad2d80..16483ed56ad 100644 --- a/src/Build/Definition/ProjectLoadSettings.cs +++ b/src/Build/Definition/ProjectLoadSettings.cs @@ -59,5 +59,7 @@ public enum ProjectLoadSettings /// Whether to profile the evaluation /// ProfileEvaluation = 128, + + FailOnUnresolvedSdk = 256, } } diff --git a/src/Build/Evaluation/Evaluator.cs b/src/Build/Evaluation/Evaluator.cs index f9126e6c61f..fafbd630265 100644 --- a/src/Build/Evaluation/Evaluator.cs +++ b/src/Build/Evaluation/Evaluator.cs @@ -1761,7 +1761,7 @@ static string EvaluateProperty(string value, IElementLocation location, if (!sdkResult.Success) { - if (_loadSettings.HasFlag(ProjectLoadSettings.IgnoreMissingImports)) + if (_loadSettings.HasFlag(ProjectLoadSettings.IgnoreMissingImports) && !_loadSettings.HasFlag(ProjectLoadSettings.FailOnUnresolvedSdk)) { ProjectImportedEventArgs eventArgs = new ProjectImportedEventArgs( importElement.Location.Line, diff --git a/src/MSBuild/XMake.cs b/src/MSBuild/XMake.cs index f6e3bc27f4b..b6ad235ec79 100644 --- a/src/MSBuild/XMake.cs +++ b/src/MSBuild/XMake.cs @@ -1431,7 +1431,7 @@ private static (BuildResultCode result, Exception exception) ExecuteRestore(stri toolsVersion, targetsToBuild: new[] { MSBuildConstants.RestoreTargetName }, hostServices: null, - flags: BuildRequestDataFlags.ClearCachesAfterBuild | BuildRequestDataFlags.SkipNonexistentTargets | BuildRequestDataFlags.IgnoreMissingEmptyAndInvalidImports); + flags: BuildRequestDataFlags.ClearCachesAfterBuild | BuildRequestDataFlags.SkipNonexistentNonTopLevelTargets | BuildRequestDataFlags.IgnoreMissingEmptyAndInvalidImports | BuildRequestDataFlags.FailOnUnresolvedSdk); return ExecuteBuild(buildManager, restoreRequest); }