Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/man
diff options
context:
space:
mode:
authorMarek Habersack <grendel@twistedcode.net>2018-05-16 21:05:45 +0300
committerMarek Safar <marek.safar@gmail.com>2018-05-18 20:37:04 +0300
commit170e9442c976ed6cd4a499093e11a9e12e7368bb (patch)
tree09f34f6d51dec5966d601715d66876f900752a4a /man
parent0429856f02d380bab39ca3de596581efef0f4825 (diff)
mkbundle interop changes
mkbundle works by generating a small C source file which, in addition to embedded assemblies/configs/etc, contains a certain amount of code to initialize the bundle, uncompress the assemblies and set runtime options (e.g. AOT mode). This source code is generated based on a number of templates shipped as resources inside `mkbundle.exe` and is not part of any public, maintained API. The generated code contains calls to Mono runtime which work just fine when mkbundle is used to generate a desktop application bundle with the default template code. However, it breaks when a third party (like Xamarin.Android) embeds Mono runtime and loads it dynamically **after** the application is initialized. Such third parties must ensure that the bundle's startup code is able to access the Mono runtime functions it needs by providing pointers to them, loaded using e.g. the `dlsym` function. However, as the Mono calls are hard-coded into the generated source code, the third party needs to resort to search-and-replace methods (e.g. Xamarin.Android https://github.com/xamarin/xamarin-android/blob/62e7792ca52949f2fa213330d292865ad78d2bfa/src/Xamarin.Android.Build.Tasks/Tasks/MakeBundleNativeCodeExternal.cs#L159-L166) which are very fragile and prone to undetected breakage. One example of such breakage which slipped under the radar is https://github.com/xamarin/xamarin-android/issues/1651 which was caused by addition of the `mono_jit_set_aot_mode` call to the generated code. The change slipped under the radar and was discovered only after release. This commit attempts to make the situation better by establishing a sort of a code contract between "upstream" mkbundle and the third party. Since the template code is not "public" (nor should it be), the third party cannot simply include a header file with the API definitions. Instead, the idea here is to ensure that all and any Mono runtime calls needed by the template code are placed in a dispatch structure as pointers to functions and that the structure needs to be initialized by the embedding party before calling the `mono_mkbundle_init()` function. The third party is responsible for maintenance of its own version of the dispatch structure as well as for its initialization via the `initialize_mono_api` function in the template code. The generated code must include the third party's version of the structure, in place of the default one as shipped with `mkbundle`, and to make it possible this commit adds the `--mono-api-struct-path` mkbundle parameter which points to a file that's injected into the generated code, replacing the default structure definition. Following that, the `mono_mkbundle_init()` code calls the `validate_api_struct` function which checks each and every pointer in the structure for `null`, exiting the application with error if any `null` pointer is encountered. This (along with the `initialize_mono_api` function in the template) has the additional effect that if the third party's structure is incompatible with the default one a build error will happen, thus allowing early detection of obvious incompatibilities/omissions. As long as all the new Mono runtime calls are added to the structure, the above should make it possible for issues like the one linked to above to not happen in the future.
Diffstat (limited to 'man')
-rw-r--r--man/mkbundle.130
1 files changed, 30 insertions, 0 deletions
diff --git a/man/mkbundle.1 b/man/mkbundle.1
index 32fcbc6ccea..32f100be95d 100644
--- a/man/mkbundle.1
+++ b/man/mkbundle.1
@@ -271,6 +271,36 @@ This flag is mutually exlusive with
By default the mkbundle tool will download from a Mono server the
target runtimes, you can specify a different server to provide
cross-compiled runtimes.
+.TP
+.I "--mono-api-struct-path FILE"
+FILE points to a file with the definition of the \fIBundleMonoAPI\fP structure which contains the
+required pointers to various Mono API functions used throughout the generated code. This mechanism
+is meant to be used by third parties which embed the Mono runtime and dynamically load and initialize
+it as part of the application startup, in which case the Mono APIs will not be available for the shared
+library loader and the bundle will fail to work (one example of such an embedding third party is
+Xamarin.Android).
+
+After providing the definition FILE, the embedder must call the \fIvoid initialize_mono_api (const BundleMonoAPI *info)\fP
+function found in the generated code
+.B before
+calling \fIvoid mono_mkbundle_init ()\fP. The structure passed to \fIinitialize_mono_api\fP doesn't need
+to be dynamically allocated as its contents is copied to the local structure in the generated code and no
+pointer to the passed structure is retained or used after \fIinitialize_mono_api\fP returns.
+
+The list of pointers is not documented here. Instead, please look at the \fIbundle-mono-api.inc\fP file
+found in the mkbundle source directory in your Mono source tree (\fImcs/tools/mkbundle\fP) or in the Mono's
+GitHub repository, https://github.com/mono/mono/blob/master/mcs/tools/mkbundle/bundle-mono-api.inc
+
+Please note that your structure must match the one expected by your version of the Mono runtime.
+
+The file must also define the \fImkbundle_log_error\fP function with the following signature:
+
+.nf
+ static void mkbundle_log_error (const char *format, ...) {}
+.fi
+
+The function should implement logging API specific to the embedder.
+
.SH OLD EMBEDDING
.PP
The old embedding system compiles a small C stub that embeds the