Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
<Compile Include="..\Xamarin.Android.Build.Tasks\Linker\External\Linker\BaseMarkHandler.cs" Link="External\BaseMarkHandler.cs" />
<Compile Include="..\Xamarin.Android.Build.Tasks\Linker\MonoDroid.Tuner\AndroidLinkConfiguration.cs" Link="MonoDroid.Tuner\AndroidLinkConfiguration.cs" />
<Compile Include="..\Xamarin.Android.Build.Tasks\Linker\MonoDroid.Tuner\Extensions.cs" Link="MonoDroid.Tuner\Extensions.cs" />
<Compile Include="..\Xamarin.Android.Build.Tasks\Linker\MonoDroid.Tuner\FixLegacyResourceDesignerStep.cs" Link="MonoDroid.Tuner\FixLegacyResourceDesignerStep.cs" />
<Compile Include="..\Xamarin.Android.Build.Tasks\Linker\MonoDroid.Tuner\LinkDesignerBase.cs" Link="MonoDroid.Tuner\LinkDesignerBase.cs" />

<!--Other .NET for Android / Java.Interop files-->
<Compile Include="..\..\external\Java.Interop\src\Java.Interop.Tools.Cecil\Java.Interop.Tools.Cecil\CustomAttributeProviderRocks.cs" Link="Java.Interop\CustomAttributeProviderRocks.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,7 @@ public virtual void LogMessage (string message)

