Context: http://feedback.devdiv.io/600039
Context: 6321934237/Documentation/guides/MSBuildReferenceAssemblies.md
Context: https://github.com/dotnet/roslyn/blob/master/docs/features/refout.md#msbuild
For Xamarin.Android, we have been doing a bit of work to enable a new
MSBuild/Roslyn feature called "reference assemblies". You can opt into
this by setting $(ProduceReferenceAssembly)=true in a netstandard
project.
The benefit being that if the public API doesn't change in the
netstandard library, the head projects don't need to run `CoreCompile`
or `<Csc/>` during an incremental build.
Unfortunately, this seems to have uncovered a problem in the
Xamarin.iOS MSBuild targets. If you do a build with a XAML-only change,
you get:
Target "_CompileToNative" in file "/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets":
Skipping target "_CompileToNative" because all output files are up-to-date with respect to the input files.
Input files: /Users/jonathanpeppers/Projects/HelloForms/HelloForms.iOS/bin/iPhoneSimulator/Debug/HelloForms.iOS.exe
Output files: bin/iPhoneSimulator/Debug/device-builds/iphone11.8-12.2/HelloForms.iOS.app/HelloForms.iOS;bin/iPhoneSimulator/Debug/device-builds/iphone11.8-12.2/mtouch.stamp
Because we are using `$(ProduceReferenceAssembly)` the
`HelloForms.iOS.exe` assembly will have no changes. Only
`HelloForms.dll`, the netstandard project, has changes. We were able
to skip `CoreCompile` in the iOS head project. Faster builds, yeah!
However, we actually need `_CompileToNative` to run, or we won't see
any changes on the device or simulator... It only runs if
`$(TargetPath)` changes.
The fix here is to add new `Inputs`, so `_CompileToNative` runs when
any referenced assemblies change:
<_CompileToNativeInput Include="$(TargetDir)$(TargetFileName);@(ReferencePath);@(MTouchReferencePath)" />
This fixes incremental builds (or changes) for:
* Any `<ProjectReference/>` that has `$(ProduceReferenceAssembly)`
* Any NuGet package that ships a reference assembly alongside its
"regular" assembly
I also moved the `<ItemGroup>`'s, just so the code made sense --
so we have all the important `<ItemGroup>`'s in one place.
I also updated the `XamarinForms` test to verify things are working.
I added a couple helpers to assist in writing MSBuild tests:
* `IsTargetSkipped` to check if a specific MSBuild target ran
* `Logger.Clear` to clear past MSBuild events within a single test