Skip to content
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

Enable marshal methods support by default #7351

Merged
merged 141 commits into from
Oct 10, 2022
Merged
Show file tree
Hide file tree
Changes from 94 commits
Commits
Show all changes
141 commits
Select commit Hold shift + click to select a range
35f4e24
Implement marshal methods LLVM IR executable code generator.
grendello Mar 29, 2022
e34f88e
[marshal methods] Runtime fixes and missing features
grendello Mar 29, 2022
eb15bd2
Update
grendello Jul 18, 2022
a80e4a1
TODOs and CWLs
grendello Jul 18, 2022
49751f7
Update JI
grendello Jul 26, 2022
803b3e3
Merge branch 'main' into mm-codegen
grendello Aug 1, 2022
e6101c1
Merge branch 'mm-codegen' into mm-runtime
grendello Aug 1, 2022
657aff0
[WIP] Generate full native symbol names when necessary
grendello Aug 1, 2022
e8d3026
Handle enums properly (except when there are arrays of them)
grendello Aug 2, 2022
4d7ec30
Merge branch 'main' into mm-codegen
grendello Aug 3, 2022
39068d3
Merge branch 'mm-codegen' into mm-runtime
grendello Aug 3, 2022
82ece43
Generate correct native names and process overloads properly
grendello Aug 3, 2022
acd5bc8
When a class is first seen, make sure to set class index properly
grendello Aug 3, 2022
9a476d8
Merge branch 'main' into mm-codegen
grendello Aug 3, 2022
8d2503f
Merge branch 'mm-codegen' into mm-runtime
grendello Aug 3, 2022
f913d24
Merge branch 'main' into mm-codegen
grendello Aug 5, 2022
52c99db
Merge branch 'mm-codegen' into mm-runtime
grendello Aug 5, 2022
e5358f4
Trying to get the MAUI sample app running
grendello Aug 5, 2022
2f15f67
Merge branch 'main' into mm-codegen
grendello Aug 5, 2022
21c066f
Merge branch 'mm-codegen' into mm-runtime
grendello Aug 5, 2022
3c8901a
MAUI app ran with marshal methods for the first time
grendello Aug 8, 2022
7dc40fc
Check array dimensions when classifying methods
grendello Aug 8, 2022
2b2ce55
Merge branch 'main' into mm-codegen
grendello Aug 8, 2022
9c38c68
Merge branch 'mm-codegen' into mm-runtime
grendello Aug 8, 2022
85f2cfa
Merge branch 'main' into mm-codegen
grendello Aug 10, 2022
024b5f5
Merge branch 'mm-codegen' into mm-runtime
grendello Aug 10, 2022
4d92570
We need to generate wrappers for methods with non-blittable params
grendello Aug 10, 2022
20a2f00
Blittable wrapper generator progress
grendello Aug 11, 2022
2d3c043
Non-blittable marshal method wrappers implemented
grendello Aug 12, 2022
071e9d3
Merge branch 'main' into mm-codegen
grendello Aug 17, 2022
710242e
Merge branch 'mm-codegen' into mm-runtime
grendello Aug 17, 2022
af91895
Fix non-blittable wrapper method generation
grendello Aug 17, 2022
673836c
Merge branch 'main' into mm-codegen
grendello Aug 17, 2022
ca2f92d
Merge branch 'mm-codegen' into mm-runtime
grendello Aug 17, 2022
10e63e2
Merge branch 'main' into mm-codegen
grendello Aug 17, 2022
238417e
Merge branch 'mm-codegen' into mm-runtime
grendello Aug 17, 2022
72c4b60
Disable some debug CWLs
grendello Aug 18, 2022
eb94adc
Merge branch 'mm-codegen' into mm-runtime
grendello Aug 18, 2022
a8471cd
Add some debugging info to function pointer lookups
grendello Aug 18, 2022
cfaabf2
Escape double quotes in function attribute value
grendello Aug 18, 2022
8ca61bb
Merge branch 'main' into mm-codegen
grendello Aug 18, 2022
a473f27
Merge branch 'mm-codegen' into mm-runtime
grendello Aug 18, 2022
d99b7e3
Fix and optimize debugging info for class and method names
grendello Aug 19, 2022
cfa1b30
Reorganize code, move error handling to the end of function
grendello Aug 19, 2022
9c9612d
Merge branch 'main' into mm-runtime
grendello Aug 19, 2022
334619b
Disable marshal methods for PR
grendello Aug 19, 2022
c9332a8
Move some code behind the ENABLE_MARSHAL_METHODS flag
grendello Aug 19, 2022
e518a4e
Remove workarounds for methods with non-blittable types
grendello Aug 22, 2022
905e784
Build marshal methods support unconditionally
grendello Aug 22, 2022
f29f0d2
Remove debugging messages
grendello Aug 22, 2022
6ca1245
Update apkdesc files
grendello Aug 22, 2022
b988b7f
Merge branch 'mm-runtime' into mm-cleanup-and-enable
grendello Aug 22, 2022
63bf193
Fix a failing test
grendello Aug 22, 2022
3530c39
Merge branch 'mm-runtime' into mm-cleanup-and-enable
grendello Aug 22, 2022
c516792
Merge branch 'main' into mm-runtime
grendello Aug 23, 2022
c8a2d9f
Implement some requested changes
grendello Aug 23, 2022
e8f3215
Merge branch 'mm-runtime' into mm-cleanup-and-enable
grendello Aug 23, 2022
b60c767
Don't package mono.android.jar when marshal methods are enabled
grendello Aug 23, 2022
0aa3e95
Merge branch 'main' into mm-runtime
grendello Aug 24, 2022
e3ac595
Merge branch 'mm-runtime' into mm-cleanup-and-enable
grendello Aug 24, 2022
49895b8
Merge branch 'main' into mm-runtime
grendello Aug 24, 2022
a8cfd90
Merge branch 'mm-runtime' into mm-cleanup-and-enable
grendello Aug 24, 2022
92fa671
Remove JI workaround
grendello Aug 24, 2022
f37b4dc
Merge branch 'mm-runtime' into mm-cleanup-and-enable
grendello Aug 24, 2022
09678bd
Don't register dynamically methods for which we generate JCWs
grendello Aug 24, 2022
d60fc08
[WIP] Some cleanup + special cases
grendello Aug 25, 2022
6b116bf
Merge branch 'main' into mm-runtime
grendello Aug 26, 2022
1d88be2
Merge branch 'mm-runtime' into mm-cleanup-and-enable
grendello Aug 26, 2022
aea0b0f
TypeManager special case now works
grendello Aug 26, 2022
e1e59f0
Merge branch 'main' into mm-runtime
grendello Aug 31, 2022
aaff9f5
Merge branch 'mm-runtime' into mm-cleanup-and-enable
grendello Aug 31, 2022
df04d47
Merge branch 'main' into mm-runtime
grendello Sep 2, 2022
7e9761f
Merge branch 'mm-runtime' into mm-cleanup-and-enable
grendello Sep 2, 2022
f17ad9f
Fix Debug mode and Release w/o marshal methods
grendello Sep 5, 2022
7a00e0e
Make AOT work (with trimming)
grendello Sep 6, 2022
d3d9007
Merge branch 'main' into mm-runtime
grendello Sep 6, 2022
73237a2
Merge branch 'mm-runtime' into mm-cleanup-and-enable
grendello Sep 6, 2022
b459e4a
Merge branch 'main' into mm-runtime
grendello Sep 7, 2022
dfcf734
Merge branch 'mm-runtime' into mm-cleanup-and-enable
grendello Sep 7, 2022
5dccadb
Time to test things
grendello Sep 7, 2022
fc83958
Merge branch 'main' into mm-cleanup-and-enable
grendello Sep 7, 2022
8bdb607
Merge branch 'main' into mm-cleanup-and-enable
grendello Sep 7, 2022
cd832c7
Turn a couple of warnings into debug messages for now
grendello Sep 7, 2022
a9995b0
Update apkdesc files
grendello Sep 7, 2022
86d9fca
Try to avoid locked files on Windows
grendello Sep 7, 2022
1162a09
Merge branch 'main' into mm-cleanup-and-enable
grendello Sep 8, 2022
65471a8
Try to unbreak build of tests
grendello Sep 8, 2022
7f87a37
Don't require the `EnableMarshalMethods` parameter
grendello Sep 8, 2022
ea4c57f
Merge branch 'main' into mm-cleanup-and-enable
grendello Sep 8, 2022
115c6fa
Remove the check, it's incorrect
grendello Sep 8, 2022
222163e
Avoid warning about duplicate files to add to apk
grendello Sep 8, 2022
5bd03e2
Merge branch 'main' into mm-cleanup-and-enable
grendello Sep 8, 2022
e635b27
Update apkdesc files
grendello Sep 8, 2022
221ad8f
Let's see if it breaks any tests (it works locally)
grendello Sep 8, 2022
d03092d
Merge branch 'main' into mm-cleanup-and-enable
grendello Sep 8, 2022
e1a621e
Merge branch 'main' into mm-cleanup-and-enable
grendello Sep 9, 2022
f9bca3c
Update apkdesc files
grendello Sep 9, 2022
977a060
Hunting for reasons of the crashes
grendello Sep 9, 2022
09eeb7e
Merge branch 'main' into mm-cleanup-and-enable
grendello Sep 9, 2022
312d84e
Refactor the JNIEnv class
grendello Sep 12, 2022
b143c95
Merge branch 'main' into mm-cleanup-and-enable
grendello Sep 13, 2022
c20ae31
Generate assembly image cache array even if marshal methods disabled
grendello Sep 13, 2022
8c9ceca
Most problems solved, the crashes make sense now
grendello Sep 13, 2022
2b33563
Put the assembly reader settings back in
grendello Sep 13, 2022
94d9bea
Merge branch 'main' into mm-cleanup-and-enable
grendello Sep 14, 2022
73277aa
Fix copying of rewritten assemblies
grendello Sep 14, 2022
5b14a70
Fix a typo and relax requirements on GenerateJavaStubs.IntermediateOu…
grendello Sep 14, 2022
9077b6a
Fix unhandled exception propagation
grendello Sep 14, 2022
32347b7
Fix builds of apps with linking and just a single RID
grendello Sep 14, 2022
ddedcc3
[WIP] Investigating a Mono.Android crash
grendello Sep 15, 2022
aed7b2d
Merge branch 'main' into mm-cleanup-and-enable
grendello Sep 16, 2022
2aa7cfe
Mono.Android.NET_Tests crash investigations continued
grendello Sep 16, 2022
92fb339
TODO
grendello Sep 16, 2022
d3c54a0
Merge branch 'main' into mm-cleanup-and-enable
grendello Sep 19, 2022
170b5d1
Factor out bits of code to a separate assembly
grendello Sep 19, 2022
3fdc653
Merge branch 'main' into mm-cleanup-and-enable
grendello Sep 20, 2022
504ced9
[WIP] Exception wrapper generator in assembly rewriter
grendello Sep 20, 2022
be9280e
Merge branch 'main' into mm-cleanup-and-enable
grendello Sep 21, 2022
983ad70
Exception wrapper appears to work now
grendello Sep 21, 2022
7d201e3
Fix a handful of CI test failures
grendello Sep 21, 2022
35d49d4
Remove unnecessary argument
grendello Sep 21, 2022
1ebb5d8
Fix a couple more causes for test failures
grendello Sep 26, 2022
62a5138
More tests fixed
grendello Sep 26, 2022
9852cc5
Merge branch 'main' into mm-cleanup-and-enable
grendello Sep 27, 2022
fe2ae06
Fix tests which use callbacks with Android.Graphics.Color
grendello Sep 27, 2022
e1609d9
Let's see if the failing tests work with these changes
grendello Sep 27, 2022
98655ea
Oops, forgot to put that back in
grendello Sep 27, 2022
5d138d0
Copy PR 7406 to test if it works for marshal methods
grendello Sep 27, 2022
71aafd5
Merge branch 'main' into mm-cleanup-and-enable
grendello Sep 27, 2022
d708edc
Merge branch 'main' into mm-cleanup-and-enable
grendello Sep 27, 2022
7124851
Disable marshal methods for Designer tests
grendello Sep 28, 2022
9be7e6b
Add docs
grendello Sep 28, 2022
edcf092
See if we can get crash logs from designer tests
grendello Sep 29, 2022
48c3328
Let's see if this fixes the designer failures
grendello Sep 29, 2022
5781643
Merge branch 'main' into mm-cleanup-and-enable
grendello Sep 29, 2022
5f433b1
Remove debug logging
grendello Sep 29, 2022
8b1d3f9
Address reviews
grendello Sep 30, 2022
724de1d
Merge branch 'main' into mm-cleanup-and-enable
grendello Oct 5, 2022
d26d9e1
Get rid of dead code
grendello Oct 5, 2022
d5016fe
Update documentation
grendello Oct 10, 2022
f8db2d2
Fix indentation and trailing whitespace
grendello Oct 10, 2022
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
4 changes: 0 additions & 4 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
</PropertyGroup>

