IncrementalClean can delete a needed file from output
- Dominant language
- C#
- Stars
- 5.5k
- Forks
- 1.5k
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 141
Description
> _Edit--Current state summary: better behavior is now available in 18.0+/10.0.100+ by setting the property `TrackFileWritesShareableOutsideOfProjectDirectory` to `true`. This issue remains open to consider making that the default._
-------------
If a project has its output directory outside the project directory, and it copies a dependent file to output for more than one reason (say, via None as well as via RAR), and you remove one reason, building the project deletes the file from output, even though the file still needs to be there. Building the project again brings the file back.
1. unzip this into `C:\temp\IncrementalClean` or any other empty directory: [IncrementalClean.zip](https://github.com/dotnet/msbuild/files/14149551/IncrementalClean.zip)
2. `msbuild /r`
3. ensure `C:\temp\IncrementalClean\bin\B\A.dll` exists (hereafter it's just called "The File")
4. open `C:\temp\IncrementalClean\B\B.csproj` and comment out line 13 (to ensure the None item is not added), save file
5. `msbuild`
6. observe that The File was deleted by the `IncrementalBuild` target
7. `msbuild`
8. The File is back again
This is because `@(ReferenceCopyLocalPaths)` is not added to `@(FileWrites)`, it is added to `@(FileWritesShareable)`. If a .dll is copied to output because it was in `@(ReferenceCopyLocalPaths)`, it is not added to `B.csproj.FileListAbsolute.txt`.
In our repro, The File was added to FileListAbsolute.txt during step 2, because the `None` items added it to `@(FileWrites)`. In step 5, the file is still copied by `_CopyFilesMarkedCopyLocal`, but since it's no longer in `@(FileWrites)`, but it is in `@(_CleanPriorFileWrites)`, `IncrementalClean` deletes it. In step 8 The File is copied back by `_CopyFilesMarkedCopyLocal`, but since it's neither in current nor prior file writes, IncrementalClean doesn't delete it.
Basically I'd say it's an unfortunate confluence of the output directory being outside the project cone and `FileWritesShareable` not being added to `FileWrites`. I think this is the problematic logic that assumes the bin folder is inside the project directory:
https://github.com/dotnet/msbuild/blob/07fd5d51f25134ea3ab3620c66f6501a74df2921/src/Tasks/Microsoft.Common.CurrentVersion.targets#L5615-L5627
I doubt there's a safe fix that we can do to fix the bug but I'm filing it just the same.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.