-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Fix native components build for Android #32800
Conversation
@janvorli, @jkotas, this is the full patch for testing. I will rebase this branch when other PRs are merged (and arcade is updated). git clone https://github.com/am11/runtime --single-branch --branch feature/android-build --depth 1
cd runtime
# create rootfs
./eng/common/cross/build-android-rootfs.sh arm64 # or arm
# build coreclr, libraries and installer
ROOTFS_DIR=$(realpath .tools/android-rootfs/android-ndk-r21/sysroot) ./build.sh \
--cross --arch arm64 --subsetCategory coreclr
ROOTFS_DIR=$(realpath .tools/android-rootfs/android-ndk-r21/sysroot) ./build.sh \
--cross --arch arm64 --subsetCategory libraries
ROOTFS_DIR=$(realpath .tools/android-rootfs/android-ndk-r21/sysroot) ./build.sh \
--cross --arch arm64 --subsetCategory installer |
eng/common/cross/toolchain.cmake
Outdated
set(CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN "${CROSS_ROOTFS}/usr") | ||
set(CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN "${CROSS_ROOTFS}/usr") | ||
set(CMAKE_ASM_COMPILER_EXTERNAL_TOOLCHAIN "${CROSS_ROOTFS}/usr") | ||
if("$ENV{__DistroRid}" MATCHES "android.*") |
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.
Would CMAKE_SYSTEM_NAME
work too (and CMAKE_SYSTEM_VERSION
few lines below)? I would like to try to avoid using env vars as much as possible in the CMake scripts.
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.
Ah, I see, these things are set in this script, so it doesn't make sense. Hmm.
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 wonder - isn't this information stored somewhere in the Android rootfs so that we could extract it from there?
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.
CMAKE_SYSTEM_NAME
At this stage, the value of this variable is Linux
. I have checked it by dumpping all cmake variables one line above (followed by a line message(FATAL_ERROR ">>>> ${CMAKE_SYSTEM_NAME}"
to fail fast) and the ones resembling android
are related to our build directory artifacts/obj..
etc.
eng/common/cross/toolchain.cmake
Outdated
endif() | ||
|
||
# extract platform number required by the NDK's toolchain | ||
string(REGEX REPLACE ".*\\.([0-9]+)-.*" "\\1" ANDROID_PLATFORM "$ENV{__DistroRid}") |
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.
@janvorli, ANDROID_PLATFORM
number is required by the NDK which expects caller to specify it before calling android.toolchain.cmake
. We have two options, echo
the value --cmakeargs -DANDROID_PLATFORM=$__ApiLevel
it in the last line of rootfs script: https://github.com/dotnet/runtime/blob/05d7a5b9d2c014dd9c16b1fb29be29986c0e58ca/eng/common/cross/build-android-rootfs.sh#L117-L120
or use this parse-number-from-RID approach, which I have used since it is self-contained and we are using RID in other parts of the build that we have written in $__ToolchainDir/sysroot/android_platform
.
@@ -57,6 +57,10 @@ else(CLR_CMAKE_HOST_WIN32) | |||
set(EXPORTS_LINKER_OPTION -Wl,-exported_symbols_list,${EXPORTS_FILE}) | |||
endif(CLR_CMAKE_TARGET_DARWIN) | |||
|
|||
if(CLR_CMAKE_TARGET_ANDROID AND CLR_CMAKE_HOST_ARCH_ARM) | |||
set(EXPORTS_LINKER_OPTION "${EXPORTS_LINKER_OPTION} -Wl,--no-warn-shared-textrel") | |||
endif() |
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.
https://android-developers.googleblog.com/2016/06/android-changes-for-ndk-developers.html - NDK picked up some shared textrels during the arm (32-bit) build of libcoreclr. Looking at some of your coreclr PRs, @janvorli, I understood that coreclr intends to comply with hardened kernels (at least in 64-bit). The (warning-as) error message was:
Warning: shared library text segment is not shareable
Maybe it could be investigated, as the rootcause might not be Android specific?
While testing these changes with #31701, I realized that I was only trying coreclr build with This does not affect libraries' native+managed and installer's native builds, which continue to succeed. The only part which is currently failing (with #31701 changes) is installer managed build, where ngen step picks up the wrong RID: #31701 (comment). |
The dependency PRs were merged and arcade has been updated. I have rebased my branch on top of master. There was a minor bug found in rootfs script in the docker container testing, which is fixed by dotnet/arcade#5003. The current workaround is to create an empty Thanks! |
@@ -114,7 +114,7 @@ int32_t SystemNative_EnumerateInterfaceAddresses(IPv4AddressFound onIpv4Found, | |||
freeifaddrs(headAddr); |
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.
@dotnet/ncl Could you please review the networking related changes?
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.
__u32 ethtool_cmd_speed()
function is not defined in NDK's header, but struct ethtool_cmd
has __u16 speed
and __u16 speed_hi
defined there.
I have ifdef'd it for Android and just used .speed
, ignoring the .speed_hi
as done by Linux distros https://github.com/torvalds/linux/blob/bd2463a/include/uapi/linux/ethtool.h#L125. Not sure if there is any down side to this approach on Android.
That's the main change in networking code for Android.
@@ -25,6 +25,7 @@ void GCToCLREventSink::FireDynamicEvent(const char* eventName, void* payload, ui | |||
|
|||
void GCToCLREventSink::FireGCStart_V2(uint32_t count, uint32_t depth, uint32_t reason, uint32_t type) | |||
{ | |||
#ifndef TARGET_ANDROID |
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 is this ifdefed out?
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.
Changed to #ifdef FEATURE_EVENT_TRACE
, as we have this feature disabled for Android (lttng-ust is not available).
With these fixes, native components of coreclr, installer and libraries build on Android rootfs.
Depends on: #32746 and dotnet/arcade#4915.