Skip to content

Enable trim/AOT analyzers for Microsoft.Build and clean up annotations - #14064

Merged
JeremyKuhne merged 4 commits into
dotnet:mainfrom
JeremyKuhne:aot-enable-build
Jul 8, 2026
Merged

JeremyKuhne merged 4 commits into
dotnet:mainfrom
JeremyKuhne:aot-enable-build

Conversation

@JeremyKuhne

@JeremyKuhne JeremyKuhne commented Jun 13, 2026

Copy link
Copy Markdown
Member

Summary

Makes the Microsoft.Build evaluation object model trim- and Native-AOT-capable so an AOT-compiled host (the dotnet CLI) can evaluate and build projects in-process, and fail observably wherever a path genuinely requires run-time reflection (loading a task, SDK resolver, logger, or build check discovered by name) so the host can fall back to a JIT MSBuild - never a silent no-op and never a crash deep in the engine.

The work is evaluation-first: evaluation is kept fully trim/AOT-clean today, and execution becomes possible through closed-world host registration (registered SDK resolvers and task classes) while open-world reflective paths fail observably. The build is clean on both net10.0 and net472 (0 IL warnings, 0 warnings, 0 errors).

Change breakdown

About half the diff is documentation; validation and engine code are each roughly a quarter. The engine change is intentionally small and surgical - overwhelmingly trim/AOT annotations and feature-switch gating rather than behavior changes to the JIT path.

Category Files Added Deleted
Documentation 15 4,653 0
Validation (AOT harness + unit tests) 22 2,158 21
Engine code 69 1,990 355
Localization (.xlf/.resx for 4 new diagnostics) 14 344 0
Other (.gitignore) 1 3 0
Total 121 9,148 376

The actual engine code change is ~2,000 lines across 69 files; the remaining ~7,000 lines are documentation, the validation harness/tests, and auto-generated localization.

New public API surface

Three reflection-free, closed-world registration entry points let a host hand MSBuild the types it needs up front so the trimmer preserves them:

  • Microsoft.Build.Framework.SdkResolver.Register(SdkResolver) - contribute a pre-constructed SDK resolver instead of MSBuild discovering and Assembly.LoadFrom-ing one by reflection.
  • Microsoft.Build.Utilities.Task.RegisterTask<T>() (plus a RegisterTask(string, Func<ITask>) overload) - register a task class so the engine constructs, binds, and runs it with reflective task execution disabled.
  • Microsoft.Build.Utilities.TaskItem.RegisterTaskParameterValueType<T>() and RegisterTaskParameterItemType<T>() - resolve <UsingTask> / <ParameterGroup> parameter types without a by-name Type.GetType.

Four new diagnostics report unsupported reflective paths under trimming/AOT:

  • MSB4282 - an SDK requires a dynamically-loaded SDK resolver (unsupported in a trimmed/AOT host).
  • MSB4283 - a task requires reflective loading/execution (unsupported in a trimmed/AOT host).
  • MSB4284 - a custom BuildCheck requires reflective plugin loading (unsupported in a trimmed/AOT host).
  • MSB4285 - a logger named by its assembly/class requires reflective loading (unsupported in a trimmed/AOT host).

API-review callout: besides the additive registration APIs above, there is a deliberate public trim-metadata change - the public ITaskFactory / ITaskFactory2 / ITaskFactory3 Initialize and CreateTask members now carry [RequiresUnreferencedCode], and ITaskFactory.TaskType carries [DynamicallyAccessedMembers(PublicProperties)]. There is no managed signature change, but a host reaching task creation through the interface now sees an honest IL2026, and a third-party ITaskFactory that enables trim analysis gets IL2046 until it adds the matching attribute.

AOT validation

A new Native AOT validation harness (src/aot-validation/) publishes a fully AOT-compiled image and runs it end-to-end. It validates that AOT works for both evaluating and building the basic library (dotnet new classlib) and executable (dotnet new console) project templates:

  • Evaluate - DotnetNew_Classlib_EvaluatesAsLibraryProject, DotnetNew_Console_EvaluatesAsExecutableProject: evaluate the stock templates through the object model under AOT.
  • Build - DotnetNew_Classlib_BuildUnderAot_RunsRegisteredTasksThenFailsObservably, DotnetNew_Console_BuildUnderAot_RunsRegisteredTasksThenFailsObservably: build the templates in-process under AOT, confirming registered/intrinsic tasks run and that an unsupported reflective task fails observably (MSB4283) rather than crashing.