public virtual void LogError (int code, string message)
{
#if ILLINK
Context.LogMessage (MessageContainer.CreateCustomErrorMessage (message, code, origin: new MessageOrigin ()));
#else // !ILLINK
Context.LogError ($"XA{code}", message);
#endif // !ILLINK
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,11 @@
using Mono.Linker.Steps;

using Mono.Tuner;
#if ILLINK
using Resources = Microsoft.Android.Sdk.ILLink.Properties.Resources;
#else // !ILLINK
using Resources = Xamarin.Android.Tasks.Properties.Resources;
#endif // ILLINK

namespace MonoDroid.Tuner
{
public class FixLegacyResourceDesignerStep : LinkDesignerBase
#if !ILLINK
, Xamarin.Android.Tasks.IAssemblyModifierPipelineStep
#endif // !ILLINK
public class FixLegacyResourceDesignerStep : LinkDesignerBase, Xamarin.Android.Tasks.IAssemblyModifierPipelineStep
{
internal const string DesignerAssemblyName = "_Microsoft.Android.Resource.Designer";
internal const string DesignerAssemblyNamespace = "_Microsoft.Android.Resource.Designer";
Expand All @@ -36,14 +29,6 @@ public class FixLegacyResourceDesignerStep : LinkDesignerBase
Dictionary<string, MethodDefinition> lookup;
Dictionary<string, MethodDefinition> lookupCaseInsensitive;

protected override void EndProcess ()
{
if (designerAssembly != null) {
LogMessage ($" Setting Action on {designerAssembly.Name} to Link.");
Annotations.SetAction (designerAssembly, AssemblyAction.Link);
}
}

protected override void LoadDesigner ()
{
if (designerLoaded)
Expand Down Expand Up @@ -72,7 +57,6 @@ protected override void LoadDesigner ()
}
}

#if !ILLINK
public void ProcessAssembly (AssemblyDefinition assembly, Xamarin.Android.Tasks.StepContext context)
{
// Only run this step on non-main user Android assemblies
Expand All @@ -81,7 +65,6 @@ public void ProcessAssembly (AssemblyDefinition assembly, Xamarin.Android.Tasks.

context.IsAssemblyModified |= ProcessAssemblyDesigner (assembly);
}
#endif // !ILLINK

internal override bool ProcessAssemblyDesigner (AssemblyDefinition assembly)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,27 @@
using Mono.Linker;
using Mono.Linker.Steps;
using System;
using System.Linq;
using Xamarin.Android.Tasks;
using System.Collections.Generic;
using System.Globalization;
using Mono.Cecil.Cil;
using System.Text.RegularExpressions;
using Mono.Collections.Generic;
#if ILLINK
using Microsoft.Android.Sdk.ILLink;
#endif


namespace MonoDroid.Tuner {
public abstract class LinkDesignerBase : BaseStep
{
protected IMetadataResolver Cache => Context;

public
#if !ILLINK
override
#endif
void LogMessage (string message)
public override void LogMessage (string message)
{
Context.LogMessage (message);
}

public
#if !ILLINK
override
#endif
void LogError (int code, string error)
public override void LogError (int code, string error)
{
#if ILLINK
Context.LogMessage (MessageContainer.CreateCustomErrorMessage (error, code, origin: new MessageOrigin ()));
#else // !ILLINK
Context.LogError ($"XA{code}", error);
#endif // !ILLINK
}

public virtual AssemblyDefinition Resolve (AssemblyNameReference name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,18 +226,37 @@ Copyright (C) 2016 Xamarin. All rights reserved.
In additon we MUST set the `PostprocessAssembly` metadata to `true` so that the file
is processed by the ILLink step. If we do not do this then the reference to
`netstandard.dll` is not replaced with `System.Private.CoreLib` and the app crashes.

We use a TrimmerRootDescriptor (not TrimmerRootAssembly) to prevent ILLink from
trimming the designer's resource properties. FixLegacyResourceDesignerStep runs
after ILLink and needs all properties present when rewriting library assemblies.
A descriptor (-x) preserves types without making the assembly an entry point,
which avoids pulling netstandard.dll into the output.
-->
<Target Name="_AddResourceDesignerToPublishFiles"
Condition=" '$(AndroidUseDesignerAssembly)' == 'True' "
AfterTargets="ComputeResolvedFilesToPublishList"
DependsOnTargets="_SetupDesignerProperties">
<PropertyGroup>
<_DesignerLinkerDescriptor>$(IntermediateOutputPath)_Microsoft.Android.Resource.Designer.xml</_DesignerLinkerDescriptor>
</PropertyGroup>
<WriteLinesToFile
File="$(_DesignerLinkerDescriptor)"
Overwrite="true"
Lines="&lt;linker&gt;&lt;assembly fullname=&quot;$(_DesignerAssemblyName)&quot;&gt;&lt;type fullname=&quot;*&quot; preserve=&quot;all&quot; /&gt;&lt;/assembly&gt;&lt;/linker&gt;"
/>
<ItemGroup>
<ResolvedFileToPublish Include="$(_GenerateResourceDesignerAssemblyOutput)">
<RelativePath>$(_DesignerAssemblyName).dll</RelativePath>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<PostprocessAssembly>true</PostprocessAssembly>
<IsTrimmable>true</IsTrimmable>
</ResolvedFileToPublish>
<!-- Preserve all designer types/members via descriptor so ILLink keeps resource
properties. Using a descriptor (not TrimmerRootAssembly) avoids making the
assembly an entry point, which would pull netstandard.dll into the output. -->
<TrimmerRootDescriptor Include="$(_DesignerLinkerDescriptor)" />
<FileWrites Include="$(_DesignerLinkerDescriptor)" />
</ItemGroup>
</Target>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@
<Target Name="_PrepareLinking"
Condition=" '$(PublishTrimmed)' == 'true' "
AfterTargets="ComputeResolvedFilesToPublishList"
DependsOnTargets="GetReferenceAssemblyPaths;_CreatePropertiesCache">
DependsOnTargets="GetReferenceAssemblyPaths;_CreatePropertiesCache;_AddResourceDesignerToPublishFiles">
<PropertyGroup>
<TrimmerRemoveSymbols Condition=" '$(AndroidIncludeDebugSymbols)' != 'true' ">true</TrimmerRemoveSymbols>
<_ExtraTrimmerArgs Condition=" '$(_EnableSerializationDiscovery)' != 'false' ">--enable-serialization-discovery $(_ExtraTrimmerArgs)</_ExtraTrimmerArgs>
Expand Down Expand Up @@ -197,12 +197,6 @@
<_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" Type="Microsoft.Android.Sdk.ILLink.PreserveJavaInterfaces" />
<!-- Custom steps that run after MarkStep -->
<!-- Custom steps that run after CleanStep -->
<_TrimmerCustomSteps
Condition=" '$(AndroidUseDesignerAssembly)' == 'true' "
Include="$(_AndroidLinkerCustomStepAssembly)"
BeforeStep="MarkStep"
Type="MonoDroid.Tuner.FixLegacyResourceDesignerStep"
/>
<_TrimmerCustomSteps
Condition=" '$(_AndroidTypeMapImplementation)' == 'managed' "
Include="$(_AndroidLinkerCustomStepAssembly)"
Expand Down Expand Up @@ -247,7 +241,8 @@
Assemblies="@(_PostTrimmingAssembly)"
AddKeepAlives="$(AndroidAddKeepAlives)"
AndroidLinkResources="$(AndroidLinkResources)"
Deterministic="$(Deterministic)" />
Deterministic="$(Deterministic)"
UseDesignerAssembly="$(AndroidUseDesignerAssembly)" />
</Target>

<!-- Inject _TypeMapKind into the property cache -->
Expand Down
33 changes: 33 additions & 0 deletions src/Xamarin.Android.Build.Tasks/Tasks/PostTrimmingPipeline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Microsoft.Android.Build.Tasks;
using Microsoft.Build.Framework;
using Mono.Cecil;
using Mono.Linker;
using MonoDroid.Tuner;

namespace Xamarin.Android.Tasks;
Expand Down Expand Up @@ -34,6 +35,8 @@ public class PostTrimmingPipeline : AndroidTask

public bool Deterministic { get; set; }

public bool UseDesignerAssembly { get; set; }

public override bool RunTask ()
{
using var resolver = new DirectoryAssemblyResolver (
Expand Down Expand Up @@ -100,6 +103,15 @@ public override bool RunTask ()
},
(msg) => Log.LogDebugMessage (msg)));
}
if (UseDesignerAssembly) {
// Create an MSBuildLinkContext so FixLegacyResourceDesignerStep can resolve assemblies
// and log messages. The resolver is owned by the outer 'using' block, so we intentionally
// do not dispose this context (LinkContext.Dispose would double-dispose the resolver).
var linkContext = new MSBuildLinkContext (resolver, Log);
var fixLegacyStep = new FixLegacyResourceDesignerStep ();
fixLegacyStep.Initialize (linkContext);
steps.Add (new PostTrimmingFixLegacyResourceDesignerStep (fixLegacyStep));
}

foreach (var (item, assembly) in loadedAssemblies) {
var context = new StepContext (item, item);
Expand All @@ -118,3 +130,24 @@ public override bool RunTask ()
return !Log.HasLoggedErrors;
}
}

/// <summary>
/// Thin wrapper around <see cref="FixLegacyResourceDesignerStep"/> for the post-trimming pipeline.
/// Calls <see cref="FixLegacyResourceDesignerStep.ProcessAssemblyDesigner"/> directly, matching the
/// behavior of the former ILLink path which processed all assemblies without StepContext flag filtering.
/// Assemblies without a resource designer are skipped internally by ProcessAssemblyDesigner.
/// </summary>
class PostTrimmingFixLegacyResourceDesignerStep : IAssemblyModifierPipelineStep
{
readonly FixLegacyResourceDesignerStep _inner;

public PostTrimmingFixLegacyResourceDesignerStep (FixLegacyResourceDesignerStep inner)
{
_inner = inner;
}

public void ProcessAssembly (AssemblyDefinition assembly, StepContext context)
{
context.IsAssemblyModified |= _inner.ProcessAssemblyDesigner (assembly);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
<Compile Include="..\..\bin\Build$(Configuration)\XABuildConfig.cs" />

<!-- Include only the linker sources required for the build tasks (LinkAssembliesNoShrink and PostTrimmingPipeline) -->
<!-- These include: AddKeepAlivesStep, AddKeepAlivesHelper, CheckForObsoletePreserveAttributeStep, StripEmbeddedLibrariesStep, PostTrimmingAddKeepAlivesStep, FixAbstractMethodsStep, FixLegacyResourceDesignerStep -->
<!-- These include: AddKeepAlivesStep, AddKeepAlivesHelper, CheckForObsoletePreserveAttributeStep, StripEmbeddedLibrariesStep, PostTrimmingAddKeepAlivesStep, FixAbstractMethodsStep, FixLegacyResourceDesignerStep, LinkDesignerBase -->
<Compile Remove="Linker\**" />
<Compile Include="Linker\MonoDroid.Tuner\FindTypeMapObjectsStep.cs" />
<Compile Include="Linker\MonoDroid.Tuner\FindJavaObjectsStep.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1423,7 +1423,7 @@ private void OnPaintSurface(object sender, SKPaintSurfaceEventArgs e)
// TODO: fix for NativeAOT
if (!addResource && runtime != AndroidRuntime.NativeAOT) {
Assert.IsFalse (b.Build (app, doNotCleanupOnUpdate: true), $"Build of {app.ProjectName} should have failed.");
Assert.IsTrue (b.LastBuildOutput.ContainsText (isRelease ? "IL8000" : "XA8000"));
Assert.IsTrue (b.LastBuildOutput.ContainsText ("XA8000"));
Assert.IsTrue (b.LastBuildOutput.ContainsText ("@styleable/SKCanvasView"), "Expected '@styleable/SKCanvasView' in build output.");
Assert.IsTrue (b.LastBuildOutput.ContainsText ("@styleable/SKCanvasView_ignorePixelScaling"), "Expected '@styleable/SKCanvasView_ignorePixelScaling' in build output.");
return;
Expand Down