<PropertyGroup Condition=" '$(MSBuildRuntimeType)' == 'Core' ">
<_EnableMarshalMethods>NoThanks</_EnableMarshalMethods> <!-- set to YesPlease to enable -->
</PropertyGroup>

<PropertyGroup>
<ProductVersion>13.0.99</ProductVersion>
<!-- NuGet package version numbers. See Documentation/guides/OneDotNet.md.
Expand Down
1 change: 0 additions & 1 deletion build-tools/scripts/JavaCallableWrappers.targets
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
/>
<ItemGroup>
<_JavaSources Include="$(IntermediateOutputPath)jcw\src\**\*.java" />
<_JavaSources Include="$(JavaInteropSourceDirectory)\src\Java.Interop\java\com\xamarin\**\*.java" />
</ItemGroup>
<WriteLinesToFile
File="$(IntermediateOutputPath)jcw/classes.txt"
Expand Down
67 changes: 23 additions & 44 deletions src/Mono.Android/Android.Runtime/AndroidRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -473,28 +473,18 @@ static bool CallRegisterMethodByIndex (JniNativeMethodRegistrationArguments argu
public override void RegisterNativeMembers (JniType nativeClass, Type type, string? methods) =>
RegisterNativeMembers (nativeClass, type, methods.AsSpan ());

#if ENABLE_MARSHAL_METHODS
// Temporary hack, see comments in RegisterNativeMembers below
static readonly Dictionary<string, string[]> dynamicRegistrationMethods = new Dictionary<string, string[]> (StringComparer.Ordinal) {
{"Android.Views.View+IOnLayoutChangeListenerImplementor", new string[] { "GetOnLayoutChange_Landroid_view_View_IIIIIIIIHandler" }},
{"Android.Views.View+IOnLayoutChangeListenerInvoker", new string[] { "GetOnLayoutChange_Landroid_view_View_IIIIIIIIHandler" }},
{"Java.Interop.TypeManager+JavaTypeManager", new string[] { "GetActivateHandler" }},
// leaving it empty for now, until we're sure it's no longer needed (there are some test failures which may still require it to fix them)
};
#endif

public void RegisterNativeMembers (JniType nativeClass, Type type, ReadOnlySpan<char> methods)
{
#if ENABLE_MARSHAL_METHODS
Logger.Log (LogLevel.Info, "monodroid-mm", $"RegisterNativeMembers ('{nativeClass?.Name}', '{type?.FullName}', '{methods.ToString ()}')");
Logger.Log (LogLevel.Info, "monodroid-mm", "RegisterNativeMembers called from:");
var st = new StackTrace (true);
Logger.Log (LogLevel.Info, "monodroid-mm", st.ToString ());

if (methods.IsEmpty) {
Logger.Log (LogLevel.Info, "monodroid-mm", "No methods to register, returning");
Logger.Log (LogLevel.Debug, "monodroid-mm", "No methods to register, returning");
return;
}
#endif

try {
if (FastRegisterNativeMembers (nativeClass, type, methods))
return;
Expand All @@ -517,9 +507,8 @@ public void RegisterNativeMembers (JniType nativeClass, Type type, ReadOnlySpan<
MethodInfo []? typeMethods = null;

ReadOnlySpan<char> methodsSpan = methods;
#if ENABLE_MARSHAL_METHODS
bool needToRegisterNatives = false;
#endif

while (!methodsSpan.IsEmpty) {
int newLineIndex = methodsSpan.IndexOf ('\n');

Expand All @@ -545,9 +534,7 @@ public void RegisterNativeMembers (JniType nativeClass, Type type, ReadOnlySpan<
if (minfo == null)
throw new InvalidOperationException (String.Format ("Specified managed method '{0}' was not found. Signature: {1}", mname.ToString (), signature.ToString ()));
callback = CreateDynamicCallback (minfo);
#if ENABLE_MARSHAL_METHODS
needToRegisterNatives = true;
#endif
} else {
Type callbackDeclaringType = type;
if (!callbackDeclaringTypeString.IsEmpty) {
Expand All @@ -556,64 +543,57 @@ public void RegisterNativeMembers (JniType nativeClass, Type type, ReadOnlySpan<
while (callbackDeclaringType.ContainsGenericParameters) {
callbackDeclaringType = callbackDeclaringType.BaseType!;
}
#if ENABLE_MARSHAL_METHODS

// TODO: this is temporary hack, it needs a full fledged registration mechanism for methods like these (that is, ones which
// aren't registered with [Register] but are baked into Mono.Android's managed and Java code)
bool createCallback = false;
string declaringTypeName = callbackDeclaringType.FullName;
string callbackName = callbackString.ToString ();

foreach (var kvp in dynamicRegistrationMethods) {
string dynamicTypeName = kvp.Key;
bool createCallback;
if (JNIEnv.MarshalMethodsEnabled) {
string declaringTypeName = callbackDeclaringType.FullName;
string callbackName = callbackString.ToString ();

createCallback = false;
foreach (var kvp in dynamicRegistrationMethods) {
string dynamicTypeName = kvp.Key;

foreach (string dynamicCallbackMethodName in kvp.Value) {
if (ShouldRegisterDynamically (declaringTypeName, callbackName, dynamicTypeName, dynamicCallbackMethodName)) {
createCallback = true;
break;
}
}

foreach (string dynamicCallbackMethodName in kvp.Value) {
if (ShouldRegisterDynamically (declaringTypeName, callbackName, dynamicTypeName, dynamicCallbackMethodName)) {
createCallback = true;
if (createCallback) {
break;
}
}

if (createCallback) {
break;
}
} else {
createCallback = true;
}

if (createCallback) {
Logger.Log (LogLevel.Info, "monodroid-mm", $" creating delegate for: '{callbackString.ToString()}' in type {callbackDeclaringType.FullName}");
#endif
GetCallbackHandler connector = (GetCallbackHandler) Delegate.CreateDelegate (typeof (GetCallbackHandler),
callbackDeclaringType, callbackString.ToString ());
callback = connector ();
#if ENABLE_MARSHAL_METHODS
} else {
Logger.Log (LogLevel.Warn, "monodroid-mm", $" would try to create delegate for: '{callbackString.ToString()}' in type {callbackDeclaringType.FullName}");
}
#endif
}

if (callback != null) {
#if ENABLE_MARSHAL_METHODS
needToRegisterNatives = true;
#endif
natives [nativesIndex++] = new JniNativeMethodRegistration (name.ToString (), signature.ToString (), callback);
}
}

methodsSpan = newLineIndex != -1 ? methodsSpan.Slice (newLineIndex + 1) : default;
}

#if ENABLE_MARSHAL_METHODS
if (needToRegisterNatives) {
#endif
JniEnvironment.Types.RegisterNatives (nativeClass.PeerReference, natives, nativesIndex);
#if ENABLE_MARSHAL_METHODS
}
#endif
} catch (Exception e) {
JniEnvironment.Runtime.RaisePendingException (e);
}

#if ENABLE_MARSHAL_METHODS
bool ShouldRegisterDynamically (string callbackTypeName, string callbackString, string typeName, string callbackName)
{
if (String.Compare (typeName, callbackTypeName, StringComparison.Ordinal) != 0) {
Expand All @@ -622,7 +602,6 @@ bool ShouldRegisterDynamically (string callbackTypeName, string callbackString,

return String.Compare (callbackName, callbackString, StringComparison.Ordinal) == 0;
}
#endif
}

static int CountMethods (ReadOnlySpan<char> methodsSpan)
Expand Down
5 changes: 5 additions & 0 deletions src/Mono.Android/Android.Runtime/JNIEnv.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ struct JnienvInitializeArgs {
public byte ioExceptionType;
public int jniAddNativeMethodRegistrationAttributePresent;
public bool jniRemappingInUse;
public bool marshalMethodsEnabled;
}
#pragma warning restore 0649

Expand All @@ -57,6 +58,7 @@ public static partial class JNIEnv {

internal static bool IsRunningOnDesktop;
internal static bool LogAssemblyCategory;
internal static bool MarshalMethodsEnabled;

static AndroidRuntime? androidRuntime;
static BoundExceptionType BoundExceptionType;
Expand Down Expand Up @@ -156,6 +158,9 @@ internal static unsafe void Initialize (JnienvInitializeArgs* args)
gref_gc_threshold = args->grefGcThreshold;

jniRemappingInUse = args->jniRemappingInUse;
#if NETCOREAPP
MarshalMethodsEnabled = args->marshalMethodsEnabled;
#endif
java_vm = args->javaVm;

version = args->version;
Expand Down
7 changes: 7 additions & 0 deletions src/Mono.Android/Java.Interop/TypeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,13 @@ static void n_Activate (IntPtr jnienv, IntPtr jclass, IntPtr typename_ptr, IntPt
TypeManager.n_Activate (jnienv, jclass, typename_ptr, signature_ptr, jobject, parameters_ptr);
}

#if NETCOREAPP
[UnmanagedCallersOnly]
static void n_Activate_mm (IntPtr jnienv, IntPtr jclass, IntPtr typename_ptr, IntPtr signature_ptr, IntPtr jobject, IntPtr parameters_ptr)
{
TypeManager.n_Activate (jnienv, jclass, typename_ptr, signature_ptr, jobject, parameters_ptr);
}
#endif
internal static Delegate GetActivateHandler ()
{
return TypeManager.GetActivateHandler ();
Expand Down
2 changes: 2 additions & 0 deletions src/Mono.Android/java/mono/android/TypeManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ public static void Activate (String typeName, String sig, Object instance, Objec

private static native void n_activate (String typeName, String sig, Object instance, Object[] parameterList);

//#MARSHAL_METHODS:START - do not remove or modify this line, it is required during application build
static {
String methods =
"n_activate:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;[Ljava/lang/Object;)V:GetActivateHandler\n" +
"";
mono.android.Runtime.register ("Java.Interop.TypeManager+JavaTypeManager, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", TypeManager.class, methods);
}
//#MARSHAL_METHODS:END - do not remove or modify this line, it is required during application build
}
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,9 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
<_ProtobufFormat Condition=" '$(AndroidPackageFormat)' == 'aab' ">True</_ProtobufFormat>
<_ProtobufFormat Condition=" '$(_ProtobufFormat)' == '' ">False</_ProtobufFormat>
<_Aapt2ProguardRules Condition=" '$(AndroidLinkTool)' != '' ">$(IntermediateOutputPath)aapt_rules.txt</_Aapt2ProguardRules>
<_OutputFileDir>$([System.IO.Path]::GetDirectoryName ('$(_PackagedResources)'))</_OutputFileDir>
</PropertyGroup>
<MakeDir Directories="$(_OutputFileDir)" Condition=" !Exists ('$(_OutputFileDir)') " />
<Aapt2Link
AndroidManifestFile="$(_AndroidManifestAbs)"
CompiledResourceFlatFiles="@(_CompiledFlatFiles)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,27 @@ They run in a context of an inner build with a single $(RuntimeIdentifier).
<FileWrites Include="@(_AotCompiledAssemblies)" />
<ResolvedFileToPublish
Include="@(_AotCompiledAssemblies)"
Condition=" '$(_AndroidUseMarshalMethods)' != 'True' "
ArchiveFileName="libaot-$([System.IO.Path]::GetFileNameWithoutExtension('%(_AotCompiledAssemblies.Identity)')).so"
/>
<_AotResolvedFileToPublish
Include="@(_AotCompiledAssemblies)"
Condition=" '$(_AndroidUseMarshalMethods)' == 'True' "
ArchiveFileName="libaot-$([System.IO.Path]::GetFileNameWithoutExtension('%(_AotCompiledAssemblies.Identity)')).so"
/>
</ItemGroup>
</Target>

<Target Name="_AndroidAotAndComputeFilesToPublishForRuntimeIdentifiers"
DependsOnTargets="_AndroidAot"
Returns="@(_AotResolvedFileToPublish)">
<ItemGroup>
<_AotResolvedFileToPublish Remove="@(_SourceItemsToCopyToPublishDirectory)" />
<_AotResolvedFileToPublish
Condition=" '%(_AotResolvedFileToPublish.RuntimeIdentifier)' == '' "
Update="@(_AotResolvedFileToPublish)"
RuntimeIdentifier="$(RuntimeIdentifier)"
/>
Comment on lines +66 to +71
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not following exactly how @(_AotResolvedFileToPublish) is used. Does some target use it later?

Is it possible that the libaot-*.so files don't actually make it to the .apk with these changes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is converted to ResolvedFileToPublish here https://github.com/xamarin/xamarin-android/pull/7351/files#diff-e2c60a31385c6fbadf9b9f439d3681ee357077bf3e66f181a0ddb02b9d98adf1R1668, while if it returned @(ResolvedFileToPublish), it would duplicate the items that were in the group before the target was invoked.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<Target Name="_RunAotForAllRIDs"
        Condition=" '$(_AndroidUseMarshalMethods)' == 'True' "
        Returns="@(ResolvedFileToPublish)">
  <MSBuild
      Projects="@(_ProjectToBuild)"
      BuildInParallel="$(_AndroidBuildRuntimeIdentifiersInParallel)"
      Targets="_AndroidAotAndComputeFilesToPublishForRuntimeIdentifiers">
    <Output TaskParameter="TargetOutputs" ItemName="ResolvedFileToPublish" />
  </MSBuild>
</Target>

The <Output TaskParameter="TargetOutputs"> expression doesn't care what is the name of items returned by the called target - it just takes the items and copies them with the new name specified in ItemName. And since we use _AotResolvedFileToPublish in the Returns attribute of the _AndroidAotAndComputeFilesToPublishForRuntimeIdentifiers target, we don't get duplicates of ResolvedFileToPublish

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I see it now. 👍

</ItemGroup>
</Target>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,13 @@ _ResolveAssemblies MSBuild target.
</CompileDependsOn>
</PropertyGroup>

<PropertyGroup>
<!-- When marshal methods are enabled, AOT needs to run after the GenerateJavaStubs task -->
<_RunAotMaybe Condition=" '$(_AndroidUseMarshalMethods)' != 'True' ">_AndroidAot</_RunAotMaybe>
</PropertyGroup>

<Target Name="_ComputeFilesToPublishForRuntimeIdentifiers"
DependsOnTargets="_FixupIntermediateAssembly;ResolveReferences;ComputeFilesToPublish;_AndroidAot"
DependsOnTargets="_FixupIntermediateAssembly;ResolveReferences;ComputeFilesToPublish;$(_RunAotMaybe)"
Returns="@(ResolvedFileToPublish)">
<ItemGroup>
<ResolvedFileToPublish Remove="@(_SourceItemsToCopyToPublishDirectory)" />
Expand Down
79 changes: 79 additions & 0 deletions src/Xamarin.Android.Build.Tasks/Tasks/CreateTypeManagerJava.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using System.IO;
using System.Reflection;
using System.Text;
using System;

using Microsoft.Android.Build.Tasks;
using Microsoft.Build.Framework;

namespace Xamarin.Android.Tasks
{
public class CreateTypeManagerJava : AndroidTask
{
public override string TaskPrefix => "CTMJ";

[Required]
public string ResourceName { get; set; }

[Required]
public string OutputFilePath { get; set; }

static readonly Assembly ExecutingAssembly = Assembly.GetExecutingAssembly ();

public override bool RunTask ()
{
string? content = ReadResource (ResourceName);

if (String.IsNullOrEmpty (content)) {
return false;
}

var result = new StringBuilder ();
bool ignoring = false;
foreach (string line in content.Split ('\n')) {
if (!ignoring) {
if (ignoring = line.StartsWith ("//#MARSHAL_METHODS:START", StringComparison.Ordinal)) {
continue;
}
result.AppendLine (line);
} else if (line.StartsWith ("//#MARSHAL_METHODS:END", StringComparison.Ordinal)) {
ignoring = false;
}
}

if (result.Length == 0) {
Log.LogDebugMessage ("TypeManager.java not generated, empty resource data");
return false;
}

using (var ms = new MemoryStream ()) {
using (var sw = new StreamWriter (ms)) {
sw.Write (result.ToString ());
sw.Flush ();

if (Files.CopyIfStreamChanged (ms, OutputFilePath)) {
Log.LogDebugMessage ($"Wrote resource {OutputFilePath}.");
} else {
Log.LogDebugMessage ($"Resource {OutputFilePath} is unchanged. Skipping.");
}
}
}

return !Log.HasLoggedErrors;
}

string? ReadResource (string resourceName)
{
using (var from = ExecutingAssembly.GetManifestResourceStream (resourceName)) {
if (from == null) {
Log.LogCodedError ("XA0116", Properties.Resources.XA0116, resourceName);
return null;
}

using (var sr = new StreamReader (from)) {
return sr.ReadToEnd ();
}
}
}
}
}
Loading