Additional harness coverage exercised against the published AOT image: object-model evaluation, property-function reachability, and each of the three registration APIs (SDK resolver, task class, task-parameter type).

Design criterion: fail observably, never silently

A trimmed/AOT path that cannot run surfaces a reported error (or a host-readable property) so the host can branch and fall back; it never silently drops a project's expressed intent and never crashes in the engine. [UnconditionalSuppressMessage] is used only for provable false positives; accurate warnings are gated behind feature switches (with observable failure) or carry honest [RequiresUnreferencedCode] to a public boundary.

Design notes, the strategy catalog, and living suppression/annotation trackers are in documentation/aot/; the host-registration API proposals are in documentation/specs/.

Copilot AI review requested due to automatic review settings June 13, 2026 00:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enables IL trim/AOT analysis for Microsoft.Build (via IsAotCompatible on net8.0+) and resolves the resulting IL warnings primarily by propagating [RequiresUnreferencedCode] through reflection-heavy/extensibility call chains, adding targeted suppressions at message-pump/delegate boundaries, and tightening DynamicallyAccessedMembers annotations.

Changes:

  • Enable trim/AOT analyzers for src/Build/Microsoft.Build.csproj (net8.0+ only) and eliminate IL warnings across net10.0 + net472.
  • Propagate [RequiresUnreferencedCode] across task loading, SDK resolution, logging, project cache, evaluation/graph, build-request engine, and BuildCheck acquisition.
  • Apply a small set of AOT-friendly refactors (notably ParallelWorkSet, task-parameter array creation, and logger registration) to avoid analyzer-triggering patterns.

Reviewed changes

Copilot reviewed 64 out of 64 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/Build/Microsoft.Build.csproj Enables IsAotCompatible for net8.0+ to run trim/AOT analyzers.
src/Tasks/XamlTaskFactory/XamlTaskFactory.cs Adds DynamicallyAccessedMembers annotation to TaskType.
src/Tasks/RoslynCodeTaskFactory/RoslynCodeTaskFactory.cs Isolates trim-unsafe reflection behind RUC helpers; adjusts suppressions.
src/Tasks/CodeTaskFactory.cs Annotates TaskType with DynamicallyAccessedMembers; updates stub branch.
src/Shared/TypeLoader.cs Marks runtime assembly/type loading paths as RUC.
src/Shared/TaskParameter.cs AOT-friendly array creation for primitive arrays during translation.
src/Shared/TaskLoader.cs Adds suppression on type-filter delegate used during reflective discovery.
src/Shared/TaskEngineAssemblyResolver.cs Adds suppression on assembly-resolve handlers.
src/Framework/ReflectableTaskPropertyInfo.cs Reworks property lookup to avoid trim-unfriendly APIs; narrows DAM.
src/Framework/Loader/LoadedType.cs Expands DAM requirements to include public parameterless ctor.
src/Framework/ITaskFactory.cs Adds DAM annotation to ITaskFactory.TaskType.
src/Build/Utilities/NuGetFrameworkWrapper.cs Marks runtime load/reflection over NuGet.Frameworks as RUC.
src/Build/ObjectModelRemoting/DefinitionObjectsLinks/ProjectLink.cs Marks remote evaluation/build helper APIs as RUC.
src/Build/Logging/LoggerDescription.cs Marks reflective logger creation as RUC; adds delegate suppressions.
src/Build/Instance/TaskRegistry.cs Marks reflective task factory loading/parameter reflection as RUC; adds suppressions for unrecognized reflection patterns.
src/Build/Instance/TaskFactories/AssemblyTaskFactory.cs Marks assembly task factory type-loading paths as RUC; annotates TaskType.
src/Build/Instance/ProjectInstance.cs Marks project instance constructors/build/evaluation-heavy entrypoints as RUC.
src/Build/Graph/ProjectGraph.cs Marks project graph construction/evaluation entrypoints as RUC.
src/Build/Graph/ParallelWorkSet.cs Replaces Lazy<TResult> with custom lazy work item to avoid IL2091.
src/Build/Graph/GraphBuildSubmission.cs Marks cache-plugin initialization paths as RUC.
src/Build/Evaluation/IntrinsicFunctions.cs Suppresses trim warning around Lazy factory calling RUC code.
src/Build/Evaluation/Expander.cs Adds DAM annotations and suppressions around property-function reflection paths.
src/Build/Evaluation/Evaluator.cs Marks evaluation/import expansion paths as RUC.
src/Build/Definition/ProjectCollection.cs Adds RUC propagation and boundary suppressions around logger registration and project loading.
src/Build/Definition/Project.cs Marks public project construction/evaluation/build entrypoints as RUC.
src/Build/Construction/Solution/SolutionProjectGenerator.cs Marks solution evaluation/generation paths as RUC.
src/Build/BuildCheck/Infrastructure/NullBuildCheckManager.cs Marks custom BuildCheck acquisition as RUC.
src/Build/BuildCheck/Infrastructure/IBuildCheckManager.cs Adds RUC to custom BuildCheck acquisition contract.
src/Build/BuildCheck/Infrastructure/BuildCheckManagerProvider.cs Marks custom check materialization/acquisition paths as RUC; adds suppression boundary.
src/Build/BuildCheck/Infrastructure/BuildCheckBuildEventHandler.cs Adds suppression boundary on build-event handler invoking acquisition.
src/Build/BuildCheck/Acquisition/IBuildCheckAcquisitionModule.cs Marks acquisition interface as RUC.
src/Build/BuildCheck/Acquisition/BuildCheckAcquisitionModule.cs Marks acquisition implementation as RUC.
src/Build/BackEnd/TaskExecutionHost/TaskExecutionHost.cs Adds RUC propagation and AOT-friendly array creation for task parameters.
src/Build/BackEnd/Shared/BuildRequestConfiguration.cs Marks project load/eval into configuration as RUC.
src/Build/BackEnd/Node/OutOfProcNode.cs Adds message-pump suppression boundary; propagates RUC into request handling.
src/Build/BackEnd/Node/InProcNode.cs Adds message-pump suppression boundary; propagates RUC into request handling.
src/Build/BackEnd/Components/SdkResolution/SdkResolverService.cs Marks SDK resolution (runtime resolver load/reflection) as RUC.
src/Build/BackEnd/Components/SdkResolution/SdkResolverLoader.cs Marks SDK resolver discovery/loading/reflection as RUC.
src/Build/BackEnd/Components/SdkResolution/OutOfProcNodeSdkResolverService.cs Propagates RUC to out-of-proc resolver service.
src/Build/BackEnd/Components/SdkResolution/MainNodeSdkResolverService.cs Adds suppression boundary in packet handler; propagates RUC to ResolveSdk.
src/Build/BackEnd/Components/SdkResolution/ISdkResolverService.cs Adds RUC to SDK resolver service contract.
src/Build/BackEnd/Components/SdkResolution/HostedSdkResolverServiceBase.cs Adds RUC to hosted resolver service base contract.
src/Build/BackEnd/Components/SdkResolution/CachingSdkResolverService.cs Propagates RUC to caching wrapper.
src/Build/BackEnd/Components/SdkResolution/CachingSdkResolverLoader.cs Propagates RUC to caching loader overrides.
src/Build/BackEnd/Components/RequestBuilder/TaskHost.cs Adds suppression boundary for public task-callback contract; propagates RUC into internal build entrypoints.
src/Build/BackEnd/Components/RequestBuilder/TaskBuilder.cs Propagates RUC to task execution pipeline methods.
src/Build/BackEnd/Components/RequestBuilder/TargetEntry.cs Propagates RUC to target execution pipeline methods.
src/Build/BackEnd/Components/RequestBuilder/TargetBuilder.cs Propagates RUC to target build/callback methods.
src/Build/BackEnd/Components/RequestBuilder/RequestBuilder.cs Propagates RUC through request builder thread/pump paths.
src/Build/BackEnd/Components/RequestBuilder/ITaskBuilder.cs Adds RUC to task-builder contract.
src/Build/BackEnd/Components/RequestBuilder/ITargetBuilderCallback.cs Adds RUC to target-builder callback contract.
src/Build/BackEnd/Components/RequestBuilder/ITargetBuilder.cs Adds RUC to target-builder contract.
src/Build/BackEnd/Components/RequestBuilder/IRequestBuilderCallback.cs Adds RUC to request-builder callback contract.
src/Build/BackEnd/Components/RequestBuilder/IRequestBuilder.cs Adds RUC to request-builder contract.
src/Build/BackEnd/Components/RequestBuilder/IntrinsicTasks/MSBuild.cs Adds suppression boundary for intrinsic-task reflective execution wall.
src/Build/BackEnd/Components/RequestBuilder/IntrinsicTasks/IntrinsicTaskFactory.cs Adds DAM annotations to intrinsic task factory TaskType.
src/Build/BackEnd/Components/ProjectCache/ProjectCacheService.cs Marks plugin loading/reflection/materialization as RUC; adds DAM for ctor activation.
src/Build/BackEnd/Components/Logging/LoggingService.cs Removes reflection for in-box forwarding logger; factors core registration helper; adds RUC to reflective entrypoints.
src/Build/BackEnd/Components/Logging/ILoggingService.cs Adds RUC to distributed logger registration / node logger init contracts.
src/Build/BackEnd/Components/Logging/BuildErrorTelemetryTracker.cs Replaces enum-values reflection with constant-length array sizing.
src/Build/BackEnd/Components/BuildRequestEngine/IBuildRequestEngine.cs Adds RUC to engine contract entrypoints.
src/Build/BackEnd/Components/BuildRequestEngine/BuildRequestEngine.cs Propagates RUC into engine implementation; adds suppression boundaries for event handlers.
src/Build/BackEnd/BuildManager/BuildSubmission.cs Propagates RUC through submission execution entrypoints.
src/Build/BackEnd/BuildManager/BuildManager.cs Propagates RUC through build lifecycle and packet processing entrypoints; adds message-pump suppression boundary.

