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 @@ -135,7 +135,7 @@ public void Generate (IReadOnlyList<string> perAssemblyTypeMapNames, bool useSha
pe.EmitIgnoresAccessChecksToAttribute (accessTargets);

// Emit TypeMapLoader class with Initialize() method
EmitTypeMapLoader (pe, anchorTypeHandle, perAssemblyTypeMapNames, useSharedTypemapUniverse, maxArrayRank);
EmitTypeMapLoader (pe, anchorTypeHandle, perAssemblyTypeMapNames, useSharedTypemapUniverse, maxArrayRank, assemblyName);

pe.WritePE (stream);
}
Expand Down Expand Up @@ -201,7 +201,7 @@ static void EmitAssemblyTargetAttribute (PEAssemblyBuilder pe, MemberReferenceHa
pe.Metadata.AddCustomAttribute (EntityHandle.AssemblyDefinition, ctorRef, blobHandle);
}

static void EmitTypeMapLoader (PEAssemblyBuilder pe, EntityHandle anchorTypeHandle, IReadOnlyList<string> perAssemblyTypeMapNames, bool useSharedTypemapUniverse, int maxArrayRank)
static void EmitTypeMapLoader (PEAssemblyBuilder pe, EntityHandle anchorTypeHandle, IReadOnlyList<string> perAssemblyTypeMapNames, bool useSharedTypemapUniverse, int maxArrayRank, string assemblyName)
{
var metadata = pe.Metadata;

Expand Down Expand Up @@ -243,21 +243,21 @@ static void EmitTypeMapLoader (PEAssemblyBuilder pe, EntityHandle anchorTypeHand
if (maxArrayRank > 0) {
var initializeRef = AddInitializeSingleWithArraysRef (pe, trimmableTypeMapRef, iReadOnlyDictOpenRef, systemTypeRef);
EmitInitializeWithSingleTypeMap (pe, anchorTypeHandle, getExternalMemberRef, getProxyMemberRef,
initializeRef, externalDictTypeSpec, externalDictArrayTypeSpec, perAssemblyTypeMapNames, maxArrayRank);
initializeRef, externalDictTypeSpec, externalDictArrayTypeSpec, perAssemblyTypeMapNames, maxArrayRank, assemblyName);
} else {
var initializeRef = AddInitializeSingleNoArraysRef (pe, trimmableTypeMapRef, iReadOnlyDictOpenRef, systemTypeRef);
EmitInitializeWithSingleTypeMapNoArrays (pe, anchorTypeHandle, getExternalMemberRef, getProxyMemberRef, initializeRef);
EmitInitializeWithSingleTypeMapNoArrays (pe, anchorTypeHandle, getExternalMemberRef, getProxyMemberRef, initializeRef, assemblyName);
}
} else {
var proxyDictTypeSpec = MakeIReadOnlyDictTypeSpec (pe, iReadOnlyDictOpenRef, systemTypeRef, keyIsString: false);
if (maxArrayRank > 0) {
var initializeRef = AddInitializeAggregateWithArraysRef (pe, trimmableTypeMapRef, iReadOnlyDictOpenRef, systemTypeRef);
EmitInitializeWithAggregateTypeMap (pe, perAssemblyTypeMapNames, getExternalMemberRef, getProxyMemberRef,
initializeRef, externalDictTypeSpec, proxyDictTypeSpec, externalDictArrayTypeSpec, iReadOnlyDictOpenRef, systemTypeRef, maxArrayRank);
initializeRef, externalDictTypeSpec, proxyDictTypeSpec, externalDictArrayTypeSpec, iReadOnlyDictOpenRef, systemTypeRef, maxArrayRank, assemblyName);
} else {
var initializeRef = AddInitializeAggregateNoArraysRef (pe, trimmableTypeMapRef, iReadOnlyDictOpenRef, systemTypeRef);
EmitInitializeWithAggregateTypeMapNoArrays (pe, perAssemblyTypeMapNames, getExternalMemberRef, getProxyMemberRef,
initializeRef, externalDictTypeSpec, proxyDictTypeSpec, iReadOnlyDictOpenRef, systemTypeRef);
initializeRef, externalDictTypeSpec, proxyDictTypeSpec, iReadOnlyDictOpenRef, systemTypeRef, assemblyName);
}
}
}
Expand All @@ -274,7 +274,8 @@ static void EmitInitializeWithAggregateTypeMap (PEAssemblyBuilder pe,
TypeSpecificationHandle externalDictTypeSpec, TypeSpecificationHandle proxyDictTypeSpec,
TypeSpecificationHandle externalDictArrayTypeSpec,
TypeReferenceHandle iReadOnlyDictOpenRef, TypeReferenceHandle systemTypeRef,
int maxArrayRank)
int maxArrayRank,
string assemblyName)
{
var count = perAssemblyTypeMapNames.Count;

Expand All @@ -292,6 +293,7 @@ static void EmitInitializeWithAggregateTypeMap (PEAssemblyBuilder pe,
MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
sig => sig.MethodSignature ().Parameters (0, rt => rt.Void (), p => { }),
encoder => {
EmitSetTypeMappingEntryAssembly (pe, encoder, assemblyName);
// var typeMaps = new IReadOnlyDictionary<string, Type>[N]; (loc 0)
EmitNewArrayLocal (encoder, count, externalDictTypeSpec, slot: 0);
EmitFillArrayLocal (encoder, count, getExternalSpecs, slot: 0);
Expand Down Expand Up @@ -345,7 +347,8 @@ static void EmitInitializeWithAggregateTypeMapNoArrays (PEAssemblyBuilder pe,
MemberReferenceHandle getExternalMemberRef, MemberReferenceHandle getProxyMemberRef,
MemberReferenceHandle initializeRef,
TypeSpecificationHandle externalDictTypeSpec, TypeSpecificationHandle proxyDictTypeSpec,
TypeReferenceHandle iReadOnlyDictOpenRef, TypeReferenceHandle systemTypeRef)
TypeReferenceHandle iReadOnlyDictOpenRef, TypeReferenceHandle systemTypeRef,
string assemblyName)
{
var count = perAssemblyTypeMapNames.Count;

Expand All @@ -363,6 +366,7 @@ static void EmitInitializeWithAggregateTypeMapNoArrays (PEAssemblyBuilder pe,
MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
sig => sig.MethodSignature ().Parameters (0, rt => rt.Void (), p => { }),
encoder => {
EmitSetTypeMappingEntryAssembly (pe, encoder, assemblyName);
EmitNewArrayLocal (encoder, count, externalDictTypeSpec, slot: 0);
EmitFillArrayLocal (encoder, count, getExternalSpecs, slot: 0);

Expand Down Expand Up @@ -432,7 +436,8 @@ static void EmitInitializeWithSingleTypeMap (PEAssemblyBuilder pe, EntityHandle
MemberReferenceHandle initializeRef,
TypeSpecificationHandle externalDictTypeSpec, TypeSpecificationHandle externalDictArrayTypeSpec,
IReadOnlyList<string> perAssemblyTypeMapNames,
int maxArrayRank)
int maxArrayRank,
string assemblyName)
{
var getExternalSpec = MakeGenericMethodSpec (pe, getExternalMemberRef, anchorTypeHandle);
var getProxySpec = MakeGenericMethodSpec (pe, getProxyMemberRef, anchorTypeHandle);
Expand All @@ -441,6 +446,7 @@ static void EmitInitializeWithSingleTypeMap (PEAssemblyBuilder pe, EntityHandle
MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
sig => sig.MethodSignature ().Parameters (0, rt => rt.Void (), p => { }),
encoder => {
EmitSetTypeMappingEntryAssembly (pe, encoder, assemblyName);
// TrimmableTypeMap.Initialize(GetExternal<JL.Object>(), GetProxy<JL.Object>(), arrayMapsByAssemblyAndRank-or-null)
encoder.Call (getExternalSpec, parameterCount: 0, returnsValue: true);
encoder.Call (getProxySpec, parameterCount: 0, returnsValue: true);
Expand All @@ -456,7 +462,8 @@ static void EmitInitializeWithSingleTypeMap (PEAssemblyBuilder pe, EntityHandle
/// </summary>
static void EmitInitializeWithSingleTypeMapNoArrays (PEAssemblyBuilder pe, EntityHandle anchorTypeHandle,
MemberReferenceHandle getExternalMemberRef, MemberReferenceHandle getProxyMemberRef,
MemberReferenceHandle initializeRef)
MemberReferenceHandle initializeRef,
string assemblyName)
{
var getExternalSpec = MakeGenericMethodSpec (pe, getExternalMemberRef, anchorTypeHandle);
var getProxySpec = MakeGenericMethodSpec (pe, getProxyMemberRef, anchorTypeHandle);
Expand All @@ -465,6 +472,7 @@ static void EmitInitializeWithSingleTypeMapNoArrays (PEAssemblyBuilder pe, Entit
MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
sig => sig.MethodSignature ().Parameters (0, rt => rt.Void (), p => { }),
encoder => {
EmitSetTypeMappingEntryAssembly (pe, encoder, assemblyName);
encoder.Call (getExternalSpec, parameterCount: 0, returnsValue: true);
encoder.Call (getProxySpec, parameterCount: 0, returnsValue: true);
encoder.Call (initializeRef, parameterCount: 2);
Expand All @@ -486,6 +494,22 @@ static MemberReferenceHandle AddInitializeSingleNoArraysRef (PEAssemblyBuilder p
pe.Metadata.GetOrAddString ("Initialize"), pe.Metadata.GetOrAddBlob (blob));
}

static void EmitSetTypeMappingEntryAssembly (PEAssemblyBuilder pe, TrackedInstructionEncoder encoder, string assemblyName)
{
var appContextRef = pe.Metadata.AddTypeReference (pe.SystemRuntimeRef,
pe.Metadata.GetOrAddString ("System"), pe.Metadata.GetOrAddString ("AppContext"));
var setDataRef = pe.AddMemberRef (appContextRef, "SetData",
sig => sig.MethodSignature ().Parameters (2,
rt => rt.Void (),
p => {
p.AddParameter ().Type ().String ();
p.AddParameter ().Type ().Object ();
}));
encoder.LoadString (pe.Metadata.GetOrAddUserString ("System.Runtime.InteropServices.TypeMappingEntryAssembly"));
encoder.LoadString (pe.Metadata.GetOrAddUserString (assemblyName));
encoder.Call (setDataRef, parameterCount: 2);
}

/// <summary>MemberRef for <c>TrimmableTypeMap.Initialize(typeMap, proxyMap, arrayMapsByAssemblyAndRank[][])</c>.</summary>
static MemberReferenceHandle AddInitializeSingleWithArraysRef (PEAssemblyBuilder pe, TypeReferenceHandle trimmableTypeMapRef,
TypeReferenceHandle iReadOnlyDictOpenRef, TypeReferenceHandle systemTypeRef)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,11 @@ public sealed record JavaPeerInfo
public required string AssemblyName { get; init; }

/// <summary>
/// True when the type belongs to a framework assembly.
/// True when the type belongs to a framework assembly supplied by the Android SDK.
/// Framework ACWs are generated by the SDK and can be trimmed like bindings unless
/// another rule explicitly roots them.
/// </summary>
public bool IsFrameworkAssembly { get; init; }
public bool IsFrameworkAssembly { get; set; }

/// <summary>
/// True when per-rank array typemap entries should be generated for this peer.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@
<_TrimmableRuntimeProviderJavaName Condition=" '$(_TrimmableRuntimeProviderJavaName)' == '' ">mono.MonoRuntimeProvider</_TrimmableRuntimeProviderJavaName>
</PropertyGroup>

<PropertyGroup>
<_GenerateProguardAfterTargets Condition=" '$(_GenerateProguardAfterTargets)' == '' ">ILLink</_GenerateProguardAfterTargets>
</PropertyGroup>

<!-- Add TypeMap DLLs to ILLink input. ILLink natively understands TypeMapAttribute<T>. -->
<Target Name="_AddTrimmableTypeMapToLinker"
BeforeTargets="PrepareForILLink;_RunILLink"
DependsOnTargets="_GenerateTrimmableTypeMap">
<ItemGroup>
<ManagedAssemblyToLink Include="$(_TypeMapOutputDirectory)*.dll">
<DestinationSubPath>%(Filename)%(Extension)</DestinationSubPath>
<IsTrimmable>true</IsTrimmable>
</ManagedAssemblyToLink>
</ItemGroup>
</Target>
Expand All @@ -21,10 +26,28 @@
BeforeTargets="PrepareForILLink;_RunILLink"
DependsOnTargets="_GenerateTrimmableTypeMap">
<PropertyGroup>
<_ExtraTrimmerArgs>--typemap-entry-assembly $(_TypeMapAssemblyName) $(_ExtraTrimmerArgs)</_ExtraTrimmerArgs>
<_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --typemap-entry-assembly "$(_TypeMapAssemblyName)"</_ExtraTrimmerArgs>
</PropertyGroup>
</Target>

<Target Name="_PrepareLinkedAssembliesForProguard"
AfterTargets="$(_GenerateProguardAfterTargets)"
Condition=" '$(PublishTrimmed)' == 'true' and '$(_ProguardProjectConfiguration)' != '' ">
<ItemGroup>
<_LinkedAssemblyForProguard Include="@(ResolvedFileToPublish)" Condition=" '%(Extension)' == '.dll' " />
</ItemGroup>
</Target>

<Target Name="_GenerateProguardConfiguration"
AfterTargets="_PrepareLinkedAssembliesForProguard"
Condition=" '$(PublishTrimmed)' == 'true' and '$(_ProguardProjectConfiguration)' != '' "
Inputs="@(_LinkedAssemblyForProguard)"
Outputs="$(_ProguardProjectConfiguration)">
<GenerateProguardConfiguration
LinkedAssemblies="@(_LinkedAssemblyForProguard)"
OutputFile="$(_ProguardProjectConfiguration)" />
</Target>

<!-- Add linked TypeMap DLLs to the normal publish assembly pipeline. The SDK R2R
target only compiles ResolvedFileToPublish items with PostprocessAssembly=true. -->
<Target Name="_AddTrimmableTypeMapToResolvedFileToPublish"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<UsingTask TaskName="Xamarin.Android.Tasks.GenerateTrimmableTypeMap" AssemblyFile="$(_XamarinAndroidBuildTasksAssembly)" />
<UsingTask TaskName="Xamarin.Android.Tasks.GenerateEmptyTypemapStub" AssemblyFile="$(_XamarinAndroidBuildTasksAssembly)" />
<UsingTask TaskName="Xamarin.Android.Tasks.GenerateNativeAotBootstrapSources" AssemblyFile="$(_XamarinAndroidBuildTasksAssembly)" />
<UsingTask TaskName="Xamarin.Android.Tasks.GenerateProguardConfiguration" AssemblyFile="$(_XamarinAndroidBuildTasksAssembly)" />

<Import Project="$(MSBuildThisFileDirectory)Microsoft.Android.Sdk.TypeMap.Trimmable.CoreCLR.targets"
Condition=" '$(_AndroidRuntime)' == 'CoreCLR' " />
Expand All @@ -23,10 +24,10 @@
<_TypeMapOutputDirectory>$(_TypeMapBaseOutputDir)typemap/</_TypeMapOutputDirectory>
<_TypeMapJavaOutputDirectory>$(_TypeMapBaseOutputDir)typemap/java</_TypeMapJavaOutputDirectory>
<_TypeMapAssembliesListFile>$(_TypeMapOutputDirectory)typemap-assemblies.txt</_TypeMapAssembliesListFile>
<!-- Max array rank for __ArrayMapRank{N} sentinel emission. Defaults to 3 for NativeAOT
(PublishAot=true, dynamic code is unavailable, so array creation uses the typemap path);
<!-- Max array rank for __ArrayMapRank{N} sentinel emission. Defaults to 3 when
dynamic code is unavailable, so array creation uses the typemap path;
defaults to 0 otherwise, where dynamic code can use Array.CreateInstance directly. -->
<_AndroidTrimmableTypeMapMaxArrayRank Condition=" '$(_AndroidTrimmableTypeMapMaxArrayRank)' == '' and '$(PublishAot)' == 'true' ">3</_AndroidTrimmableTypeMapMaxArrayRank>
<_AndroidTrimmableTypeMapMaxArrayRank Condition=" '$(_AndroidTrimmableTypeMapMaxArrayRank)' == '' and ('$(PublishAot)' == 'true' or '$(DynamicCodeSupport)' == 'false') ">3</_AndroidTrimmableTypeMapMaxArrayRank>
<_AndroidTrimmableTypeMapMaxArrayRank Condition=" '$(_AndroidTrimmableTypeMapMaxArrayRank)' == '' ">0</_AndroidTrimmableTypeMapMaxArrayRank>
<IncrementalCleanDependsOn>
_RecordTrimmableTypeMapFileWrites;
Expand Down Expand Up @@ -88,6 +89,7 @@
<GenerateTrimmableTypeMap
ResolvedAssemblies="@(_TypeMapInputAssemblies)"
ResolvedFrameworkAssemblies="@(ResolvedFrameworkAssemblies)"
FrameworkAssemblyNames="@(ResolvedFrameworkAssemblies->'%(Filename)')"
OutputDirectory="$(_TypeMapOutputDirectory)"
JavaSourceOutputDirectory="$(_TypeMapJavaOutputDirectory)"
TargetFrameworkVersion="$(TargetFrameworkVersion)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ namespace Xamarin.Android.Tasks;

public class GenerateTrimmableTypeMap : AndroidTask
{
static readonly string [] DefaultFrameworkAssemblyNames = [
"Java.Interop",
"Mono.Android",
"Mono.Android.Runtime",
];

sealed class MSBuildTrimmableTypeMapLogger (TaskLoggingHelper log) : ITrimmableTypeMapLogger
{
public void LogNoJavaPeerTypesFound () =>
Expand Down Expand Up @@ -46,6 +52,7 @@ public void LogJniAddNativeMethodRegistrationAttributeError (string managedTypeN
[Required]
public ITaskItem [] ResolvedAssemblies { get; set; } = [];
public ITaskItem [] ResolvedFrameworkAssemblies { get; set; } = [];
public string [] FrameworkAssemblyNames { get; set; } = [];
[Required]
public string OutputDirectory { get; set; } = "";
[Required]
Expand Down Expand Up @@ -105,7 +112,10 @@ public override bool RunTask ()
Path: g.Key,
IsFrameworkAssembly: frameworkAssemblyPaths.Contains (g.Key) || g.Any (IsFrameworkAssemblyItem)))
.ToList ();
var frameworkAssemblyNames = new HashSet<string> (StringComparer.OrdinalIgnoreCase);
var frameworkAssemblyNames = new HashSet<string> (DefaultFrameworkAssemblyNames, StringComparer.OrdinalIgnoreCase);
foreach (var assemblyName in FrameworkAssemblyNames) {
frameworkAssemblyNames.Add (assemblyName);
}

Directory.CreateDirectory (OutputDirectory);
Directory.CreateDirectory (JavaSourceOutputDirectory);
Expand Down
Loading