-
Notifications
You must be signed in to change notification settings - Fork 546
Stop using dlopen/dlsym to load Mono symbols #3223
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Conversation
1c52d19
to
0b8fedf
Compare
@garuma: Heads up on this PR: it changes I can only assume that this will require changes on the Designer side. |
My initial feeling would be that as long as the right libmonosgen-2.0 is linked (aka the desktop version) we should be fine. We'll see what the integration tests say |
75f1ba4
to
c97af07
Compare
The below error might be related to the fact that we don't load the
|
2bfd22c
to
29517aa
Compare
29517aa
to
a2714fa
Compare
aea4dd5
to
dd208ea
Compare
dd208ea
to
aeae253
Compare
d00ccaa
to
a03df04
Compare
Context: dotnet/android#3223 Context: https://jenkins.mono-project.com/job/xamarin-android-pr-pipeline-debug/619/ Commit a30523e breaks the xamarin-android build, as it introduces new XML attributes to `class-parse` output which `Xamarin.Android.Tools.ApiXmlAdjuster` doesn't appreciate: Unhandled Exception: System.Exception: …/xamarin-android/bin/BuildDebug/api/api-10.xml.class-parse (16,7): Element 'class' has an unexpected attribute: 'source-file-name'. Expected attributes are: source-file-name at Xamarin.Android.Tools.ApiXmlAdjuster.XmlUtil.CheckExtraneousAttributes (System.String elementName, System.Xml.XmlReader reader, System.String[] expected) at Xamarin.Android.Tools.ApiXmlAdjuster.JavaApiLoaderExtensions.LoadTypeAttributes (Xamarin.Android.Tools.ApiXmlAdjuster.JavaType type, System.Xml.XmlReader reader, System.String[] otherAllowedAttributes) at Xamarin.Android.Tools.ApiXmlAdjuster.JavaApiLoaderExtensions.Load (Xamarin.Android.Tools.ApiXmlAdjuster.JavaClass kls, System.Xml.XmlReader reader) Update `Xamarin.Android.Tools.ApiXmlAdjuster` so that the new attributes introduced in a30523e are considered acceptable. Additionally, fix the error message so that it *actually* lists the "expected attributes", instead of repeating the *un*-expected attribute.
b43b28c
to
d580c54
Compare
Changes: dotnet/java-interop@be58159...60e85b0 Context: dotnet/java-interop#459 Updates `generator` so that all bound Java interfaces also implement `IJavaPeerable` in addition to `IJavaObject`, for eventual future C#8 Default Interface Member support. [generator] Remove extraneous slash when creating `.projitems`. [generator] Always use `XAPeerMembers` for `XAJavaInterop1` Drop dependency on DylibMono when building for Xamarin.Android (#3223) [jnienv-gen] fix p/invoke usage for .NET framework Add `jnimarshalmethod-gen.exe -r ASSEMBLY` option. Improve support for binding package-private interfaces. Parse `EnclosingMethod`, `SourceFile` attribute blobs. Emit events for `addListener(Listener,Handler)` pattern. Fix `jnimarshalmethod-gen.exe`-related build error introduced by having bound interfaces implement `IJavaPeerable`: Instance property 'PeerReference' is not defined for type 'Android.Widget.IListAdapter' Parameter name: propertyName System.ArgumentException: Instance property 'PeerReference' is not defined for type 'Android.Widget.IListAdapter' Parameter name: propertyName at System.Linq.Expressions.Expression.Property (System.Linq.Expressions.Expression expression, System.String propertyName) at Java.Interop.JavaPeerableValueMarshaler.CreateIntermediaryExpressionFromManagedExpression (Java.Interop.Expressions.JniValueMarshalerContext context, System.Linq.Expressions.ParameterExpression sourceValue) at Java.Interop.JavaPeerableValueMarshaler.CreateReturnValueFromManagedExpression (Java.Interop.Expressions.JniValueMarshalerContext context, System.Linq.Expressions.ParameterExpression sourceValue) Added `external/Java.Interop/build-tools/jnienv-gen.csproj` to `Xamarin.Android.sln` so that it builds properly.
e2f48e8
to
177a264
Compare
link_directories("${XA_LIB_TOP_DIR}/${HOST_BUILD_NAME}") | ||
include_directories("${DEFAULT_BIN_DIR}/include/${HOST_BUILD_NAME}") | ||
include_directories("${DEFAULT_BIN_DIR}/include/${HOST_BUILD_NAME}/eglib") | ||
include_directories("../../bin/${CONFIGURATION}/include/${HOST_BUILD_NAME}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should header files be extracted into $(topdir)/bin/Debug/include
. Or should bin/BuildDebug
be used? Though if the header files are part of the “mono bundle”, they’ll need to be in the former and not the latter...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer to keep them where the Mono archive puts them.
#include "debug.h" | ||
#include "util.h" | ||
#include "globals.h" | ||
#include "debug.hh" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why rename some files to be .hh
, but not others such as monodroid.h
? Why rename at all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The .hh
files contain C++ classes/syntax. This is for the benefit of text editors which use the extension to determine what type of file is being edited (it is also the case with some LSP servers). It follows the convention of naming C++
files with the .cc
or .cpp
convention. Without renaming the files, some editors/servers would treat the files as C
code thus greying out the C++
code (where #ifdef __cplusplus
is used, for instance) and/or show syntax errors.
@@ -10,7 +10,7 @@ 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_aot_register_module) (void** aot_info); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Er...what? Did we always have the wrong declaration? Did Mono change the declaration?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like we had it wrong from the beginning. The signature of the function in Mono is:
void mono_aot_register_module (gpointer *aot_info);
It was added in this commit to the C
code and in this commit to jit.h
using void*
instead of gpointer
.
@@ -2268,16 +2249,16 @@ extern "C" void monodroid_dylib_mono_free (DylibMono *mono_imports) | |||
|
|||
it should also accept libmono_path = nullptr parameter | |||
*/ | |||
extern "C" int monodroid_dylib_mono_init (DylibMono *mono_imports, const char *libmono_path) | |||
extern "C" int monodroid_dylib_mono_init (void *mono_imports, const char *libmono_path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Who/what is invoking this function that we need to keep it around?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only caller I found is in Java.Interop
's java-interop-gc-bridge-mono.cc
. It can probably be removed from that source, but there's no knowing if anyone else out there calls the function...
@@ -55,6 +55,7 @@ public static void LoadApplication (Context context, ApplicationInfo runtimePack | |||
// needed in the latest Android versions but is required in at least | |||
// API 16 and since there's no inherent negative effect of doing it, | |||
// we can do it unconditionally. | |||
System.loadLibrary("monosgen-2.0"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be cool if you could try to load Mono from externalDir
first. That way @brendanzagaeski and I can still drop in a hacked up libmonosgen-2.0
if we want to triage some Mono regression.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't do it unconditionally. The code has to work for all apps and access to externalDir
needs an Android permission to be granted (I think that holds true even for debug mode apps).
177a264
to
9cd7d8d
Compare
9cd7d8d
to
b97a957
Compare
5be7be2
to
6567425
Compare
Since the dawn of time `Xamarin.Android` (nee `MonoAndroid`) used `dlopen/dlsym` to load Mono runtime symbols that were required for the managed applications to work on Android. This was done due to the fact that there had been no way to reliably load shared libraries referenced by the XA runtime in earlier versions of Android. However, thanks to the recent switch to API level 16 as our lowest supported level, we are now able to simply preload the shared libraries we depend on and, thus, allow the system linker to resolve all the symbols when loading `libmonodroid.so`. This, in turn, means we can now directly link `libmonosgen-2.0` on all target platforms (including all of the supported host operating systems) and, what's also very important, include Mono headers directly in our source. This makes sure we don't divert in definitions of various macros and functions that we use accross our runtime and that we continue to work with any version of Mono shipped in the Mono SDK archives. This commit removes all traces of the `DylibMono` class and it also renames all the C++ header files to have the `.hh` extension, to mirror the `.cc` source file convention and cleary mark the C++ headers as such, as opposed to the handful of C headers (`.h`) we have in our tree.
6567425
to
dcc1207
Compare
For a very long time Xamarin.Android (nee `Mono for Android`) used **dlopen**(3)/**dlsym**(3) to load Mono runtime symbols that were required for the managed applications to work on Android. The more "conventional" solution would have been to change `libmonodroid.so` to have a link-time dependency on `libmonosgen-2.0.so`, instead of `dlopen(".../libmonosgen-2.0.so")` and corresponding `dlsym()` usage, but Android complicates matters by not reliably [loading dependencies from the same path][0]. However, thanks to the recent switch to API level 16 as our lowest supported API level, we are now able to simply preload the shared libraries we depend on and, thus, allow the system linker to resolve all the symbols when loading `libmonodroid.so` ("convention"). This, in turn, means we can now directly link against `libmonosgen-2.0` on all target platforms (including all of the supported host operating systems) and, what's also very important, include Mono headers directly in our source. This ensures we don't differ in definitions of various macros and functions that we use across our runtime and that we continue to work with any version of Mono shipped in the Mono SDK archives. Remove all traces of the `DylibMono` class and also rename all the C++ header files to have the `.hh` extension, to mirror the `.cc` source file convention and clearly mark the C++ headers as such, as opposed to the handful of C headers (`.h`) we have in our tree. [0]: https://stackoverflow.com/questions/11058898/loading-shared-libs-that-depend-on-other-shared-libs
Since the dawn of time
Xamarin.Android
(neeMonoAndroid
) useddlopen/dlsym
to load Mono runtime symbols that were required for the managed applications to
work on Android. This was done due to the fact that there had been no way to
reliably load shared libraries referenced by the XA runtime in earlier versions
of Android. However, thanks to the recent switch to API level 16 as our lowest
supported level, we are now able to simply preload the shared libraries we
depend on and, thus, allow the system linker to resolve all the symbols when
loading
libmonodroid.so
. This, in turn, means we can now directly linklibmonosgen-2.0
on all target platforms (including all of the supported hostoperating systems) and, what's also very important, include Mono headers
directly in our source. This makes sure we don't divert in definitions of
various macros and functions that we use accross our runtime and that we
continue to work with any version of Mono shipped in the Mono SDK archives.
This commit removes all traces of the
DylibMono
class and it also renames allthe C++ header files to have the
.hh
extension, to mirror the.cc
sourcefile convention and cleary mark the C++ headers as such, as opposed to the
handful of C headers (
.h
) we have in our tree.