-
Notifications
You must be signed in to change notification settings - Fork 564
Description
Steps to Reproduce
- Create a Forms solution with an Android head + netstandard lib: example here
- Run
git clean -dxfto just ensure a clean work tree - Run
msbuild .\HelloForms\HelloForms.Android\HelloForms.Android.csproj /t:SetupDependenciesForDesigner /p:DesignTimeBuild=true /p:AndroidUseManagedDesignTimeResourceGenerator=false /restore /bl
Doing this, you hit an error in <ResolveAssemblies/>:
"HelloForms.Android.csproj" (SetupDependenciesForDesigner target) (1:7) ->
(_ResolveAssemblies target) ->
Xamarin.Android.Common.targets(1898,2): error : Exception while loading assemblies: System.InvalidOperationException: Failed to load assembly HelloForms\bin\Debug\netstandard2.0\HelloForms.dll
Xamarin.Android.Common.targets(1898,2): error : at Xamarin.Android.Tasks.ResolveAssemblies.Execute(DirectoryAssemblyResolver resolver)
Expected Behavior
The designer could load more quickly if the SetupDependenciesForDesigner could complete successfully even if not all <ProjectReference/> projects are built.
Actual Behavior
If any assemblies are missing, the <ResolveAssemblies/> MSBuild task will fail.
Thoughts on Implementation
If I make this change to Xamarin.Android.Common.targets, then ResolveAssemblies works in this scenario:
--- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
+++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
@@ -1917,9 +1917,9 @@ because xbuild doesn't support framework reference assemblies.
<FilteredAssemblies Include="$(OutDir)$(TargetFileName)"
Condition="Exists ('$(OutDir)$(TargetFileName)')" />
<FilteredAssemblies Include="@(ReferenceCopyLocalPaths)"
- Condition="'%(ReferenceCopyLocalPaths.ResolvedFrom)' != 'ImplicitlyExpandDesignTimeFacades' And '%(ReferenceCopyLocalPaths.Extension)' == '.dll' And '%(ReferenceCopyLocalPaths.RelativeDir)' == '' "/>
+ Condition="'%(ReferenceCopyLocalPaths.ResolvedFrom)' != 'ImplicitlyExpandDesignTimeFacades' And '%(ReferenceCopyLocalPaths.Extension)' == '.dll' And '%(ReferenceCopyLocalPaths.RelativeDir)' == '' And ('$(DesignTimeBuild)' != 'True' Or Exists('%(ReferenceCopyLocalPaths.Identity)')) "/>
<FilteredAssemblies Include="@(ReferencePath)"
- Condition="'%(ReferencePath.ResolvedFrom)' != 'ImplicitlyExpandDesignTimeFacades' "/>
+ Condition="'%(ReferencePath.ResolvedFrom)' != 'ImplicitlyExpandDesignTimeFacades' And ('$(DesignTimeBuild)' != 'True' Or Exists('%(ReferencePath.Identity)'))"/>
</ItemGroup>It seems safer to me to only enable this behavior when $(DesignTimeBuild) is True.
Concerns
It might be possible this change could break future builds after SetupDependenciesForDesigner completes:
- Some
<ProjectReference/>that containsJava.Lang.Objectsubclasses is not built yet. SetupDependenciesForDesignerruns.- The
<ProjectReference/>gets built. _GenerateJavaStubscould get skipped and we have a missing Java stub?
When we implement this, we should include a test with this scenario that makes sure everything works.
The types of tests we should add:
- Xamarin.Forms app with a netstandard library
- An incremental build
- Since the change will mostly be in this repo, we should test calling
UpdateAndroidResourcesdirectly. The designer targets are in a private repo, but I think this will simulate the behavior nicely. - Add a
<ProjectReference/>to the tests we already have in the monodroid private repo.
Log File
Here are logs before/after the proposed change: logs.zip
VS bug #753650