From 61a8193453b9bca9f3cfa80182176d2c2ddf2ead Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Tue, 29 May 2018 23:06:00 +0200 Subject: [PATCH 1/2] [linker] Added PreserveJniMarshalMethods option This option makes preserving new marshal methods, generated by `jnimarshalmethod-gen.exe`, optional in the linker. It also introduces new `JniMarshalMethods` property to toggle building with generated marshal methods and will be used by following patches. It defaults to *False*. --- Documentation/guides/BuildProcess.md | 19 ++++++++++++++++++- .../MonoDroid.Tuner/AndroidLinkContext.cs | 16 ++++++++++++++++ .../Linker/MonoDroid.Tuner/Linker.cs | 3 ++- .../Linker/MonoDroid.Tuner/LinkerOptions.cs | 1 + .../MonoDroid.Tuner/MonoDroidMarkStep.cs | 12 ++++++++++-- .../Tasks/LinkAssemblies.cs | 4 ++++ .../Xamarin.Android.Build.Tasks.csproj | 1 + .../Xamarin.Android.Common.targets | 3 +++ 8 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AndroidLinkContext.cs diff --git a/Documentation/guides/BuildProcess.md b/Documentation/guides/BuildProcess.md index 85d0e3ed505..b63dc75b750 100644 --- a/Documentation/guides/BuildProcess.md +++ b/Documentation/guides/BuildProcess.md @@ -663,6 +663,23 @@ when packaing Release applications. See [Lint Help](http://www.androiddocs.com/tools/help/lint.html) for more details on the android `lint` tooling. +- **AndroidGenerateJniMarshalMethods** – A bool property which + enables generating of JNI marshal methods as part of the build + process. This greatly reduces the System.Reflection usage in the + binding helper code. + + By default this will be set to False. If the developers wish to use + the new JNI marshal methods feature, they can set + + True + + in their csproj. Alternatively provide the property on the command + line via + + /p:AndroidGenerateJniMarshalMethods=True + + **Experimental**. Added in Xamarin.Android 8.3. + ### Binding Project Build Properties The following MSBuild properties are used with @@ -761,7 +778,7 @@ resources. - **AndroidUseAapt2** – A bool property which allows the developer to control the use of the `aapt2` tool for packaging. By default this will be set to false and we will use `aapt`. - If the developer wishes too use the new `aapt2` functionality + If the developer wishes to use the new `aapt2` functionality they can set True diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AndroidLinkContext.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AndroidLinkContext.cs new file mode 100644 index 00000000000..47503b2965f --- /dev/null +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AndroidLinkContext.cs @@ -0,0 +1,16 @@ +using Mono.Linker; +using Mono.Cecil; + +namespace MonoDroid.Tuner +{ + public class AndroidLinkContext : LinkContext + { + public AndroidLinkContext (Pipeline pipeline, AssemblyResolver resolver) + : base (pipeline, resolver) {} + + public AndroidLinkContext (Pipeline pipeline, AssemblyResolver resolver, ReaderParameters readerParameters, UnintializedContextFactory factory) + : base (pipeline, resolver, readerParameters, factory) {} + + public bool PreserveJniMarshalMethods { get; set; } + } +} diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Linker.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Linker.cs index 89b7b408171..8bef4f076a7 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Linker.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/Linker.cs @@ -37,7 +37,7 @@ static void Run (Pipeline pipeline, LinkContext context) static LinkContext CreateLinkContext (LinkerOptions options, Pipeline pipeline, ILogger logger) { - var context = new LinkContext (pipeline, options.Resolver); + var context = new AndroidLinkContext (pipeline, options.Resolver); if (options.DumpDependencies) { var prepareDependenciesDump = context.Annotations.GetType ().GetMethod ("PrepareDependenciesDump", new Type[] {}); if (prepareDependenciesDump != null) @@ -51,6 +51,7 @@ static LinkContext CreateLinkContext (LinkerOptions options, Pipeline pipeline, context.SymbolReaderProvider = new DefaultSymbolReaderProvider (true); context.SymbolWriterProvider = new DefaultSymbolWriterProvider (); context.OutputDirectory = options.OutputDirectory; + context.PreserveJniMarshalMethods = options.PreserveJniMarshalMethods; return context; } diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/LinkerOptions.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/LinkerOptions.cs index d8a6af1ff74..8bd0992ef02 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/LinkerOptions.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/LinkerOptions.cs @@ -22,5 +22,6 @@ class LinkerOptions public bool DumpDependencies { get; set; } public string HttpClientHandlerType { get; set; } public string TlsProvider { get; set; } + public bool PreserveJniMarshalMethods { get; set; } } } diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MonoDroidMarkStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MonoDroidMarkStep.cs index 6ef16b20026..3b0de21ad5e 100644 --- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MonoDroidMarkStep.cs +++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/MonoDroidMarkStep.cs @@ -22,7 +22,7 @@ public override void Process (LinkContext context) marshalTypes.Clear (); base.Process (context); - if (UpdateMarshalTypes ()) + if (PreserveJniMarshalMethods () && UpdateMarshalTypes ()) base.Process (context); } @@ -196,6 +196,14 @@ bool UpdateMarshalRegisterMethod (MethodDefinition method, HashSet marke return true; } + bool PreserveJniMarshalMethods () + { + if (_context is AndroidLinkContext ac) + return ac.PreserveJniMarshalMethods; + + return false; + } + // If this is one of our infrastructure methods that has [Register], like: // [Register ("hasWindowFocus", "()Z", "GetHasWindowFocusHandler")], // we need to preserve the "GetHasWindowFocusHandler" method as well. @@ -207,7 +215,7 @@ protected override void DoAdditionalMethodProcessing (MethodDefinition method) return; MethodDefinition marshalMethod; - if (method.TryGetMarshalMethod (nativeMethod, signature, out marshalMethod)) { + if (PreserveJniMarshalMethods () && method.TryGetMarshalMethod (nativeMethod, signature, out marshalMethod)) { MarkMethod (marshalMethod); marshalTypes.Add (marshalMethod.DeclaringType); } diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssemblies.cs b/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssemblies.cs index 86d9015e703..954d17eaa58 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssemblies.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/LinkAssemblies.cs @@ -51,6 +51,8 @@ public class LinkAssemblies : Task, ML.ILogger public string TlsProvider { get; set; } + public bool PreserveJniMarshalMethods { get; set; } + IEnumerable GetRetainAssemblies (DirectoryAssemblyResolver res) { List retainList = null; @@ -83,6 +85,7 @@ public override bool Execute () Log.LogDebugMessage (" LinkOnlyNewerThan: {0}", LinkOnlyNewerThan); Log.LogDebugMessage (" HttpClientHandlerType: {0}", HttpClientHandlerType); Log.LogDebugMessage (" TlsProvider: {0}", TlsProvider); + Log.LogDebugMessage (" PreserveJniMarshalMethods: {0}", PreserveJniMarshalMethods); var rp = new ReaderParameters { InMemory = true, @@ -115,6 +118,7 @@ bool Execute (DirectoryAssemblyResolver res) options.DumpDependencies = DumpDependencies; options.HttpClientHandlerType = HttpClientHandlerType; options.TlsProvider = TlsProvider; + options.PreserveJniMarshalMethods = PreserveJniMarshalMethods; var skiplist = new List (); diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj index 0c0ef54ffb3..89133632461 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj @@ -575,6 +575,7 @@ PreserveNewest + <_MonoAndroidEnum Include="$(AndroidGeneratedClassDirectory)\Android.Content.PM.LaunchMode.cs" /> diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index 19fdd25d1ac..640a4043581 100755 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -303,6 +303,8 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved. <_InstantRunEnabled Condition=" '$(_InstantRunEnabled)' == '' ">False <_AndroidBuildPropertiesCache>$(IntermediateOutputPath)build.props + False + @@ -2057,6 +2059,7 @@ because xbuild doesn't support framework reference assemblies. LinkSkip="$(AndroidLinkSkip)" LinkDescriptions="@(LinkDescription)" ProguardConfiguration="$(_ProguardProjectConfiguration)" + PreserveJniMarshalMethods="$(AndroidGenerateJniMarshalMethods)" EnableProguard="$(AndroidEnableProguard)" DumpDependencies="$(LinkerDumpDependencies)" ResolvedAssemblies="@(ResolvedAssemblies->'$(MonoAndroidLinkerInputDir)%(Filename)%(Extension)')" From 6708210f46e2a349d468daf80834306f21ac57cb Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Wed, 30 May 2018 16:15:57 -0400 Subject: [PATCH 2/2] Fix version number. --- Documentation/guides/BuildProcess.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/guides/BuildProcess.md b/Documentation/guides/BuildProcess.md index b63dc75b750..9e3608c77ff 100644 --- a/Documentation/guides/BuildProcess.md +++ b/Documentation/guides/BuildProcess.md @@ -678,7 +678,8 @@ when packaing Release applications. /p:AndroidGenerateJniMarshalMethods=True - **Experimental**. Added in Xamarin.Android 8.3. + **Experimental**. Added in Xamarin.Android 8.4. + The default value is False. ### Binding Project Build Properties