Skip to content

[spec] MSBuild target changes to support Android Designer #2548

@jonathanpeppers

Description

@jonathanpeppers

Steps to Reproduce

  1. Create a Forms solution with an Android head + netstandard lib: example here
  2. Run git clean -dxf to just ensure a clean work tree
  3. 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:

  1. Some <ProjectReference/> that contains Java.Lang.Object subclasses is not built yet.
  2. SetupDependenciesForDesigner runs.
  3. The <ProjectReference/> gets built.
  4. _GenerateJavaStubs could 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 UpdateAndroidResources directly. 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

Metadata

Metadata

Labels

enhancementProposed change to current functionality.proposalvs-syncFor internal use only; creates a VSTS "mirror" issue.

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions