Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Xamarin.Android.Build.Tasks] Deploy changes to transitive reference …
…assembly dependencies (dotnet#4887) Fixes: https://developercommunity.visualstudio.com/content/problem/1086457/index.html Context: 8f2ae24 Context: https://dev.azure.com/devdiv/DevDiv/_workitems/edit/938468 If a Xamarin.Android app referenced a .NET Standard library that had `$(ProduceReferenceAssembly)`=`true`, and that library in turn referenced a second .NET Standard library, then changes to the second library would not be deployed during incremental deployments in Visual Studio unless the app project also directly referenced the second library. For additional context, note that as discussed in internal work item 938468, if a .NET Framework console application references a .NET Standard library that has `$(ProduceReferenceAssembly)`=`true`, then changes to the library are similarly missing in the running console app after incremental builds in Visual Studio. Although the problem in Xamarin.Android apps was similar to the .NET Framework behavior, an important difference was that Xamarin.Android apps did reflect changes correctly for libraries referenced directly by the app. Only transitive references caused trouble in Xamarin.Android. The reason direct references worked was that Visual Studio always ran Xamarin.Android's `Install` target on each incremental deployment, and the `<ResolveAssemblies/>` task in that target correctly located the up-to-date assemblies for direct references. For example, for the included build test, the `<ResolveAssemblies/>` task resolved the `Library1` reference to: C:\Source\xamarin-android\bin\TestDebug\temp\TransitiveDependencyProduceReferenceAssembly\Library1\bin\Debug\netstandard2.0\Library1.dll In contrast, the `<ResolveAssemblies/>` task resolved the `Library2` reference to: C:\Source\xamarin-android\bin\TestDebug\temp\TransitiveDependencyProduceReferenceAssembly\App\bin\Debug\Library2.dll This was problematic because that copy of the library was left over from the previous deployment. In a sense, this was a circular reference: The input for the current deployment was the output from the previous deployment. To fix this behavior, add the `@(ReferenceDependencyPaths)` items that are found by the `<ResolveAssemblyReference/>` task to the `@(FilteredAssemblies)` input. For the included build test, this means the following additional item is now included in `@(FilteredAssemblies)`: C:\Source\xamarin-android\bin\TestDebug\temp\TransitiveDependencyProduceReferenceAssembly\Library1\bin\Debug\netstandard2.0\Library2.dll This path is then treated as a top-level reference in `<ResolveAssemblies/>`, so the task no longer needs to try to resolve it from elsewhere. In theory, another way to fix the problem could be to change how `<ResolveAssemblies/>` resolves transitive dependencies, but `<ResolveAssemblies/>` is only used in the legacy build targets, so adding more sophistication now would have limited value. Other changes: * The `BuildWithResolveAssembliesFailure` test using `packages.config` gets a slightly different error message due to the head project knowing about `Microsoft.Azure.EventHubs`. I think the new behavior is OK. * `@(FilteredAssemblies)` can now have duplicates, so we need to use `->Distinct()`. Note that MSBuild preserves ordering: https://github.com/microsoft/msbuild/blob/9c2d922959e80ba72fefb7addec21ede227639c3/src/Build/Evaluation/Expander.cs#L2484-L2513 Co-authored-by: Jonathan Peppers <jonathan.peppers@gmail.com> Co-authored-by: Jonathan Peppers <jonathan.peppers@gmail.com>
- Loading branch information