diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/MakeBundleNativeCodeExternal.cs b/src/Xamarin.Android.Build.Tasks/Tasks/MakeBundleNativeCodeExternal.cs
index 916fc7f4ac6..698aeaab84c 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/MakeBundleNativeCodeExternal.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/MakeBundleNativeCodeExternal.cs
@@ -39,6 +39,9 @@ public class MakeBundleNativeCodeExternal : Task
public bool EmbedDebugSymbols { get; set; }
public bool KeepTemp { get; set; }
+ [Required]
+ public string BundleApiPath { get; set; }
+
[Output]
public ITaskItem [] OutputNativeLibraries { get; set; }
@@ -113,6 +116,8 @@ bool DoExecute ()
clb.AppendSwitch ("--nomain");
clb.AppendSwitch ("--i18n none");
clb.AppendSwitch ("--bundled-header");
+ clb.AppendSwitch ("--mono-api-struct-path");
+ clb.AppendFileNameIfNotNull (BundleApiPath);
clb.AppendSwitch ("--style");
clb.AppendSwitch ("linux");
clb.AppendSwitch ("-c");
@@ -157,22 +162,6 @@ bool DoExecute ()
return false;
}
- Log.LogDebugMessage ("[mkbundle] modifying mono_mkbundle_init");
- // make some changes in the mkbundle output so that it does not require libmonodroid.so
- var mkbundleOutput = new StringBuilder (File.ReadAllText (Path.Combine (outpath, "temp.c")));
-
- mkbundleOutput.Replace ("mono_jit_set_aot_mode", "mono_jit_set_aot_mode_ptr")
- .Replace ("void mono_mkbundle_init ()", "void mono_mkbundle_init (void (register_bundled_assemblies_func)(const MonoBundledAssembly **), void (register_config_for_assembly_func)(const char *, const char *), void (mono_jit_set_aot_mode_func) (int mode))")
- .Replace ("mono_register_config_for_assembly (\"", "register_config_for_assembly_func (\"")
- .Replace ("install_dll_config_files (void)", "install_dll_config_files (void (register_config_for_assembly_func)(const char *, const char *))")
- .Replace ("install_dll_config_files ()", "install_dll_config_files (register_config_for_assembly_func)")
- .Replace ("mono_register_bundled_assemblies(", "register_bundled_assemblies_func(")
- .Replace ("int nbundles;", "int nbundles;\n\n\tmono_jit_set_aot_mode_ptr = mono_jit_set_aot_mode_func;");
-
- mkbundleOutput.Insert (0, "void (*mono_jit_set_aot_mode_ptr) (int mode);\n");
-
- File.WriteAllText (Path.Combine (outpath, "temp.c"), mkbundleOutput.ToString ());
-
// then compile temp.c into temp.o and ...
clb = new CommandLineBuilder ();
@@ -182,6 +171,10 @@ bool DoExecute ()
// defined even if we don't use them
clb.AppendSwitch ($"-D__ANDROID_API__={level}");
+ // This is necessary because of the injected code, which is reused between libmonodroid
+ // and the bundle
+ clb.AppendSwitch ("-DANDROID");
+
clb.AppendSwitch ("-o");
clb.AppendFileNameIfNotNull (Path.Combine (outpath, "temp.o"));
if (!string.IsNullOrWhiteSpace (IncludePath)) {
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 89133632461..cfa2b5b5215 100644
--- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj
+++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj
@@ -574,6 +574,10 @@
LayoutBinding.cs
PreserveNewest
+
+ mkbundle-api.h
+ PreserveNewest
+
diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
index 80084f0bde8..9d93cbdbf64 100755
--- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
+++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
@@ -303,9 +303,8 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
<_AndroidSequencePointsMode Condition=" '$(_AndroidSequencePointsMode)' == ''">None
<_InstantRunEnabled Condition=" '$(_InstantRunEnabled)' == '' ">False
<_AndroidBuildPropertiesCache>$(IntermediateOutputPath)build.props
-
False
-
+ False
@@ -2688,12 +2687,14 @@ because xbuild doesn't support framework reference assemblies.
+ ToolPath="$(_MonoAndroidToolsDirectory)"
+ BundleApiPath="$(MSBuildThisFileDirectory)\mkbundle-api.h">
diff --git a/src/monodroid/jni/dylib-mono.c b/src/monodroid/jni/dylib-mono.c
index 8e1675a7042..67dd46b566d 100644
--- a/src/monodroid/jni/dylib-mono.c
+++ b/src/monodroid/jni/dylib-mono.c
@@ -139,7 +139,7 @@ int monodroid_dylib_mono_init (struct DylibMono *mono_imports, const char *libmo
LOAD_SYMBOL(mono_thread_create)
LOAD_SYMBOL(mono_thread_current)
LOAD_SYMBOL(mono_use_llvm)
-
+ LOAD_SYMBOL(mono_aot_register_module)
if (symbols_missing) {
log_fatal (LOG_DEFAULT, "Failed to load some Mono symbols, aborting...");
diff --git a/src/monodroid/jni/dylib-mono.h b/src/monodroid/jni/dylib-mono.h
index 25cb828adfd..9d95e4fb7a3 100644
--- a/src/monodroid/jni/dylib-mono.h
+++ b/src/monodroid/jni/dylib-mono.h
@@ -254,6 +254,7 @@ typedef MonoThread* (*monodroid_mono_thread_current_fptr) (void);
typedef void (*monodroid_mono_gc_disable_fptr) (void);
typedef void* (*monodroid_mono_install_assembly_refonly_preload_hook_fptr) (MonoAssemblyPreLoadFunc func, void *user_data);
typedef int (*monodroid_mono_runtime_set_main_args_fptr) (int argc, char* argv[]);
+typedef void (*mono_aot_register_module_fptr) (void* aot_info);
/* NOTE: structure members MUST NOT CHANGE ORDER. */
struct DylibMono {
@@ -342,6 +343,7 @@ struct DylibMono {
monodroid_mono_class_get_property_from_name_fptr mono_class_get_property_from_name;
monodroid_mono_domain_from_appdomain_fptr mono_domain_from_appdomain;
monodroid_mono_thread_current_fptr mono_thread_current;
+ mono_aot_register_module_fptr mono_aot_register_module;
};
MONO_API struct DylibMono* monodroid_dylib_mono_new (const char *libmono_path);
diff --git a/src/monodroid/jni/mkbundle-api.h b/src/monodroid/jni/mkbundle-api.h
new file mode 100644
index 00000000000..aa833a70b00
--- /dev/null
+++ b/src/monodroid/jni/mkbundle-api.h
@@ -0,0 +1,27 @@
+#ifndef __MKBUNDLE_API_H
+#define __MKBUNDLE_API_H
+typedef struct BundleMonoAPI
+{
+ void (*mono_register_bundled_assemblies) (const MonoBundledAssembly **assemblies);
+ void (*mono_register_config_for_assembly) (const char* assembly_name, const char* config_xml);
+ void (*mono_jit_set_aot_mode) (int mode);
+ void (*mono_aot_register_module) (void* aot_info);
+ void (*mono_config_parse_memory) (const char *buffer);
+ void (*mono_register_machine_config) (const char *config_xml);
+} BundleMonoAPI;
+
+#if ANDROID
+#include
+#include
+
+static void
+mkbundle_log_error (const char *format, ...)
+{
+ va_list ap;
+
+ va_start (ap, format);
+ __android_log_vprint (ANDROID_LOG_ERROR, "mkbundle", format, ap);
+ va_end (ap);
+}
+#endif // ANDROID
+#endif // __MKBUNDLE_API_H
diff --git a/src/monodroid/jni/monodroid-glue.c b/src/monodroid/jni/monodroid-glue.c
index 61c7d23a3a2..31ba3d6af67 100644
--- a/src/monodroid/jni/monodroid-glue.c
+++ b/src/monodroid/jni/monodroid-glue.c
@@ -71,6 +71,7 @@
#include "unzip.h"
#include "ioapi.h"
#include "monodroid-glue.h"
+#include "mkbundle-api.h"
#ifndef WINDOWS
#include "xamarin_getifaddrs.h"
@@ -693,6 +694,7 @@ get_libmonosgen_path ()
typedef void* (*mono_mkbundle_init_ptr) (void (*)(const MonoBundledAssembly **), void (*)(const char* assembly_name, const char* config_xml),void (*) (int mode));
mono_mkbundle_init_ptr mono_mkbundle_init;
+void (*mono_mkbundle_initialize_mono_api) (const BundleMonoAPI *info);
static void
setup_bundled_app (const char *libappso)
@@ -705,7 +707,11 @@ setup_bundled_app (const char *libappso)
log_fatal (LOG_BUNDLE, "bundled app initialization error: %s", dlerror ());
exit (FATAL_EXIT_CANNOT_LOAD_BUNDLE);
}
-
+
+ mono_mkbundle_initialize_mono_api = dlsym (libapp, "initialize_mono_api");
+ if (!mono_mkbundle_initialize_mono_api)
+ log_error (LOG_BUNDLE, "Missing initialize_mono_api in the application");
+
mono_mkbundle_init = dlsym (libapp, "mono_mkbundle_init");
if (!mono_mkbundle_init)
log_error (LOG_BUNDLE, "Missing mono_mkbundle_init in the application");
@@ -2647,6 +2653,20 @@ mono_runtime_init (char *runtime_args)
register_gc_hooks ();
+ if (mono_mkbundle_initialize_mono_api) {
+ BundleMonoAPI bundle_mono_api = {
+ .mono_register_bundled_assemblies = mono.mono_register_bundled_assemblies,
+ .mono_register_config_for_assembly = mono.mono_register_config_for_assembly,
+ .mono_jit_set_aot_mode = mono.mono_jit_set_aot_mode,
+ .mono_aot_register_module = mono.mono_aot_register_module,
+ .mono_config_parse_memory = mono.mono_config_parse_memory,
+ .mono_register_machine_config = mono.mono_register_machine_config,
+ };
+
+ /* The initialization function copies the struct */
+ mono_mkbundle_initialize_mono_api (&bundle_mono_api);
+ }
+
if (mono_mkbundle_init)
mono_mkbundle_init (mono.mono_register_bundled_assemblies, mono.mono_register_config_for_assembly, mono.mono_jit_set_aot_mode);