Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[native] Runtime linking at app build time #9006

Draft
wants to merge 53 commits into
base: main
Choose a base branch
from

Conversation

grendello
Copy link
Contributor

No description provided.

@grendello grendello force-pushed the dev/grendel/runtime-link-at-build branch 4 times, most recently from bf5c35a to bfedf30 Compare June 12, 2024 19:08
@grendello grendello force-pushed the dev/grendel/runtime-link-at-build branch 4 times, most recently from 9a604d3 to 9fc5594 Compare June 27, 2024 19:41
@grendello grendello force-pushed the dev/grendel/runtime-link-at-build branch 3 times, most recently from 7f5c98e to 57ab585 Compare July 5, 2024 16:06
@grendello grendello force-pushed the dev/grendel/runtime-link-at-build branch 4 times, most recently from 58f17e2 to 6f5f5c6 Compare July 16, 2024 07:12
@grendello grendello force-pushed the dev/grendel/runtime-link-at-build branch 2 times, most recently from 68ab1b7 to da87011 Compare July 23, 2024 16:24
grendello added a commit that referenced this pull request Jul 24, 2024
Context: #9006

This commit prepares ground for dynamic native runtime linking at application build time by
moving code around and making it more modular, thus allowing the on-build linking of the 
runtime to work properly. 

In particular, this applies to the `p/invoke` handling code which is going to be different between the
pre-linked (and shipped) runtime and the one linked on demand during application build.  The difference
lies in the fact that on-demand build will scan the application for p/invoke usage (after trimming) and will
only include functions that are actually called from the managed land.   Results of the scan will be used to
generate LLVM IR code at build time that references the required functions, which will allow the native linker 
to remove the remaining ones. 

Changes implemented here can be committed to `main` and, possibly, released with .NET9
without changing how things currently work.
@grendello grendello force-pushed the dev/grendel/runtime-link-at-build branch 6 times, most recently from 5f35bf1 to 99baef4 Compare July 31, 2024 08:24
@grendello grendello force-pushed the dev/grendel/runtime-link-at-build branch from 99baef4 to 6d17643 Compare August 19, 2024 09:00
@grendello grendello force-pushed the dev/grendel/runtime-link-at-build branch 3 times, most recently from 9ed6397 to 4d17d92 Compare August 29, 2024 19:14
@grendello grendello force-pushed the dev/grendel/runtime-link-at-build branch from 92da875 to 813c444 Compare September 3, 2024 19:43
The "hello world" apps size decrease:

  * ~2 meg for XA
  * ~1.8 meg for MAUI
It seems `$(AndroidIncludeDebugSymbols)` isn't defined yet by the time
`src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets`
is evaluated, so we need to move `$(_AndroidEnableNativeRuntimeLinking)`
to src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets in
order to disable linking in Debug builds.
MonoVM requires `libunwind.a` on x86_64.  Until the requirement is
removed, we'll include the archive.

dotnet/runtime#107615
Otherwise `<FileWrites>` in `_CompileNativeAssemblySources` won't
actually get written to the cache and the `GenerateJavaStubsAndAssembly`
test fails.
They might contain nested types with interesting methods.

Doh.
Unconditionally disable dynamic linking in the AOT profiling test
Testing just a single configuration, it's enough.
@grendello grendello force-pushed the dev/grendel/runtime-link-at-build branch from 7503400 to 81a7369 Compare November 25, 2024 15:34
grendello added a commit to grendello/runtime that referenced this pull request Nov 25, 2024
In dotnet/android#9006 we are working on linking
the .NET for Android runtime dynamically at the application build time.
Linking involves all the BCL native libraries, including
`System.Security.Cryptography.Native.Android` and one of the goals is to
hide all the exported symbols used as p/invokes by the managed BCL
libraries.  This is because p/invoke calls are handled internally and,
with dynamic linking of the runtime, there is no longer any reason to
use `dlopen` and `dlsym` to look them up, they are all resolved
internally, at the link time.

Symbol hiding works fine thanks to the `--exclude-libs` `clang` flag,
which makes all the exported symbols in the indicated `.a` archives to
not be exported by the linker.  However,
`System.Security.Cryptography.Native.Android` is special in the sense
that it contains one symbol which must not be hidden,
`Java_net_dot_android_crypto_DotnetProxyTrustManager_verifyRemoteCertificate`.

The above function is a Java `native` method implementation, and it
requires that not only its name follows the Java JNI naming rules, but
that is also available for the JVM to look up using `dlsym`.

I tried using the `--export-dynamic-symbol` clang flag to
export **just** this function, but it doesn't appear to work no matter
where I put the flag in relation to reference to the `.a` archives.

Instead, the problem can be dealt with by putting the JNI function in a
separate static library, so that I can link it without changing symbol
visibility, while making all the
`System.Security.Cryptography.Native.Android` symbols invisible.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant