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
[Xamarin.Android.Build.Tasks] minimal Reference Assemblies support #2474
[Xamarin.Android.Build.Tasks] minimal Reference Assemblies support #2474
Conversation
to be rebuilt *less often*. | ||
|
||
[msbuild_refassemblies]: https://github.com/dotnet/roslyn/blob/master/docs/features/refout.md | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The above section was the relevant good stuff from here, written by @jonpryor : https://github.com/xamarin/xamarin-android/wiki/Build-Performance-Ideas#embrace-reference-assemblies
Should this also set |
Hmm, that project would be good, but I don’t think anything would test an incremental build on it... I think it might actually make more sense to convert the Xamarin.Forms integration project to use NetStandard instead of a shared project. Then enable it there. @radekdoulik would that be ok with you? Would that hurt our plots? |
f053ff8
to
72f065e
Compare
Well looks like calling
I'm not sure why, it seemed to work for me locally? |
3e04390
to
89558df
Compare
12b3310
to
c382404
Compare
Windows is green:
This is fixed in #2480 |
c382404
to
ad7d1c8
Compare
Suggested Squash-and-merge commit message: [Xamarin.Android.Build.Tasks] Start Reference Assemblies support (#2474)
|
This is the beginning of our support for MSBuild/Roslyn "Reference Assemblies". Adding the following to a `csproj` file: <ProduceReferenceAssembly>True</ProduceReferenceAssembly> Causes a `bin\Debug\ref\MyLibrary.dll` to exist alongside `bin\Debug\MyLibrary.dll`. Two item groups, `@(ReferenceCopyLocalPaths)` and `@(ReferencePath)` will have new `%(ReferenceAssembly)` metadata: bin\Debug\MyLibrary.dll ReferenceAssembly = C:\full\path\to\bin\Debug\ref\MyLibrary.dll If an assembly does *not* include a reference assembly, it will still maintain `%(ReferenceAssembly)` metadata pointing to itself: bin\Debug\OtherLibrary.dll ReferenceAssembly = C:\full\path\to\bin\Debug\OtherLibrary.dll In some cases this metadata might not be there, such as using a path as input to `ResolveAssemblies` (`$(OutDir)$(TargetFileName)`), so our `ResolveAssemblies` MSBuild task should produce the value if it does not exist. ~~ Changes ~~ The biggest change here is to rework `ResolveAssemblies` so that it preserves item metadata. The metadata was getting lost in various ways: - Use of `%(ReferencePath.Identity)` instead of `@(ReferencePath)`. - Any new `TaskItem` instances created should use the ctor taking in an existing `ITaskItem`. This preserves the metadata from the original item. We also needed to make some changes to support `%(ReferenceAssembly)`: - New `TaskItem` objects created by a file path should set `%(ReferenceAssembly)`. - We should check if `%(ReferenceAssembly)` is missing, and set it where appropriate. I looked into reworking `_GenerateJavaStubs` so it can be skipped when a reference assembly didn't change. I merely changed a single input: `@(_ResolvedAssemblies)` to `@(_ResolvedAssemblies->'%(ReferenceAssembly)')`. Unfortunately, this would break! A developer could write this completely valid C# class: internal class Example : Java.Lang.Object { } However, since we have preserved item metadata, we can now use `%(ReferenceAssembly)` throughout the build. We can take advantage of it in the future. I added some documentation about what I found out with MSBuild "Reference Assembly" support, in general. I also added a unit test verifying which targets skip when `$(ProduceReferenceAssembly)` is set in a library project. I also reworked our Xamarin.Forms integration project so that it is netstandard instead of a shared project. This will help us test `$(ProduceReference)` assembly, and also has a much simpler project file! Other changes: - I let VS Windows fixup the `Xamarin.Android-Tests.sln file`. It looks like there were a few mismatched guids and other things. - We did not have XamlC enabled: `[assembly: XamlCompilation (XamlCompilationOptions.Compile)]` this will greatly improve startup times! - We will need to call `/t:Restore` on the Xamarin.Forms netstandard project now.
ad7d1c8
to
61ccb05
Compare
in which version is this included? In VS2017 15.9, I always get the message that the ref dll is modified even if I only change one value in XAML file.
|
You need VS 2019 16.0 for XAML files to work properly in reference assemblies. I reported a bug for Roslyn around EmbeddedResource, they fixed and shipped in 16.0 GA. |
@jonathanpeppers thanks for the information. This explains it. |
ok, works in 16.3 Preview1
please update your blogpost "Optimize your Xamarin.Android Builds" and add this information. |
That blog post is assuming you are using 16.2 stable. Did that not work for you? |
@jonathanpeppers this was not clear. I hate VS2019 because of the broken UI and so I'll stay at VS2017 and will likely skip 2019 at all. I only have a VM with Preview channel to test if UI designers repaired the broken UI mess. |
I added a sentence to the intro paragraph, thanks: https://devblogs.microsoft.com/xamarin/optimize-xamarin-android-builds/ |
This is the beginning of our support for MSBuild/Roslyn "Reference
Assemblies".
Adding the following to a
csproj
file:Causes a
bin\Debug\ref\MyLibrary.dll
to exist alongsidebin\Debug\MyLibrary.dll
.Two item groups,
@(ReferenceCopyLocalPaths)
and@(ReferencePath)
will have new
%(ReferenceAssembly)
metadata:If an assembly does not include a reference assembly, it will still
maintain
%(ReferenceAssembly)
metadata pointing to itself:In some cases this metadata might not be there, such as using a path
as input to
ResolveAssemblies
($(OutDir)$(TargetFileName)
), so ourResolveAssemblies
MSBuild task should produce the value if it doesnot exist.
Changes
The biggest change here is to rework
ResolveAssemblies
so that itpreserves item metadata. The metadata was getting lost in various
ways:
%(ReferencePath.Identity)
instead of@(ReferencePath)
.TaskItem
instances created should use the ctor taking inan existing
ITaskItem
. This preserves the metadata from theoriginal item.
We also needed to make some changes to support
%(ReferenceAssembly)
:TaskItem
objects created by a file path should set%(ReferenceAssembly)
.%(ReferenceAssembly)
is missing, and set itwhere appropriate.
I looked into reworking
_GenerateJavaStubs
so it can be skippedwhen a reference assembly didn't change.
I merely changed a single input:
@(_ResolvedAssemblies)
to@(_ResolvedAssemblies->'%(ReferenceAssembly)')
.Unfortunately, this would break! A developer could write this
completely valid C# class:
However, since we have preserved item metadata, we can now use
%(ReferenceAssembly)
throughout the build. We can take advantage ofit in the future.
I added some documentation about what I found out with MSBuild
"Reference Assembly" support, in general. I also added a unit test
verifying which targets skip when
$(ProduceReferenceAssembly)
is setin a library project.
I also reworked our Xamarin.Forms integration project so that it is
netstandard instead of a shared project.
This will help us test
$(ProduceReference)
assembly, and also has amuch simpler project file!
Other changes:
Xamarin.Android-Tests.sln file
. Itlooks like there were a few mismatched guids and other things.
[assembly: XamlCompilation (XamlCompilationOptions.Compile)]
this will greatly improve startup times!
/t:Restore
on the Xamarin.Forms netstandardproject now.