Skip to content

Commit 2a9ac6a

Browse files
radekdoulikjonpryor
authored andcommitted
[jnimarshalmethod-gen] Delete the temporary files (#301)
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.
1 parent a4a7fda commit 2a9ac6a

File tree

2 files changed

+46
-15
lines changed

2 files changed

+46
-15
lines changed

Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,6 @@ run-android: $(ATESTS)
159159
run-test-jnimarshal: bin/Test$(CONFIGURATION)/Java.Interop.Export-Tests.dll bin/Test$(CONFIGURATION)/$(JAVA_INTEROP_LIB)
160160
MONO_TRACE_LISTENER=Console.Out \
161161
$(RUNTIME) bin/$(CONFIGURATION)/jnimarshalmethod-gen.exe -v -L $(JI_MONO_LIB_PATH)mono/4.5 -L $(JI_MONO_LIB_PATH)mono/4.5/Facades "$<"
162-
$(RM) "$(basename $<)-JniMarshalMethods.dll"
163162
$(call RUN_TEST,$<)
164163

165164

tools/jnimarshalmethod-gen/App.cs

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,36 @@
1515

1616
namespace Xamarin.Android.Tools.JniMarshalMethodGenerator {
1717

18-
class App
18+
class App : MarshalByRefObject
1919
{
2020

2121
internal const string Name = "jnimarshalmethod-gen";
2222
static DirectoryAssemblyResolver resolver = new DirectoryAssemblyResolver (logger: (l, v) => { Console.WriteLine (v); }, loadDebugSymbols: true, loadReaderParameters: new ReaderParameters () { ReadSymbols = true });
2323
static Dictionary<string, TypeBuilder> definedTypes = new Dictionary<string, TypeBuilder> ();
2424
static public bool Debug;
2525
static public bool Verbose;
26+
static bool keepTemporary;
2627
static List<Regex> typeNameRegexes = new List<Regex> ();
28+
List<string> FilesToDelete = new List<string> ();
2729

2830
public static int Main (string [] args)
31+
{
32+
var domain = AppDomain.CreateDomain ("workspace");
33+
var app = (App)domain.CreateInstanceAndUnwrap (typeof (App).Assembly.FullName, typeof (App).FullName);
34+
35+
var assemblies = app.ProcessArguments (args);
36+
app.ProcessAssemblies (assemblies);
37+
var filesToDelete = app.FilesToDelete;
38+
39+
AppDomain.Unload (domain);
40+
41+
foreach (var path in filesToDelete)
42+
File.Delete (path);
43+
44+
return 0;
45+
}
46+
47+
List<string> ProcessArguments (string [] args)
2948
{
3049
var help = false;
3150
var options = new OptionSet {
@@ -39,6 +58,9 @@ public static int Main (string [] args)
3958
{ "d|debug",
4059
"Inject debug messages",
4160
v => Debug = true },
61+
{ "keeptemp",
62+
"Keep temporary *-JniMarshalMethod.dll files.",
63+
v => keepTemporary = true },
4264
{ "L=",
4365
"{DIRECTORY} to resolve assemblies from.",
4466
v => resolver.SearchDirectories.Add (v) },
@@ -53,24 +75,35 @@ public static int Main (string [] args)
5375
v => Verbose = true },
5476
};
5577

56-
var jvm = CreateJavaVM ();
57-
5878
var assemblies = options.Parse (args);
59-
if (help) {
79+
if (help || args.Length < 1) {
6080
options.WriteOptionDescriptions (Console.Out);
6181

62-
return 0;
82+
Environment.Exit (0);
83+
}
84+
85+
if (assemblies.Count < 1) {
86+
Error ("Please specify at least one ASSEMBLY to process.");
87+
Environment.Exit (2);
6388
}
6489

90+
return assemblies;
91+
}
92+
93+
void ProcessAssemblies (List<string> assemblies)
94+
{
95+
CreateJavaVM ();
96+
6597
var readWriteParameters = new ReaderParameters {
6698
AssemblyResolver = resolver,
6799
ReadSymbols = true,
68100
ReadWrite = true,
69101
};
102+
70103
foreach (var assembly in assemblies) {
71104
if (!File.Exists (assembly)) {
72105
Error ($"Path '{assembly}' does not exist.");
73-
return 1;
106+
Environment.Exit (1);
74107
}
75108

76109
resolver.SearchDirectories.Add (Path.GetDirectoryName (assembly));
@@ -81,19 +114,15 @@ public static int Main (string [] args)
81114
CreateMarshalMethodAssembly (assembly);
82115
} catch (Exception e) {
83116
Error ($"Unable to process assembly '{assembly}'\n{e.Message}\n{e}");
84-
return 1;
117+
Environment.Exit (1);
85118
}
86119
}
87-
88-
jvm.Dispose ();
89-
90-
return 0;
91120
}
92121

93-
static JniRuntime CreateJavaVM ()
122+
void CreateJavaVM ()
94123
{
95124
var builder = new JreRuntimeOptions ();
96-
return builder.CreateJreVM ();
125+
builder.CreateJreVM ();
97126
}
98127

99128
static JniRuntime.JniMarshalMemberBuilder CreateExportedMemberBuilder ()
@@ -119,7 +148,7 @@ static TypeBuilder GetTypeBuilder (ModuleBuilder mb, Type type)
119148
return tb;
120149
}
121150

122-
static void CreateMarshalMethodAssembly (string path)
151+
void CreateMarshalMethodAssembly (string path)
123152
{
124153
var assembly = Assembly.LoadFile (path);
125154

@@ -237,6 +266,9 @@ static void CreateMarshalMethodAssembly (string path)
237266
var dstAssembly = resolver.GetAssembly (destPath);
238267
var mover = new TypeMover (dstAssembly, ad, definedTypes, resolver);
239268
mover.Move ();
269+
270+
if (!keepTemporary)
271+
FilesToDelete.Add (dstAssembly.MainModule.FileName);
240272
}
241273

242274
static readonly MethodInfo Delegate_CreateDelegate = typeof (Delegate).GetMethod ("CreateDelegate", new[] {

0 commit comments

Comments
 (0)