From c7678bcf8e43bb6b9d07b3bf04010a2dba7e60ef Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Thu, 19 Apr 2018 12:56:24 +0200 Subject: [PATCH] [jnimarshalmethod-gen] Delete the temporary files We don't want to leave the `*-JniMarshalMethods.dll` files behind, so we need to delete them, once the methods are moved back to the originating assemblies. Because the dynamic assembly builder needs to save the temporary assembly, we need it to use `AssemblyBuilderAccess.Save`, which means the assembly cannot be unloaded from the domain. Thus we do the work in separate `AppDomain` and unload the whole domain at the end, so that the temporary files are not locked anymore. A bit of refactoring was needed for that. There is also new `--keeptemp` option to enable the old behavior and keep the temporary files. And finally the help message is printed when no arguments supplied. Plus new error message in case no assemblies were specified. --- Makefile | 1 - tools/jnimarshalmethod-gen/App.cs | 60 +++++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 1caa2f69a..3abb82e15 100644 --- a/Makefile +++ b/Makefile @@ -159,7 +159,6 @@ run-android: $(ATESTS) run-test-jnimarshal: bin/Test$(CONFIGURATION)/Java.Interop.Export-Tests.dll bin/Test$(CONFIGURATION)/$(JAVA_INTEROP_LIB) MONO_TRACE_LISTENER=Console.Out \ $(RUNTIME) bin/$(CONFIGURATION)/jnimarshalmethod-gen.exe -v -L $(JI_MONO_LIB_PATH)mono/4.5 -L $(JI_MONO_LIB_PATH)mono/4.5/Facades "$<" - $(RM) "$(basename $<)-JniMarshalMethods.dll" $(call RUN_TEST,$<) diff --git a/tools/jnimarshalmethod-gen/App.cs b/tools/jnimarshalmethod-gen/App.cs index b098dac5e..beaf6311d 100644 --- a/tools/jnimarshalmethod-gen/App.cs +++ b/tools/jnimarshalmethod-gen/App.cs @@ -15,7 +15,7 @@ namespace Xamarin.Android.Tools.JniMarshalMethodGenerator { - class App + class App : MarshalByRefObject { internal const string Name = "jnimarshalmethod-gen"; @@ -23,9 +23,28 @@ class App static Dictionary definedTypes = new Dictionary (); static public bool Debug; static public bool Verbose; + static bool keepTemporary; static List typeNameRegexes = new List (); + List FilesToDelete = new List (); public static int Main (string [] args) + { + var domain = AppDomain.CreateDomain ("workspace"); + var app = (App)domain.CreateInstanceAndUnwrap (typeof (App).Assembly.FullName, typeof (App).FullName); + + var assemblies = app.ProcessArguments (args); + app.ProcessAssemblies (assemblies); + var filesToDelete = app.FilesToDelete; + + AppDomain.Unload (domain); + + foreach (var path in filesToDelete) + File.Delete (path); + + return 0; + } + + List ProcessArguments (string [] args) { var help = false; var options = new OptionSet { @@ -39,6 +58,9 @@ public static int Main (string [] args) { "d|debug", "Inject debug messages", v => Debug = true }, + { "keeptemp", + "Keep temporary *-JniMarshalMethod.dll files.", + v => keepTemporary = true }, { "L=", "{DIRECTORY} to resolve assemblies from.", v => resolver.SearchDirectories.Add (v) }, @@ -53,24 +75,35 @@ public static int Main (string [] args) v => Verbose = true }, }; - var jvm = CreateJavaVM (); - var assemblies = options.Parse (args); - if (help) { + if (help || args.Length < 1) { options.WriteOptionDescriptions (Console.Out); - return 0; + Environment.Exit (0); + } + + if (assemblies.Count < 1) { + Error ("Please specify at least one ASSEMBLY to process."); + Environment.Exit (2); } + return assemblies; + } + + void ProcessAssemblies (List assemblies) + { + CreateJavaVM (); + var readWriteParameters = new ReaderParameters { AssemblyResolver = resolver, ReadSymbols = true, ReadWrite = true, }; + foreach (var assembly in assemblies) { if (!File.Exists (assembly)) { Error ($"Path '{assembly}' does not exist."); - return 1; + Environment.Exit (1); } resolver.SearchDirectories.Add (Path.GetDirectoryName (assembly)); @@ -81,19 +114,15 @@ public static int Main (string [] args) CreateMarshalMethodAssembly (assembly); } catch (Exception e) { Error ($"Unable to process assembly '{assembly}'\n{e.Message}\n{e}"); - return 1; + Environment.Exit (1); } } - - jvm.Dispose (); - - return 0; } - static JniRuntime CreateJavaVM () + void CreateJavaVM () { var builder = new JreRuntimeOptions (); - return builder.CreateJreVM (); + builder.CreateJreVM (); } static JniRuntime.JniMarshalMemberBuilder CreateExportedMemberBuilder () @@ -119,7 +148,7 @@ static TypeBuilder GetTypeBuilder (ModuleBuilder mb, Type type) return tb; } - static void CreateMarshalMethodAssembly (string path) + void CreateMarshalMethodAssembly (string path) { var assembly = Assembly.LoadFile (path); @@ -237,6 +266,9 @@ static void CreateMarshalMethodAssembly (string path) var dstAssembly = resolver.GetAssembly (destPath); var mover = new TypeMover (dstAssembly, ad, definedTypes, resolver); mover.Move (); + + if (!keepTemporary) + FilesToDelete.Add (dstAssembly.MainModule.FileName); } static readonly MethodInfo Delegate_CreateDelegate = typeof (Delegate).GetMethod ("CreateDelegate", new[] {