-
Notifications
You must be signed in to change notification settings - Fork 538
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
[AOT] provide libc and libm stubs for correct linking when NDK is not used #7475
Conversation
Needed for proper linking of AOT libraries
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.
Looks ok to me.
Initially I was wondering about the escaping for the ldFlags being removed, but it was moved rather than re-moved :D
TBH, I was wondering about the same... :) |
I'm working on a test for this |
Also try another way of passing paths to the stub libs, hopefully it works
* main: Bump LLVM to 15.0.3 (dotnet#7425)
* main: Use Environment.SpecialFolder.UserProfile, not SpecialFolder.Personal (dotnet#7481) [dependabot] Fix automatic submodule updates (dotnet#7482)
* main: [readme] Be more explicit about support status. (dotnet#7494) Bump to dotnet/installer@d5520378 8.0.200-alpha.1.22511.1 (dotnet#7451) Bump external/android-api-docs from `52d8515` to `bfbe38e` (dotnet#7483) [dependabot] Update submodule ignore list (dotnet#7492)
if (!string.IsNullOrEmpty (LdFlags)) { | ||
aotOptions.Add ($"ld-flags={LdFlags}"); | ||
} | ||
|
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.
Do we also want to move the ld-name arg down here? I see there is a comment above about making sure both are always passed last.
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.
Not sure, to be honest. ld-name
is an argument which takes a simple value which doesn't appear to confuse the AOT parser. I think I'd leave it where it is, especially that everything seems to have worked fine after the ld-flags
repositioning.
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.
Small question above but otherwise LGTM, the test failures appear to also be occurring on main.
The |
* main: [Tests] Replace azurestorage with a github repo. (dotnet#7524) Bump to xamarin/Java.Interop/main@5318261 (dotnet#7502) [build] fix 8.0.100-alpha.1 version band (dotnet#7500) [monodroid] Disable loading of libLLVM at runtime (dotnet#7499) Bump to dotnet/installer@8c1708f 8.0.100-alpha.1.22526.2 (dotnet#7497)
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
* main: [xaprepare] use 8.0.100 version band for Mono workloads (dotnet#7530)
Context: 346a93301831047f8d09a477495973249c8acfc7
346a9330 made it possible to build and link AOT shared libraries
without having to have Android NDK available. However, it seems
that the produced shared libraries do not depend on the `libc` and
`libm` standard libraries, leading to runtime errors similar to:
D monodroid-assembly: monodroid_dlopen: hash match found, DSO name is 'libaot-Mono.Android.dll.so'
I monodroid-assembly: Trying to load shared library '/data/app/~~4kGTzxWG6HKO7nzyg6ryBg==/com.companyname.hellomaui.old-h8Jlutcvf8Dzfpuuq1ouUA==/lib/arm64/libaot-Mono.Android.dll.so'
I monodroid-assembly: Failed to load shared library '/data/app/~~4kGTzxWG6HKO7nzyg6ryBg==/com.companyname.hellomaui.old-h8Jlutcvf8Dzfpuuq1ouUA==/lib/arm64/libaot-Mono.Android.dll.so'. dlopen failed: cannot locate symbol "memset" referenced by "/data/app/~~4kGTzxWG6HKO7nzyg6ryBg==/com.companyname.hellomaui.old-h8Jlutcvf8Dzfpuuq1ouUA==/lib/arm64/libaot-Mono.Android.dll.so"...
This is caused by us not passing the `-lc` and `-lm` flags to the
linker (or full paths to the `libc.so` and `libm.so` libraries).
However, without the NDK available we do not have either of these
standard libraries to link against.
Fortunately, ELF shared libraries by default will resolve symbols
from anywhere in the process address space, so there is no need to
provide a `libc.so` which contains *all* public symbols. We can
instead build and use a "dummy"/"stub" version of `libc.so` and
`libm.so`, existing only so that the linker will add the appropriate
`NEEDED` entries and resolve symbols from those libraries.
Update `src/monodroid` to also produce "stub" `libc.so` and `libm.so`
native libraries, and update the `<Aot/>` task to add the equivalent
of `-L path/to/libstubs -lc -lm` to the AOT command-line.
This ensures that the resulting `.so` files now require `libc.so`:
$ llvm-readelf -a Mono.Android.dll.so | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libc.so]
0x0000000000000001 (NEEDED) Shared library: [libm.so] |
@dellis1972, @jonathanpeppers : do we have any existing on-device AOT tests? If so, how hard would it be to update them to verify that the |
We have this one which uses LLVM https://github.com/xamarin/xamarin-android/blob/1526df0115351020902710feeb9903c5387869ea/tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs#L682. Plus ANY MSBuildDeviceIntegration test which runs on dotnet and Release Mode is going to be a AOT test. |
var activityName = "MainActivity"; | ||
var logcatFilePath = Path.Combine (Root, builder.ProjectDirectory, "startup-logcat.log"); | ||
var failedToLoad = new List<string> (); | ||
bool appLaunched = MonitorAdbLogcat ((line) => { |
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.
@grendello, @dellis1972: how does this updated test look for verifying that .so
files were all loaded successfully?
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.
@grendello, @dellis1972 : my attempted unit test change failed. Is that because things aren't working properly, or because the test is looking for the wrong thing?
LLVM .so files not loaded:
11-21 23:05:25.104 10192 10192 I monodroid-assembly: Failed to load shared library '/data/app/com.xamarin.runwithinterpreterenabled-EBknjyBcFiejLCycXre3mw==/split_config.x86_64.apk!/lib/x86_64/UnnamedProject.dll.so'. dlopen failed: library "/data/app/com.xamarin.runwithinterpreterenabled-EBknjyBcFiejLCycXre3mw==/split_config.x86_64.apk!/lib/x86_64/UnnamedProject.dll.so" not found
11-21 23:05:25.105 10192 10192 I monodroid-assembly: Failed to load shared library 'UnnamedProject.dll.so'. dlopen failed: library "UnnamedProject.dll.so" not found
11-21 23:05:25.106 10192 10192 I monodroid-assembly: Failed to load shared library '/data/app/com.xamarin.runwithinterpreterenabled-EBknjyBcFiejLCycXre3mw==/split_config.x86_64.apk!/lib/x86_64/Mono.Android.dll.so'. dlopen failed: library "/data/app/com.xamarin.runwithinterpreterenabled-EBknjyBcFiejLCycXre3mw==/split_config.x86_64.apk!/lib/x86_64/Mono.Android.dll.so" not found
11-21 23:05:25.106 10192 10192 I monodroid-assembly: Failed to load shared library 'Mono.Android.dll.so'. dlopen failed: library "Mono.Android.dll.so" not found
11-21 23:05:25.107 10192 10192 I monodroid-assembly: Failed to load shared library '/data/app/com.xamarin.runwithinterpreterenabled-EBknjyBcFiejLCycXre3mw==/split_config.x86_64.apk!/lib/x86_64/Java.Interop.dll.so'. dlopen failed: library "/data/app/com.xamarin.runwithinterpreterenabled-EBknjyBcFiejLCycXre3mw==/split_config.x86_64.apk!/lib/x86_64/Java.Interop.dll.so" not found
11-21 23:05:25.108 10192 10192 I monodroid-assembly: Failed to load shared library 'Java.Interop.dll.so'. dlopen failed: library "Java.Interop.dll.so" not found
11-21 23:05:25.116 10192 10192 I monodroid-assembly: Failed to load shared library '/data/app/com.xamarin.runwithinterpreterenabled-EBknjyBcFiejLCycXre3mw==/split_config.x86_64.apk!/lib/x86_64/Mono.Android.Runtime.dll.so'. dlopen failed: library "/data/app/com.xamarin.runwithinterpreterenabled-EBknjyBcFiejLCycXre3mw==/split_config.x86_64.apk!/lib/x86_64/Mono.Android.Runtime.dll.so" not found
11-21 23:05:25.116 10192 10192 I monodroid-assembly: Failed to load shared library 'Mono.Android.Runtime.dll.so'. dlopen failed: library "Mono.Android.Runtime.dll.so" not found
11-21 23:05:25.122 10192 10192 I monodroid-assembly: Failed to load shared library '/data/app/com.xamarin.runwithinterpreterenabled-EBknjyBcFiejLCycXre3mw==/split_config.x86_64.apk!/lib/x86_64/System.Runtime.dll.so'. dlopen failed: library "/data/app/com.xamarin.runwithinterpreterenabled-EBknjyBcFiejLCycXre3mw==/split_config.x86_64.apk!/lib/x86_64/System.Runtime.dll.so" not found
11-21 23:05:25.122 10192 10192 I monodroid-assembly: Failed to load shared library 'System.Runtime.dll.so'. dlopen failed: library "System.Runtime.dll.so" not found
11-21 23:05:25.585 10192 10192 I monodroid-assembly: Failed to load shared library '/data/app/com.xamarin.runwithinterpreterenabled-EBknjyBcFiejLCycXre3mw==/split_config.x86_64.apk!/lib/x86_64/System.Console.dll.so'. dlopen failed: library "/data/app/com.xamarin.runwithinterpreterenabled-EBknjyBcFiejLCycXre3mw==/split_config.x86_64.apk!/lib/x86_64/System.Console.dll.so" not found
11-21 23:05:25.585 10192 10192 I monodroid-assembly: Failed to load shared library 'System.Console.dll.so'. dlopen failed: library "System.Console.dll.so" not found
Expected: 0
But was: 12
My guess is that Failed to load shared library
always appears, because not all assemblies are AOT'd. Which seems odd, as $(EnableLLVM)
=true is set; shouldn't that AOT all of them?
Also, those names look weird, e.g. System.Runtime.dll.so
can't be found. Shouldn't it be libaot-System.Runtime.dll.so
?
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.
Lines ending with not found
should be ignored, since it's perfectly fine that an AOT library wasn't packaged (e.g. if it was empty) or even created. However, testing for this properly would require finding a library that references one of the symbols in libc/libm and check if that library is loaded. However, I can't find any such library.
@jonathanpeppers originally found the problem in libaot-Mono.Android.dll.so
:
so I was testing LLVM with the .NET 7 RC, and noticed it was really slow...
Looking at full logcat I get:
10-18 23:55:17.844 20389 20389 D monodroid-assembly: monodroid_dlopen: hash match found, DSO name is 'libaot-Mono.Android.dll.so'
10-18 23:55:17.844 20389 20389 I monodroid-assembly: Trying to load shared library '/data/app/~~4kGTzxWG6HKO7nzyg6ryBg==/com.companyname.hellomaui.old-h8Jlutcvf8Dzfpuuq1ouUA==/lib/arm64/libaot-Mono.Android.dll.so'
10-18 23:55:17.844 20389 20389 I monodroid-assembly: Failed to load shared library '/data/app/~~4kGTzxWG6HKO7nzyg6ryBg==/com.companyname.hellomaui.old-h8Jlutcvf8Dzfpuuq1ouUA==/lib/arm64/libaot-Mono.Android.dll.so'. dlopen failed: cannot locate symbol "memset" referenced by "/data/app/~~4kGTzxWG6HKO7nzyg6ryBg==/com.companyname.hellomaui.old-h8Jlutcvf8Dzfpuuq1ouUA==/lib/arm64/libaot-Mono.Android.dll.so"...
Do you have an idea of what went wrong there?
Basically none of the AOT images are loading
And indeed, when you look at symbols referenced by libaot-Mono.Android.dll.so
from the apk (see the attached zip), you can see both the references and a text
segment:
$ llvm-nm -CD libaot-Mono.Android.dll.so | head -10
0000000000048450 W gc.safepoint_poll
U memset
00000000000d89d0 D mono_aot_file_info
00000000000a9f80 T p_101_plt_Java_Net_Proxy_get_NoProxy_llvm
00000000000aa00c T p_108_plt_Android_Runtime_JNIEnv_FindClass_string_llvm
00000000000aa020 T p_109_plt_Android_Runtime_JNIEnv_GetMethodID_intptr_string_string_llvm
00000000000aa034 T p_110_plt_Android_Runtime_JNIEnv_DeleteGlobalRef_intptr_llvm
00000000000aa070 T p_113_plt_Android_Runtime_JNIEnv_CallObjectMethod_intptr_intptr_llvm
00000000000aa0d4 T p_118_plt_Java_Net_HttpURLConnection__ctor_intptr_Android_Runtime_JniHandleOwnership_llvm
00000000000aa0e8 T p_119_plt_Android_Runtime_XAPeerMembers__ctor_string_System_Type_llvm
However, Mono.Android.dll.so
produced with XA/main has just the data mono_aot_file_info
symbol:
$ llvm-nm -CD Mono.Android.dll.so | head -10
0000000000062840 D mono_aot_file_info
@jonathanpeppers's test was with one of the NET7 RC builds, so perhaps something has changed inbetween? Also with regard to library names?
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.
With regards to names, I've just checked and we still rename the .so libraries to have the libaot
prefix when packaging:
$ zipinfo com.microsoft.net6.helloandroid-Signed.apk | grep 'lib/arm64-v8a/.*Mono\.Android.*' | head
-rwxr-xr-x 6.3 unx 4432 b- defX 22-Nov-22 09:08 lib/arm64-v8a/libaot-Mono.Android.Runtime.dll.so
-rwxr-xr-x 6.3 unx 208512 b- defX 22-Nov-22 09:08 lib/arm64-v8a/libaot-Mono.Android.dll.so
The reason you see the unprefixed names in error messages is that this is what MonoVM asks us to load, it isn't aware of the libaot
prefix. The way it works now, is that we generate hash entries for various mutations of the library name at build time and then use the hash to look up the "real" (packaged) name of the shared library, but the name in the error message is what was originally requested by Mono.
Consider this fragment of the environment.arm64-v8a.ll
file we generate:
@__DSOCacheEntry_name.1 = internal constant [27 x i8] c"libaot-Mono.Android.dll.so\00", align 1
; dso_cache
@dso_cache = local_unnamed_addr global [140 x %struct.DSOCacheEntry] [
; 0
%struct.DSOCacheEntry {
i64 120698629574877762, ; hash 0x1accec39cafe242, from name: Mono.Android
i8 0, ; ignore
i8* getelementptr inbounds ([27 x i8], [27 x i8]* @__DSOCacheEntry_name.1, i32 0, i32 0), ; name
i8* null; handle
},
; 54
%struct.DSOCacheEntry {
i64 8522025752637549819, ; hash 0x7644514538b12cfb, from name: aot-Mono.Android.dll.so
i8 0, ; ignore
i8* getelementptr inbounds ([27 x i8], [27 x i8]* @__DSOCacheEntry_name.1, i32 0, i32 0), ; name
i8* null; handle
},
; 61
%struct.DSOCacheEntry {
i64 8772604801161716260, ; hash 0x79be8d9660216224, from name: aot-Mono.Android
i8 0, ; ignore
i8* getelementptr inbounds ([27 x i8], [27 x i8]* @__DSOCacheEntry_name.1, i32 0, i32 0), ; name
i8* null; handle
},
; 115
%struct.DSOCacheEntry {
i64 15394198501530322172, ; hash 0xd5a32df9a590c4fc, from name: libaot-Mono.Android
i8 0, ; ignore
i8* getelementptr inbounds ([27 x i8], [27 x i8]* @__DSOCacheEntry_name.1, i32 0, i32 0), ; name
i8* null; handle
},
; 129
%struct.DSOCacheEntry {
i64 16768067971893542065, ; hash 0xe8b424faba51bcb1, from name: libaot-Mono.Android.dll.so
i8 0, ; ignore
i8* getelementptr inbounds ([27 x i8], [27 x i8]* @__DSOCacheEntry_name.1, i32 0, i32 0), ; name
i8* null; handle
},
; 131
%struct.DSOCacheEntry {
i64 17309541862275468045, ; hash 0xf037d89d25aecb0d, from name: Mono.Android.dll.so
i8 0, ; ignore
i8* getelementptr inbounds ([27 x i8], [27 x i8]* @__DSOCacheEntry_name.1, i32 0, i32 0), ; name
i8* null; handle
},
], align 8; end of 'dso_cache' array
Note that all of the entries map the various mutations of the name to the name that's actually in the package - the @__DSOCacheEntry_name.1
string. This speeds up look up, regardless of what name MonoVM passes to us but perhaps the error message should refer to the packaged name (although knowing what MonoVM requested is also valuable)
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.
Is the test passing because $(AndroidNdkDirectory)
is set and valid?
When I hit the original problem, I was building on Azure DevOps with an NDK in a non-standard location -- would be the same as not having an NDK installed at all.
I solved the problem by doing:
-p:AndroidNdkDirectory=$(ANDROID_NDK_HOME)
* main: (112 commits) [ci] Remove classic Mono.Android-Tests runs (dotnet#7778) $(AndroidPackVersionSuffix)=preview.2; net8 is 34.0.0-preview.2 (dotnet#7761) Localized file check-in by OneLocBuild Task (dotnet#7758) Bump to dotnet/installer@dec1209 8.0.100-alpha.1.23080.11 (dotnet#7755) LEGO: Merge pull request 7756 Localized file check-in by OneLocBuild (dotnet#7752) [Xamarin.Android.Build.Tasks] Fix issue where app will not install (dotnet#7719) Bump to dotnet/installer@779a644 8.0.100-alpha.1.23070.23 (dotnet#7728) LEGO: Merge pull request 7751 [Mono.Android] Wrap connection exceptions in HttpRequestException (dotnet#7661) [Mono.Android] Fix View.SystemUiVisibility enumification (dotnet#7730) Bump r8 from 3.3.75 to 4.0.48 (dotnet#7700) [monodroid] Prevent overlapped decompression of embedded assemblies (dotnet#7732) [xaprepare] Support arm64 emulator components (dotnet#7743) Bump SQLite to 3.40.1 (dotnet#7733) Bump to xamarin/xamarin-android-binutils/L_15.0.7-5.0.3@6721af4b (dotnet#7742) [monodroid] Replace `exit()` with `abort()` in native code (dotnet#7734) Bump to xamarin/Java.Interop/main@8a1ae57 (dotnet#7738) [build] bump `$(AndroidNet7Version)` (dotnet#7737) Bump to xamarin/Java.Interop/main@1366d99 (dotnet#7718) ...
* main: [ci] Remove some Classic XA test stages/jobs. (dotnet#7770)
* main: [tests] Bump NUnit versions to latest (dotnet#7802) [Microsoft.Android.Sdk.ILLink] target `net7.0` temporarily (dotnet#7803) [tests] `InstallAndroidDependenciesTest` can use `platform-tools` 34.0.0 (dotnet#7800) Bump to xamarin/Java.Interop/main@9e0a469 (dotnet#7797) [Xamarin.Android.Build.Tasks] FileWrites&libraryprojectimports.cache (dotnet#7780) Bump to dotnet/installer@d25a3bb 8.0.100-preview.2.23105.6 (dotnet#7769) [lgtm] Fix LGTM-reported issues (dotnet#1074) [ci] Report issues in the API docs build log (dotnet#7784)
* main: Add Unit Test for testOnly apps (dotnet#7637) [build] Only build the latest API level (dotnet#7786) [Xamarin.Android.Build.Tasks] Improve aapt2+file not found handling (dotnet#7644) [MSBuildDeviceIntegration] Fix duplicated test parameter (dotnet#7809)
* main: LEGO: Merge pull request 7825 Bump to xamarin/Java.Interop/main@bbaeda6f (dotnet#7799) Bump NDK to r25c (dotnet#7808) [Xamarin.Android.Build.Tests] Improve logcat logging in failed tests (dotnet#7816) [Mono.Android] Update api-compat reference file for current API-33 (dotnet#7822) Localized file check-in by OneLocBuild Task (dotnet#7820)
* main: Revert "Bump to dotnet/installer@d25a3bb 8.0.100-preview.2.23105.6 (dotnet#7769)" LEGO: Merge pull request 7828
* main: (22 commits) Bump to dotnet/installer@632ddca 8.0.100-preview.3.23128.1 (dotnet#7836) LEGO: Merge pull request 7852 [ci] Reduce overhead for MSBuildIntegration unit test jobs. (dotnet#7832) [ci] Allow dynamic`$(NuGetArtifactName)` values (dotnet#7848) [Xamarin.Android.Build.Tasks] guard `AutoImport.props` against empty values (dotnet#7837) [Mono.Android] Print type & member remapping info (dotnet#7844) [Mono.Android] Tweak AndroidMessageHandler behavior for WCF support (dotnet#7785) LEGO: Merge pull request 7845 Localized file check-in by OneLocBuild Task (dotnet#7842) [ci] Use compliance stage template (dotnet#7818) [build] pass `--skip-sign-check` to `dotnet workload` (dotnet#7840) Replace K4os.Hash.xxHash with System.IO.Hashing (dotnet#7831) $(AndroidPackVersionSuffix)=preview.3; net8 is 34.0.0-preview.3 (dotnet#7839) [Xamarin.Android.Build.Tasks] Remove support for mkbundle (dotnet#7772) [Xamarin.Android.Build.Tasks] `unable to open file as zip archive`? (dotnet#7759) [monodroid] Properly process satellite assemblies (dotnet#7823) Bump to xamarin/java.interop/main@77800dda (dotnet#7824) [ci] Use AZDO built-in parallelization strategy. (dotnet#7804) Bump to dotnet/installer@e3ab0b5 8.0.100-preview.2.23123.10 (dotnet#7813) [ci] Run nunit tests with stable .NET version (dotnet#7826) ...
* main: [AOT] provide libc and libm stubs so NDK is not required (dotnet#7475) [MSBuildDeviceIntegration] Handle Debugger errors (dotnet#7864) [ci] Remove separate SmokeTests jobs. (dotnet#7872) Bump to dotnet/installer@cddf8e6 8.0.100-preview.3.23163.4 (dotnet#7885) [Actions] Do not double quote the commit message (dotnet#7887) [Actions] Ensure that the commit message is valid json. (dotnet#7884) [github] Use ".NET Android", not "Android for .NET" (dotnet#7882) Bump `$(AndroidNet7Version)` (dotnet#7883) [ci] Install fewer Android SDK platforms on test agents. (dotnet#7874)
* main: [AOT] provide libc and libm stubs so NDK is not required (dotnet#7475) [MSBuildDeviceIntegration] Handle Debugger errors (dotnet#7864) [ci] Remove separate SmokeTests jobs. (dotnet#7872) Bump to dotnet/installer@cddf8e6 8.0.100-preview.3.23163.4 (dotnet#7885) [Actions] Do not double quote the commit message (dotnet#7887) [Actions] Ensure that the commit message is valid json. (dotnet#7884) [github] Use ".NET Android", not "Android for .NET" (dotnet#7882) Bump `$(AndroidNet7Version)` (dotnet#7883) [ci] Install fewer Android SDK platforms on test agents. (dotnet#7874)
* main: [AOT] provide libc and libm stubs so NDK is not required (dotnet#7475) [MSBuildDeviceIntegration] Handle Debugger errors (dotnet#7864) [ci] Remove separate SmokeTests jobs. (dotnet#7872) Bump to dotnet/installer@cddf8e6 8.0.100-preview.3.23163.4 (dotnet#7885) [Actions] Do not double quote the commit message (dotnet#7887) [Actions] Ensure that the commit message is valid json. (dotnet#7884)
Context: 346a933
346a933 made it possible to build and link AOT shared libraries without having to have Android NDK available.
However, it seems that the produced shared libraries do not depend on
libc
andlibm
standard libraries,leading to errors at runtime similar to:
This is caused by us not passing either
-lc
and-lm
flags to the linker (or full paths tolibc
andlibm
libraries).However, without NDK available we do not have neither of these standard libraries to link against. Fortunately, shared library
builds by default do not try to resolve all the symbols and so we can link AOT libraries against "dummy"/stub versions of
libc
andlibm
, making sure that the resulting binaries reference them properly:$ llvm-readelf -a Mono.Android.dll.so | grep NEEDED 0x0000000000000001 (NEEDED) Shared library: [libc.so] 0x0000000000000001 (NEEDED) Shared library: [libm.so]
This commit adds code to build the
libc
andlibm
stubs, whose paths are then passed during AOT build time to the linker.