Comment thread src/Build/Graph/ParallelWorkSet.cs Outdated
Comment thread src/Framework/ReflectableTaskPropertyInfo.cs
Comment thread src/Build/BackEnd/TaskExecutionHost/TaskExecutionHost.cs
Comment thread src/Build/BackEnd/Components/Logging/BuildErrorTelemetryTracker.cs Outdated
Comment thread src/Framework/ITaskFactory.cs

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Design Before Implementation — ISSUE
SEVERITY: MAJOR
FILE: src/Build/BackEnd/Components/Logging/BuildErrorTelemetryTracker.cs
LINES: 39 (the _errorCounts initializer)
SCENARIO: A developer adds a new ErrorCategory value after Other — e.g., ErrorCategory.Security at ordinal 16. (int)ErrorCategory.Other + 1 remains 16 (array indices 0–15). TrackError calls Interlocked.Increment(ref _errorCounts[(int)ErrorCategory.Security]) which dereferences _errorCounts[16]IndexOutOfRangeException at runtime. There is nothing in the code that enforces the "Other is always last" invariant, so this is a silent time bomb for the next contributor who extends the enum.
FINDING: The replacement of Enum.GetValues(typeof(ErrorCategory)).Length with (int)ErrorCategory.Other + 1 avoids the reflection/trimming warning but introduces a fragile positional assumption that is not machine-checkable. The original code was self-maintaining; the new code is not.
RECOMMENDATION: Use the trim-safe generic overload Enum.GetValues<ErrorCategory>().Length (available since .NET 5, annotated only with [RequiresDynamicCode], not [RequiresUnreferencedCode], so it does not trigger IL2026). Add a #if NET guard for the .NET Framework build path (Enum.GetValues(typeof(ErrorCategory)).Length). Alternatively, add a sentinel Count member at the end of the enum and use new int[(int)ErrorCategory.Count] — that is the classic pattern to make array sizing both AOT-safe and self-maintaining.


All other evaluated dimensions are clean:

  • WorkItem class (ParallelWorkSet.cs): The explicit comment correctly explains why Lazy<T> is unsuitable (its [DynamicallyAccessedMembers] annotation on T propagates to ParallelWorkSet<TKey, TResult> and produces IL2091). The documented single-writer / happens-before model makes the lock-free Value getter sound. LGTM.
  • RegisterDistributedLoggerCore extraction (LoggingService.cs): Both call sites hold _lockObject before entering Core, so all shared mutable state is properly guarded. The extraction cleanly separates the reflection-free fast path (RegisterLogger with a pre-instantiated CentralForwardingLogger) from the reflection path. LGTM.
  • ReflectableTaskPropertyInfo.cs manual loop: The change from GetProperty(..., BindingFlags.IgnoreCase) (which required NonPublicProperties in the DAM annotation) to an explicit loop over GetProperties(PublicProperties) with OrdinalIgnoreCase is the correct trim-safe replacement. Using LINQ FirstOrDefault would be semantically equivalent but would allocate an enumerator; the manual loop is preferred on a property-lookup hot path. LGTM.
  • Array.CreateInstanceFromArrayType (TaskParameter.cs, TaskExecutionHost.cs): Switching the switch arms to concrete array types (typeof(char[]) etc.) and using Array.CreateInstanceFromArrayType is exactly the right API for AOT-safe typed-array construction, with a correct #if NET fallback for .NET Framework. LGTM.

Warning

Firewall blocked 2 domains

The following domains were blocked by the firewall during workflow execution:

  • dnceng.pkgs.visualstudio.com
  • pkgs.dev.azure.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "dnceng.pkgs.visualstudio.com"
    - "pkgs.dev.azure.com"

See Network Configuration for more information.

Generated by Expert Code Review (on open) for issue #14064 · 5.7K AIC · ⌖ 12.4 AIC · ⊞ 30.1K ambient context

Comment thread src/Build/BackEnd/Components/Logging/BuildErrorTelemetryTracker.cs Outdated
@JeremyKuhne
JeremyKuhne marked this pull request as draft June 14, 2026 23:18
JeremyKuhne added a commit that referenced this pull request Jun 25, 2026
…14079)

## Summary

Splits the **functional / method-body changes** out of the broader
trim-enablement work (#14064) so they can be reviewed independently of
the annotation churn. This PR contains **no**
`[RequiresUnreferencedCode]`/`[DynamicallyAccessedMembers]` propagation
cascade and does **not** flip on the trim/AOT analyzers — those remain
in #14064.

### Property-function evaluation (made trim-compatible by construction)
- `Function<T>._receiverType` (and the `Function` ctor `receiverType`
parameter) are annotated with `[DynamicallyAccessedMembers(All)]` as a
single chokepoint, with proof-based suppressions on the
`InvokeMember`/`GetMethods`/`GetConstructor` sites.
- The curated receiver-type allowlist (`AvailableStaticMethods`) is
preserved with `[DynamicDependency]`, constrained to the members
property functions actually use (public ctors/methods/properties/fields;
non-public methods for `IntrinsicFunctions`).
- The runtime assembly-probing path
(`MSBUILDENABLEALLPROPERTYFUNCTIONS=1`) is gated behind the
`EnableAllPropertyFunctions` trimmer feature switch so the trimmer
removes it; the env var stays honored at run time. net472 polyfills
added for `FeatureSwitchDefinition`/`DynamicDependency`.

### Functional changes making reflection AOT/trim-friendly (no behavior
change)
- **TaskParameter / TaskExecutionHost**: construct typed arrays via
`Array.CreateInstanceFromArrayType` instead of
`Array.CreateInstance(elementType)`.
- **ParallelWorkSet**: a custom `WorkItem` replaces `Lazy<TResult>`
(avoids the DAM requirement `Lazy<T>` places on `TResult`).
- **BuildErrorTelemetryTracker**: size the count array from a `Count`
sentinel instead of `Enum.GetValues(...)`.
- **LoggingService**: instantiate the built-in `CentralForwardingLogger`
directly instead of via reflection.
- **ReflectableTaskPropertyInfo**: resolve the property via
`GetProperties()` enumeration (also avoids `AmbiguousMatchException` on
shadowed properties).

## Validation
- `Microsoft.Build` compiles for **net10.0** (`-p:IsTrimmable=true`) and
**net472**.
- Targeted unit tests pass: `ParallelWorkSet`,
`TaskExecutionHost_Tests`, `LoggingService_Tests`, `TaskParameter`.
@JeremyKuhne
JeremyKuhne marked this pull request as ready for review June 28, 2026 19:38
@JeremyKuhne
JeremyKuhne requested review from a team as code owners June 28, 2026 19:38
@JeremyKuhne
JeremyKuhne requested a review from Copilot June 28, 2026 19:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 120 out of 121 changed files in this pull request and generated 1 comment.

Comment thread src/Build/BackEnd/Components/Logging/LoggingService.cs Outdated
@JeremyKuhne
JeremyKuhne force-pushed the aot-enable-build branch 4 times, most recently from b138d25 to b0dce1c Compare June 29, 2026 19:41
Comment thread src/Tasks/BuiltInTasks.cs
Makes the MSBuild evaluation object model trim- and Native-AOT-capable so an AOT-compiled host (the dotnet CLI) can evaluate and build in-process, and fail observably where reflective loading is required so the host can fall back to a JIT MSBuild.

Code: trim/AOT annotations, feature switches, and closed-world host-registration APIs (SdkResolver.Register, Task.RegisterTask, TaskItem task-parameter-type registration); new diagnostics MSB4282/MSB4283 for unsupported reflective paths.

Validation: a Native AOT harness that publishes and runs an AOT image, evaluating and building the classlib (library) and console (executable) templates.

Documentation: design/strategy notes, living suppression and annotation trackers, per-area deep dives, and the host-registration API specs.
Add ReadAllBytes/GetCreationTimeUtc/GetLastWriteTimeUtc to the read-only File property-function allowlist; the -mt tests for those methods now rely on the allowlist instead of the escape hatch.

Route every EnableAllPropertyFunctions hatch test through the AppContext feature switch for deterministic, order-independent behavior, and keep a single env-var test that reflectively clears the switch (AppContext has no public unset state) to vet that MSBUILDENABLEALLPROPERTYFUNCTIONS still flows.

Null-guard the BuildProject finally so a rejected overlapping build cannot NRE.
…ontext value

When the .NET SDK hosts MSBuild in a trimmed / Native AOT process the BCL 'where am I' APIs point at the muxer / install root, not the versioned SDK directory that contains MSBuild. Following dotnet/sdk#55110, read the SDK-published 'Microsoft.DotNet.Sdk.Root' AppContext value (new DotNetSdkPaths helper) as an early step in BuildEnvironmentHelper resolution, before falling back to process/assembly discovery.
The rebase onto upstream/main integrated the typed TaskItem<T> / ITaskItem<T> task-parameter feature into Microsoft.Build, which this branch compiles with the trim/AOT analyzers enabled. Fix the merge-resolved using block (drop a duplicate System.Diagnostics and an unused System.Globalization) and guard CreateTaskItemOfT's MakeGenericType + expression Compile() behind RuntimeFeature.IsDynamicCodeSupported so it fails observably under trimming / Native AOT (clearing IL3050). Tracked as follow-up item 7.
@JeremyKuhne

Copy link
Copy Markdown
Member Author

Windows Core failure — investigation

TL;DR: The Windows Core failure is an unrelated flaky Coordinator IPC test, not a regression from this PR. Recommend re-running the leg.

What failed

  • Build 1495736 reported Windows Core red with 1 error / 0 warnings.
  • The compile itself succeeded (0 Warning(s), 0 Error(s)). The single error is a process-level test failure: MSBuild.Coordinator.UnitTests.exe [net472|x86] crashed/hung (the Tests tab shows 0 clean test failures — the runner died rather than reporting an assertion).
  • Every other assembly passed, including Microsoft.Build.Engine.UnitTests on both net472 and net10.0.

Why it's unrelated to this PR

  • MSBuild.Coordinator / MSBuild.Coordinator.UnitTests is entirely upstream code — none of it is touched by this branch (git log main..HEAD -- src/MSBuild.Coordinator* is empty), and the suite references none of the files changed here (BuildEnvironmentHelper, DotNetSdkPaths, TaskExecutionHost, etc.).
  • This PR's changes are no-ops on net472 (the failing config): the new RuntimeFeature.IsDynamicCodeSupported / IL3050 guard is #if NET, and BuildEnvironmentHelper.TryFromSdkRoot reads AppContext.GetData("Microsoft.DotNet.Sdk.Root"), which is unset on net472 / SDK 10.0.300 and returns null.
  • Linux Core and macOS Core passed because the Coordinator component is net472-only and doesn't run there.

Why it's flaky

Recommendation

Re-run the Windows Core leg — no code change is warranted for this PR. If the Coordinator suite keeps flaking it may warrant an additional quarantine entry, but that's separate from this change.

@JeremyKuhne

Copy link
Copy Markdown
Member Author

@ViktorHofer I've updated for merge conflicts and the AppContext SDK root that the SDK pushes.

@ViktorHofer

Copy link
Copy Markdown
Member

How should we maintain that list of BuildInTasks? I assume we don't want to register ALL msbuild inbox tasks? https://github.com/dotnet/msbuild/blob/main/src/Tasks/Microsoft.Common.tasks

@ViktorHofer

Copy link
Copy Markdown
Member

/review

WarperSan pushed a commit to WarperSan/ThunderPipe that referenced this pull request Sep 17, 2026
Updated
[Microsoft.Build.Utilities.Core](https://github.com/dotnet/msbuild) from
18.9.6 to 18.10.1.

<details>
<summary>Release notes</summary>

_Sourced from [Microsoft.Build.Utilities.Core's
releases](https://github.com/dotnet/msbuild/releases)._

## 18.10.1

## What's Changed
* [vs16.11] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13103
* [vs17.12] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13796
* [vs17.8] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13902
* [vs17.11] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13903
* [vs17.12] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13909
* [vs17.12] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13986
* Add vs18.9 to merge-flow config; retire vs18.3 by @​JanProvaznik in
dotnet/msbuild#14214
* Bump labeler-cache-retention to use issue-labeler v2.1.0 by
@​jeffhandley in dotnet/msbuild#14171
* Bump main to 18.10.0 after vs18.9 snap by @​JanProvaznik in
dotnet/msbuild#14216
* Improve release skill: Phase 2 DARC rules, VMR backflow, deterministic
baseline by @​JanProvaznik in
dotnet/msbuild#14220
* Determinize release: hardcode OptProf baseline + Phase 3.2 baseline
resolver by @​JanProvaznik in
dotnet/msbuild#14222
* Serialize BuildRequestConfiguration.RequestedTargets to fix solution
metaproject MSB4057 in parallel builds by @​ViktorHofer in
dotnet/msbuild#14223
* [main] Update dependencies from nuget/nuget.client by
@​dotnet-maestro[bot] in dotnet/msbuild#14203
* Core support for AbsolutePath/FileInfo/DirectoryInfo and ITaskItem<T>
as task parameters by @​baronfel in
dotnet/msbuild#13971
* [main] Update dependencies from dotnet/roslyn by @​dotnet-maestro[bot]
in dotnet/msbuild#14206
* Fix existence cache kind poisoning by @​AlesProkop in
dotnet/msbuild#14249
* [main] Source code updates from dotnet/dotnet by @​dotnet-maestro[bot]
in dotnet/msbuild#14226
* Don't disable the MSBuild server for /mt builds when node reuse is off
by @​AR-May in dotnet/msbuild#14248
* Enhance expert reviewer guidelines with additional checks. by @​AR-May
in dotnet/msbuild#14255
* [main] Source code updates from dotnet/dotnet by @​dotnet-maestro[bot]
in dotnet/msbuild#14253
* [main] Update dependencies from dotnet/roslyn by @​dotnet-maestro[bot]
in dotnet/msbuild#14268
* [main] Update dependencies from nuget/nuget.client by
@​dotnet-maestro[bot] in dotnet/msbuild#14267
* Bump github/gh-aw-actions/setup from 0.81.6 to 0.82.2 by
@​dependabot[bot] in dotnet/msbuild#14266
* Avoid boxing the struct enumerator in
PropertyDictionary<T>.GetEnumerator() by @​nareshjo in
dotnet/msbuild#14272
* Refresh copy marker when implementation output changes by @​AlesProkop
in dotnet/msbuild#14231
* Send task-host build process environment as delta by @​OvesN in
dotnet/msbuild#14126
* Add regression coverage for metadata newline preservation by
@​VolPlita in dotnet/msbuild#14261
* Fix EmbedInBinlog items with relative paths from child projects by
@​huulinhnguyen-dev in dotnet/msbuild#13990
* Stop requiring VersionPrefix updates in servicing - insert prerelease
versions to VS by @​ViktorHofer in
dotnet/msbuild#14277
* Fix WriteLinesToFile rewriting unchanged file when custom encoding is
used by @​huulinhnguyen-dev in
dotnet/msbuild#14146
* Enable trim/AOT analyzers for Microsoft.Build and clean up annotations
by @​JeremyKuhne in dotnet/msbuild#14064
* [automated] Merge branch 'vs18.9' => 'main' by @​github-actions[bot]
in dotnet/msbuild#14291
* Fix MicroBuild plugin feed URL to use allowed pkgs.dev.azure.com
format by @​AlesProkop in dotnet/msbuild#14295
* Pass ExcludeRestorePackageImports during restore to avoid redundant
evaluations by @​ViktorHofer with @​Copilot in
dotnet/msbuild#14274
* [vs18.7] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13988
* Adopt Clever Test Selection (CTS) as parallel, non-blocking PR
pipeline by @​jankratochvilcz in
dotnet/msbuild#14212
* Harden exceptions when connecting to server by @​JanProvaznik in
dotnet/msbuild#14292
* Update MicrosoftBuildVersion in analyzer template by
@​github-actions[bot] in dotnet/msbuild#13886
* Fix MSBuild Server client dropping build result under WaitAny race
(#​14172) by @​JanProvaznik in
dotnet/msbuild#14251
* Partially revert #​13660: remove NuGet RestoreTask transient TaskHost
workaround by @​JanProvaznik in
dotnet/msbuild#14297
* Disable daily AI credits guardrail for Expert Code Review workflow by
@​JanProvaznik with @​Copilot in
dotnet/msbuild#14314
* Localized file check-in by OneLocBuild Task: Build definition ID 9434:
Build ID 14614733 by @​dotnet-bot in
dotnet/msbuild#14246
* Add opt-in partial (stop-after-pass) project evaluation by
@​ViktorHofer in dotnet/msbuild#14290
* Use partial evaluation for -getProperty/-getItem without a target by
@​ViktorHofer in dotnet/msbuild#14296
* [main] Source code updates from dotnet/dotnet by @​dotnet-maestro[bot]
in dotnet/msbuild#14324
* [main] Update dependencies from dotnet/roslyn by @​dotnet-maestro[bot]
in dotnet/msbuild#14333
* [main] Update dependencies from nuget/nuget.client by
@​dotnet-maestro[bot] in dotnet/msbuild#14330
* Bump github/gh-aw-actions/setup from 0.82.2 to 0.82.8 by
@​dependabot[bot] in dotnet/msbuild#14328
* Restrict partial evaluation to ProjectInstance by @​ViktorHofer in
dotnet/msbuild#14340
 ... (truncated)

Commits viewable in [compare
view](dotnet/msbuild@v18.9.6...v18.10.1).
</details>

[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=Microsoft.Build.Utilities.Core&package-manager=nuget&previous-version=18.9.6&new-version=18.10.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This was referenced Sep 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants