-
Notifications
You must be signed in to change notification settings - Fork 389
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
Up-to-date check awareness of reference assemblies #2254
Comments
@rainersigwald Basic question: how/where does MSBuild do up-to-date checking on ref assemblies? It looks like when I build a project that outputs a ref assembly and have only changed the implementation, csc will still output a new ref assembly. So the "last write" on the ref assembly will be updated and would normally trigger an "up to date" check failure. But MSBuild correctly does not rebuild a dependent project, so it must look at more than just the timestamp. Can you point me to the logic it uses? |
@panopticoncentral Yes, csc.exe will always write its outputs: obj/a.dll and obj/ref/a.dll. |
Relates to #62 |
Required for dotnet/project-system#2254. Given: ClassLibrary1 -> ClassLibrary2 -> ConsoleApp1 Where ClassLibrary2 references ClassLibrary1 and ConsoleApp1 references only ClassLibrary2. And both ClassLibrary1 and ClassLibrary2 output ref assemblies. So we do a full build, touch the implementation of ClassLibrary1, and then build. - ClassLibrary1 is out of date, so it builds ClassLibrary1.dll. However, since the interface didn't change, ref\ClassLibrary1.dll is not touched. - ClassLibrary2 is out of date because input ClassLibrary1.dll is now newer than output ClassLibrary2.dll. So it builds. However, since all inputs of CoreCompile are up to date (since ref\ClassLibrary1.dll isn't newer than ClassLibrary2.dll), we don't rebuild ClassLibrary2.dll or ref\ClassLibrary2.dll. We just copy the updated implementation of ClassLibrary1, and touch ClassLibrary2.marker. - ConsoleApp1 is out of date because input ClassLibrary2.marker is now newer than output ConsoleApp1.dll. So it builds. However, since all inputs of CoreCompile are up to date (since ref\ClassLibrary2.dll isn't newer than ConsoleApp1.dll), we don't rebuild ConsoleApp1.dll. We just copy the updated implementation of ClassLibrary1. There's no marker for ConsoleApp1. The problem in this situation is that now if you do another build, ConsoleApp1 will fail the up to date check and copy ref\ClassLibrary2.dll again, because ClassLibrary2.marker will always be newer than ConsoleApp1.dll. If ConsoleApp1 had a marker, though, then we would just compare the markers and know it was up to date.
@jcouv What do you need from me to test this? I've done testing on my own, but a doublecheck would be good. |
I'm enlisting to project-systems and I will try to build and set it up locally. I'll let you know how it goes. Thanks |
Running into some problems with
|
Delete the MicroBuild.* packages from your NuGet directory. They aren't able to run side-by-side. They are aware and have zero plans to fix this. :( |
Thanks @davkean When I do that, most VSIXs now seem to build, but I still get a failure on FSharp. I'll try to proceed, hoping that the bits I need have been deployed to RoslynDev.
|
Never seen that before. Do you have the RoslynDev hive open in VS right now? |
No, I have default hive open. |
It worked after re-running. Not sure what happened. |
The VSIX has lots of these races - they are looking into them. |
@panopticoncentral I'm this PR is introducing some regressions, even with ref assemblies turned off. The test project depends on In the attached logs, the compiler (searching for "/out:") is invoked 9 times with regular VS bits, but only 5 times with RoslynDev hive. The compilations for msbuild-log-without-refout-preview.txt |
I will repro in the morning, but could you do Tools | Options | Projects and Solutions | .NET Core and change your logging level to Verbose? Then try building again and in the output window it will give you a rundown of what the up to date checker is thinking. If you could include that, it'd be great. |
I pushed a fix that was causing a problem with the up to date check, and I can't reproduce your problem, can you retry with the logging on? |
So this morning I couldn't repro the problem again (even without the last iteration of your PR). |
Ok, I repro'ed after all and I have diagnostic logs. But this is prior to your latest fix. I will update my local setup and try again. |
I have to run out for a little while (last day of school for the kids), but something strange is going on--your log doesn't show any references at all coming up in the up to date check. I'm going to need to dig further this afternoon to figure out what's going on. |
@jcouv We figured out on Friday that this was an issue with how you were running the project system (you have to run from IDE). Do you have an update on how this works for you? |
@panopticoncentral Thanks for the ping. I lost track. |
A work item tracking adding this for CSPROJ is available at: |
The C# and VB compilers introduced “reference assemblies”, a new compiler output that contains only the public interface of an assembly, and that does not change when private implementation details are changed: dotnet/roslyn#2184. This allows projects to avoid compile time when the output of recompilation would be identical, because no local source files have changed and the interface of referenced assemblies is identical.
This presents new scenarios for the fast up-to-date check, because
Scenarios
Several new scenarios arise in a solution that uses reference assemblies.
For illustrative purposes, consider a solution consisting of
Client.csproj
that depends onLib1.csproj
that depends onLib2.csproj
. In this wayClient
is "downstream" ofLib1
and bothLib1
andClient
are downstream ofLib2
.Lib1
andLib2
; an updated copy ofLib2.dll
is copied to the output folder ofClient
and used at debug time.Lib2.dll
is copied to the output folder ofClient
and used at debug time. The compiler is not run forLib1
orClient
.Proposed design
To account for the transitive-dependency-copying behavior, I propose extending the up-to-date check with an additional set of inputs and outputs.
The MSBuild item that represents the output of a project is annotated with metadata for
ReferenceAssembly
and a new concept, theCopyUpToDateMarker
. This is done in dotnet/msbuild#2039.The
CopyUpToDateMarker
for a project is touched when references are copied to its output folder. This can then indicate that downstream projects need to build in order to copy the references along.The timestamp of references’
CopyUpToDateMarker
s must be compared only to the current project'sCopyUpToDateMarker
, because copying references will not update the primary output of the project.Alternatives considered
UpToDateCheckInput
item to avoid having detailed knowledge of reference assemblies in the project system.ProjectReference
to populate the item in time.FindDependencies=true
toResolveAssemblyReference
within a design-time build.This is the result of extensive offline discussions with @jcouv, @tmeschter, @panopticoncentral, @davkean, and others.
The text was updated successfully, but these errors were encountered: