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

LLVM libc++ Android C++ library support for Xamarin Android #4949

Closed
raghav-alevoor opened this issue Jul 21, 2020 · 6 comments · Fixed by #4958
Closed

LLVM libc++ Android C++ library support for Xamarin Android #4949

raghav-alevoor opened this issue Jul 21, 2020 · 6 comments · Fixed by #4958
Assignees
Labels
enhancement Proposed change to current functionality.

Comments

@raghav-alevoor
Copy link

The current build configs for Xamarin Android uses "libstdc++" runtime with the cmake configuration -DANDROID_STL="system"
This runtime library may be removed in a future release as discussed in android/ndk#744

Also, the LLVM libc++ is the standard C++ library since Android Lollipop. Full details https://developer.android.com/ndk/guides/cpp-support

The cmake configuration for Xamarin-Android build should also be updated to use libc++_shared.so with the configuration -DDANDROID_STL="c++_shared", so that the binaries are compatible with the current and future version of Android.

The Android Vendor Test Suite ,a requirement for Android compatibility testing, test case "VtsVndkDependencyTest" forbids
any linkage against "libstdc++" for ROM installed libraries. Because of the linkage to "libstdc++" in "libmonodroid" any ROM installed Xamarin apk will fail the test.

Can the C++ runtime libraries be updated to LLVM libc++ implementation from the current libstdc++.

Thank you.

Regards,
Raghav

@grendello
Copy link
Contributor

grendello commented Jul 22, 2020

Hey @raghav-alevoor we don't want to use the full libstdc++ in Xamarin.Android proper because of the size increase it would cause for all the APKs. Xamarin.Android's C++ code uses no libstdc++ types that require linking against the "full" library and we want it to stay this way for as long as it's possible. If, however, we were to use it, we would link it into the runtime statically. The reason is that the application developed with Xamarin.Android can ship its own version of libstdc++ and we'd end up with symbol conflicts and a situation of potentially disastrous side effects arising from two different versions of libstdc++ living in one process. On the other hand, we must link against something and currently this is the system STL implementation. Regarding the ROM requirement - I understand the issue, but I don't currently see a way to solve with the "general distribution" version of Xamarin.Android. However, I might consider adding a build option to use libc++ so that you, or anyone else who needs to include XA application in the ROMs, can build their own compliant version. I'll also experiment with static linking of the C++ standard library again to see if/how things have changed size-wise since last time I checked.

@grendello grendello self-assigned this Jul 22, 2020
@grendello
Copy link
Contributor

So, linking libc++ statically into our runtime makes it bigger by around 4-6 times, depending on the architecture. Also, a number of libc++ symbols are exported by the runtime, which is something we mustn't allow. I'll spend some time investigating this as we might not have a choice in the future but to link agains libc++, to see if I can work around the visible symbol issue.

@grendello
Copy link
Contributor

I don't see a way to hide the libc++ symbols without recompiling the STL. Also, the library is compiled with exceptions and RTII and all that baggage is carried into Xamarin.Android runtime even though we explicitly specify we don't use it. About the only way to go away from system I see now is to use ANDROID_STL=none which will cause the runtime to be built with -nostdinc++ -nostdlibc++ which is a bit of a pain because we do use some standard C++ headers even though we don't link the standard library.

raghav-alevoor added a commit to raghav-alevoor/xamarin-android that referenced this issue Jul 22, 2020
The libstdc++ runtime library may be removed in a future Android release
Android 10 VTS test prohibits linkage to library libstdc++.

This commit replaces libstdc++ STL linkage with NDK's libc++_static.
@raghav-alevoor
Copy link
Author

Hi @grendello, thanks for your comments. I've created a pull request #4952
Tested the locally built XA in an APK, the VTS test is also happy.

Thank you.

@grendello grendello added this to the Under Consideration milestone Jul 23, 2020
grendello added a commit to grendello/xamarin-android that referenced this issue Jul 23, 2020
Fixes: dotnet#4949
Context: dotnet#4952
Context: android/ndk#744

Xamarin.Android uses the "system" version of the C++ standard
library (which is, in reality, a very basic stub containing only weak
definitions of the `new` and `delete` operator functions) in order to
avoid possible conflicts with Xamarin.Android applications which could
make use of their own version of the C++ standard library. The conflict
would arise from the fact that the `libc++` library shipped with the
current versions of Android NDK is built in a way that would expose a
large number of its symbols which would conflict with any other `libc++`
used by the application.

Additionally, linking `libc++` into Xamarin.Android runtime would result
in a binary 4-6 times bigger than what we currently ship (when linking
statically) or by 6.2MB if the shared library version of `libc++` were
used.

The "system" version of `libstdc++` is deprecated in favor of `libc++`
and may be removed from the NDK in a near future.  In order to prepare
for this we need to switch to one of the supported STL implementations.
The static and dynamic linking options are not viable, as described
above, which leaves us with the `none` STL option.  However, using this
variety causes Android NDK's cmake toolchain to pass the `-nostdlib++
-nostdinc++` options to the compiler.  The first of them doesn't affect
us, since we don't use any types from the `libc++` library, but the
second of them causes the standard C++ files, which we do use, to not be
found.  This commit enables the `none` STL variety and works around the
`-nostdinc++` flag by detecting and specifying the include path to the
standard C++ headers manually on the command line.
jonpryor pushed a commit that referenced this issue Jul 23, 2020
Fixes: #4949
Context: #4952
Context: android/ndk#744

Xamarin.Android uses the "system" version of the C++ standard
library (which is, in reality, a very basic stub containing only weak
definitions of the `new` and `delete` operator functions) in order to
avoid possible conflicts with Xamarin.Android applications which could
make use of their own version of the C++ standard library.  The
conflict would arise from the fact that the `libc++` library shipped
with the current versions of Android NDK is built in a way that would
expose a large number of its symbols which would conflict with any
other `libc++` used by the application.

Additionally, linking `libc++` into Xamarin.Android runtime would
result in a binary 4-6 times bigger than what we currently ship (when
linking statically) or by 6.2MB if the shared library version of
`libc++` were used.

The "system" version of `libstdc++` is deprecated in favor of `libc++`
and may be removed from the NDK in a near future.  In order to prepare
for this we need to switch to one of the supported STL implementations.
The static and dynamic linking options are not viable, as described
above, which leaves us with the `none` STL option.  However, using this
variety causes Android NDK's `cmake` toolchain to pass the
`-nostdlib++ -nostdinc++` options to the compiler.  The first of them
doesn't affect us, since we don't use any types from the `libc++`
library, but the second of them causes the standard C++ files, which we
do use, to not be found.

Use the `none` STL variety and work around the `-nostdinc++` flag
by detecting and specifying the include path to the standard C++
headers manually on the command line.  This allows us to no longer link
against `libstdc++.so`, while continuing to use "header-file only"
functionality.
jonpryor pushed a commit that referenced this issue Aug 3, 2020
Fixes: #4949
Context: #4952
Context: android/ndk#744

Xamarin.Android uses the "system" version of the C++ standard
library (which is, in reality, a very basic stub containing only weak
definitions of the `new` and `delete` operator functions) in order to
avoid possible conflicts with Xamarin.Android applications which could
make use of their own version of the C++ standard library.  The
conflict would arise from the fact that the `libc++` library shipped
with the current versions of Android NDK is built in a way that would
expose a large number of its symbols which would conflict with any
other `libc++` used by the application.

Additionally, linking `libc++` into Xamarin.Android runtime would
result in a binary 4-6 times bigger than what we currently ship (when
linking statically) or by 6.2MB if the shared library version of
`libc++` were used.

The "system" version of `libstdc++` is deprecated in favor of `libc++`
and may be removed from the NDK in a near future.  In order to prepare
for this we need to switch to one of the supported STL implementations.
The static and dynamic linking options are not viable, as described
above, which leaves us with the `none` STL option.  However, using this
variety causes Android NDK's `cmake` toolchain to pass the
`-nostdlib++ -nostdinc++` options to the compiler.  The first of them
doesn't affect us, since we don't use any types from the `libc++`
library, but the second of them causes the standard C++ files, which we
do use, to not be found.

Use the `none` STL variety and work around the `-nostdinc++` flag
by detecting and specifying the include path to the standard C++
headers manually on the command line.  This allows us to no longer link
against `libstdc++.so`, while continuing to use "header-file only"
functionality.
@brendanzagaeski
Copy link
Contributor

Release status update

A new Preview version of Xamarin.Android has now been published that includes the fix for this item. The fix is not yet included in a Release version. I will update this item again when a Release version is available that includes the fix.

Fix included in Xamarin.Android SDK version 11.0.99.34.

Fix included on Windows in Visual Studio 2019 version 16.8 Preview 2. To try the Preview version that includes the fix, check for the latest updates in Visual Studio Preview.

Fix included on macOS in Visual Studio 2019 for Mac version 8.8 Preview 2. To try the Preview version that includes the fix, check for the latest updates on the Preview updater channel.

@brendanzagaeski
Copy link
Contributor

Release status update

A new Release version of Xamarin.Android has now been published that includes the fix for this item.

Fix included in Xamarin.Android SDK version 11.1.0.17.

Fix included on Windows in Visual Studio 2019 version 16.8. To get the new version that includes the fix, check for the latest updates or install the most recent release from https://visualstudio.microsoft.com/downloads/.

Fix included on macOS in Visual Studio 2019 for Mac version 8.8. To get the new version that includes the fix, check for the latest updates on the Stable updater channel.

@ghost ghost locked as resolved and limited conversation to collaborators Jun 4, 2022
@jpobst jpobst added the enhancement Proposed change to current functionality. label Dec 1, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement Proposed change to current functionality.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants