-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Fix RecursiveDir metadata loss in multithreaded builds #13142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Fixes loss of %(RecursiveDir) when items cross the TaskHost process boundary during multithreaded builds, preventing directory flattening in scenarios like dotnet pack.
Changes:
- Preserve
RecursiveDirby copying it into custom metadata duringTaskParameterTaskItemconstruction for TaskHost serialization. - Preserve
ProjectItemInstance.TaskItem’s_projectDirectoryacross cloning and serialization. - Ensure
TaskItemFactory.CreateItem(string, string, string)preservesincludeBeforeWildcardExpansionEscaped(needed for correctRecursiveDirsemantics).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/Shared/TaskParameter.cs | Copies RecursiveDir into custom metadata so it survives TaskHost serialization. |
| src/Build/Instance/ProjectItemInstance.cs | Preserves _projectDirectory across clone/serialization; fixes task item creation to keep pre-wildcard include. |
|
Oh wow - I think I got this in the RID-specific tool packaging work and worked around it without understanding what was happening. Really great identification of the problem here! |
675e5d0 to
f1be335
Compare
When items were returned from MSBuild tasks (like the MSBuild task's TargetOutputs) or passed to tasks via output parameters, the %(RecursiveDir) built-in metadata was lost. This caused NuGet pack to flatten directory structures (e.g., build\wix\bundle\bundle.wxs became build\bundle.wxs), resulting in NU5118 errors. Root causes found and fixed: 1. TaskExecutionHost.cs: When creating ProjectItemInstance from task outputs, only IncludeEscaped was passed to the constructor, losing IncludeBeforeWildcardExpansionEscaped which is required for RecursiveDir. Fix: Use the 5-parameter constructor that accepts both values. 2. TaskParameter.cs: TaskParameterTaskItem only copied custom metadata when wrapping ITaskItem for TaskHost serialization, but RecursiveDir is a built-in metadata computed from _includeBeforeWildcardExpansionEscaped. Fix: Explicitly copy RecursiveDir to custom metadata so it survives cross-process serialization. Added ContainsKey check before calling GetMetadataValueEscaped to avoid expensive FileMatcher calls. 3. ProjectItemInstance.cs: Related fixes to preserve _projectDirectory in copy constructor, serialization, and CreateItem methods. The CreateItem method now derives projectDirectory from definingProject. Fixes dotnet#3121
f1be335 to
f17258b
Compare
When using MSBuild's multithreaded mode (-mt / /maxcpucount), the %(RecursiveDir) built-in metadata was lost when items crossed process boundaries to the TaskHost. This caused NuGet pack to flatten directory structures (e.g., build\wix\bundle\bundle.wxs became build\bundle.wxs).
Root cause: TaskParameterTaskItem only copied custom metadata when wrapping ITaskItem for TaskHost serialization. RecursiveDir is a built-in metadata that cannot be derived from just the item spec - it requires the original wildcard pattern (_includeBeforeWildcardExpansionEscaped).
Fix: Explicitly copy RecursiveDir to custom metadata in TaskParameterTaskItem constructor before serialization, so it survives the cross-process boundary.
Also includes related fixes to ProjectItemInstance.cs:
related: #3121
fixes #13140