-
Notifications
You must be signed in to change notification settings - Fork 390
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
Make Build Acceleration support symbolic/hard links #9548
Comments
@Mariachi1231 this line in the log looks suspicious:
The source and destination of that copy are identical. Can you confirm whether that's the case in your logs? I want to rule out the possibility that the log changed when you were redacting private details. |
Hi @drewnoakes, I’ve created a repro with the actual logs. You can check it out here. |
Thanks for the repro. I see the same error when following the steps you've provided. I'm not familiar with using symlinks during build, but my first instinct here is that we should just disable build acceleration when a project appears to be using symlinks. Symlinks seem to be solving the same issue as BA here anyway, namely making it cheap to have the same file in multiple projects. Perhaps there's an API that lets us follow a symlink to its original path, in which case I think the copy would be identified as having the same source/destination. However there's likely overhead in that. I'm inclined to just have VS disable BA when the project uses symlinks. What do you think would be the best way for us to detect this? Is there a single MSBuild property, or would we need to look for all of these:
|
It seems that adding this to your <PropertyGroup>
<UseCommonOutputDirectory>true</UseCommonOutputDirectory>
</PropertyGroup> I'm not sure why. |
If we do sniff for those properties, we may also need to check the hard link equivalents, such as:
|
@drewnoakes , thanks for an investigation!
While both symlinks and BA aim to avoid redundant copying and speed up the build, symlinks are simply a way to avoid non-cheap copying and save disk space. In contrast, BA offers logging and a complex comparison of inputs and outputs to determine whether something actually needs to trigger MSBuild. In my case, the main goal is to avoid triggering MSBuild altogether, but when errors occur during the copy process in BA, MSBuild now invoked, which is unplesant. Once invoked, it can perform many tasks (even without needing to do CoreCompile), such as evaluating target platforms, frameworks, etc., which can take significant time—especially in large solutions with complex What would be ideal is if, during a copy, we could detect that the destination path already contains a symlink. If the symlink points to the same target, we could safely skip the copy. Checking for a symlink does introduce some performance overhead, but in theory, it would only affect users leveraging symlinks, since before checking for the symlink, we could perform a cheaper check to see if the build is using symbolic links at all (based on flags that you already noticed). This would limit the performance impact to only those builds using symlinks, while saving time by avoiding MSBuild executions for such clients.
Yes, but the overhead could theoretically be minimized by checking only if the build is running with Create(Hard/Symbolic)Links flags in the first place.
From what I know, there isn't a single property for this — only this level of granularity. But from the perspective of BA, it doesn't really matter to my mind, If let's say any of these flags is true, we could set a custom property to true in order to do a perf overhead of symlink checks otherwise just do as it's now. Alternatively, as you saying, you could just disable BA entirely (which, of course, isn't the best option for me 😔).
true I'm not sure why. I can imagine why, but unfortunately, I can’t use this in real scenarios where the solution consists of hundreds of projects of different types. These projects are aggregated into a single solution to correctly manage dependencies and leverage the benefits of ProjectReferences during MSBuild and single output in this case of course not an option. And of course as it's mentioned here, VS is not a friend for symlink usages. |
Visual Studio Version
Version 17.11.4
Summary
Is it possible to make FUTDC (Fast Up-to-Date Check) work properly with symbolic links?
In my large project, I’m using MSBuild properties for symbolic links, such as:
CreateSymbolicLinksForCopyFilesToOutputDirectoryIfPossible
CreateSymbolicLinksForCopyAdditionalFilesIfPossible
CreateSymbolicLinksForCopyLocalIfPossible
CreateSymbolicLinksForAdditionalFilesIfPossible
CreateSymbolicLinksForPublishFilesIfPossible
This helps save disk space and avoids unnecessary copying of files.
By default, this doesn't work in Visual Studio, so have a couple of hacks to make it work, like next:
Actual Behavior
When I build the project, it seems that file copying related to the up-to-date check fails, likely due to the symbolic link. Here's an excerpt from the log:
Where
C:\src\MyPrefix.ProjectA\bin\MyPrefix.ProjectADependency.dll
is a symbol link in the project output dir from previous builds.Expected Behavior
It's unclear to me what the ideal expected behavior should be in this case, but it would be great if this error could be avoided and the MSBuild call skipped because in general it can be accelarated to my mind.
Steps To Reproduce
Since the sln is quite complicated I don't provide the exact steps at that time, but if you will say that it makes sense, I can try to provide repo which reproduces behavior.
User Impact
In my case, this issue triggers the build of subsequent projects because of the failure to copy files during the up-to-date check.
MSBuild in past i think worked on a similar problem here
The text was updated successfully, but these errors were encountered: