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

Beginnings of native Android build #110471

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
- src/tasks/MobileBuildTasks/Apple/AppleProject.cs
- https://github.com/dotnet/sdk repo > src/Installer/redist-installer/targets/GeneratePKG.targets
-->
<AndroidApiLevelMin>21</AndroidApiLevelMin>
<AndroidApiLevelMin>29</AndroidApiLevelMin>
<iOSVersionMin>12.2</iOSVersionMin>
<tvOSVersionMin>12.2</tvOSVersionMin>
<macOSVersionMin>12.0</macOSVersionMin>
Expand Down
7 changes: 7 additions & 0 deletions eng/Subsets.props
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,16 @@
<_subset Condition="'$(Subset)' == ''">+$(DefaultSubsets)+</_subset>
</PropertyGroup>

<!-- Android has a CoreCLR and Mono runtime. Default is mono. -->
<PropertyGroup Condition="'$(TargetsAndroid)' == 'true' and $(_subset.Contains('+clr.'))">
<DefaultPrimaryRuntimeFlavor>CoreCLR</DefaultPrimaryRuntimeFlavor>
<PrimaryRuntimeFlavor>CoreCLR</PrimaryRuntimeFlavor>
</PropertyGroup>

<PropertyGroup>
<RuntimeFlavor Condition="'$(TargetsMobile)' == 'true' and !$(_subset.Contains('+clr.nativeaotlibs+'))">Mono</RuntimeFlavor>
<RuntimeFlavor Condition="('$(TargetsMobile)' == 'true' or '$(TargetsLinuxBionic)' == 'true') and $(_subset.Contains('+clr.nativeaotlibs+'))">CoreCLR</RuntimeFlavor>
<RuntimeFlavor Condition="'$(TargetsAndroid)' == 'true' and $(_subset.Contains('+clr.'))">CoreCLR</RuntimeFlavor>
<RuntimeFlavor Condition="'$(RuntimeFlavor)' == '' and ($(_subset.Contains('+mono+')) or $(_subset.Contains('+mono.runtime+'))) and (!$(_subset.Contains('+clr+')) and !$(_subset.Contains('+clr.runtime+')))">Mono</RuntimeFlavor>
<RuntimeFlavor Condition="'$(RuntimeFlavor)' == ''">$(PrimaryRuntimeFlavor)</RuntimeFlavor>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion eng/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ initDistroRid()
local isCrossBuild="$3"

# Only pass ROOTFS_DIR if __DoCrossArchBuild is specified and the current platform is not an Apple platform (that doesn't use rootfs)
if [[ $isCrossBuild == 1 && "$targetOs" != "osx" && "$targetOs" != "ios" && "$targetOs" != "iossimulator" && "$targetOs" != "tvos" && "$targetOs" != "tvossimulator" && "$targetOs" != "maccatalyst" ]]; then
if [[ $isCrossBuild == 1 && "$targetOs" != "osx" && "$targetOs" != "android" && "$targetOs" != "ios" && "$targetOs" != "iossimulator" && "$targetOs" != "tvos" && "$targetOs" != "tvossimulator" && "$targetOs" != "maccatalyst" ]]; then
passedRootfsDir=${ROOTFS_DIR}
fi
initDistroRidGlobal "${targetOs}" "${targetArch}" "${passedRootfsDir}"
Expand Down
4 changes: 3 additions & 1 deletion eng/native/build-commons.sh
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ build_native()
fi

if [[ "$targetOS" == android || "$targetOS" == linux-bionic ]]; then
# Keep in sync with $(AndroidApiLevelMin) in Directory.Build.props in the repository rooot
local ANDROID_API_LEVEL=29
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@grendello has mentioned in #110470 that even API level 28 is unfortunate and that we will want to support older API level, e.g. the originally used level 21.
So I wonder if moving to the level 29 is a good thing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not good in the long term and is something we should fix. Moving it to 29 for now allows us to not have to deal with emulated TLS usage.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless we can fix it now, I don't think this should block progress. We can do it sometime down the road.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In perspective, this would drop 12.8% of the devices (with API level from 21 to 29) according to https://apilevels.com/

Then again:
Level 21 is Android 5 and 6 years EOL
Level 29 is Android 10 and 2 years EOL (https://endoflife.date/android)
Level 34 or higher is necessary to publish apps to the Play Store (https://developer.android.com/google/play/requirements/target-sdk)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I can make the emulated TLS work without too much hassle. The question though is if we are worried about the perf implications of the emulated TLS vs the standard TLS and thus we would like to end up having support for both.

if [[ -z "$ANDROID_NDK_ROOT" ]]; then
echo "Error: You need to set the ANDROID_NDK_ROOT environment variable pointing to the Android NDK root."
exit 1
Expand All @@ -87,7 +89,7 @@ build_native()
cmakeArgs="-C $__RepoRootDir/eng/native/tryrun.cmake $cmakeArgs"

# keep ANDROID_PLATFORM in sync with SetOSTargetMinVersions in the root Directory.Build.props
cmakeArgs="-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake -DANDROID_PLATFORM=android-21 $cmakeArgs"
cmakeArgs="-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake -DANDROID_PLATFORM=android-${ANDROID_API_LEVEL} -DANDROID_NATIVE_API_LEVEL=${ANDROID_API_LEVEL} $cmakeArgs"

# Don't try to set CC/CXX in init-compiler.sh - it's handled in android.toolchain.cmake already
__Compiler="default"
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/.nuget/coreclr-packages.proj
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
<ProjectReference Include="ILCompiler.Reflection.ReadyToRun.Experimental\ILCompiler.Reflection.ReadyToRun.Experimental.pkgproj" />
</ItemGroup>

<ItemGroup Condition="'$(RuntimeFlavor)' == 'CoreCLR'">
<ItemGroup Condition="'$(RuntimeFlavor)' == 'CoreCLR' and '$(TargetsAndroid)' != 'true' ">
<ProjectReference Include="Microsoft.NETCore.TestHost\Microsoft.NETCore.TestHost.proj" />
</ItemGroup>

<ItemGroup>
<ItemGroup Condition=" '$(TargetsAndroid)' != 'true' ">
<ProjectReference Include="Microsoft.NETCore.ILAsm\Microsoft.NETCore.ILAsm.proj" />
<ProjectReference Include="Microsoft.NETCore.ILDAsm\Microsoft.NETCore.ILDAsm.proj" />
</ItemGroup>
Expand Down
6 changes: 4 additions & 2 deletions src/coreclr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,10 @@ if(NOT CLR_CMAKE_HOST_MACCATALYST AND NOT CLR_CMAKE_HOST_IOS AND NOT CLR_CMAKE_H
add_subdirectory(utilcode)
add_subdirectory(inc)

add_subdirectory(ilasm)
add_subdirectory(ildasm)
if (NOT CLR_CMAKE_TARGET_ANDROID)
add_subdirectory(ilasm)
add_subdirectory(ildasm)
endif(NOT CLR_CMAKE_TARGET_ANDROID)
add_subdirectory(gcinfo)
add_subdirectory(jit)
add_subdirectory(vm)
Expand Down
9 changes: 4 additions & 5 deletions src/coreclr/inc/crosscomp.h
Original file line number Diff line number Diff line change
Expand Up @@ -696,15 +696,15 @@ typedef struct _T_KNONVOLATILE_CONTEXT_POINTERS {
#define DAC_CS_NATIVE_DATA_SIZE 24
#elif defined(TARGET_FREEBSD) && defined(TARGET_ARM64)
#define DAC_CS_NATIVE_DATA_SIZE 24
#elif defined(TARGET_LINUX) && defined(TARGET_ARM)
#elif (defined(TARGET_LINUX) || defined(TARGET_ANDROID)) && defined(TARGET_ARM)
#define DAC_CS_NATIVE_DATA_SIZE 80
#elif defined(TARGET_LINUX) && defined(TARGET_ARM64)
#elif (defined(TARGET_LINUX) || defined(TARGET_ANDROID)) && defined(TARGET_ARM64)
#define DAC_CS_NATIVE_DATA_SIZE 104
#elif defined(TARGET_LINUX) && defined(TARGET_LOONGARCH64)
#define DAC_CS_NATIVE_DATA_SIZE 96
#elif defined(TARGET_LINUX) && defined(TARGET_X86)
#elif (defined(TARGET_LINUX) || defined(TARGET_ANDROID)) && defined(TARGET_X86)
#define DAC_CS_NATIVE_DATA_SIZE 76
#elif defined(TARGET_LINUX) && defined(TARGET_AMD64)
#elif (defined(TARGET_LINUX) || defined(TARGET_ANDROID)) && defined(TARGET_AMD64)
#define DAC_CS_NATIVE_DATA_SIZE 96
#elif defined(TARGET_LINUX) && defined(TARGET_S390X)
#define DAC_CS_NATIVE_DATA_SIZE 96
Expand Down Expand Up @@ -748,4 +748,3 @@ struct T_CRITICAL_SECTION {
#else
#define T_CRITICAL_SECTION CRITICAL_SECTION
#endif

3 changes: 3 additions & 0 deletions src/coreclr/minipal/Unix/doublemapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ bool VMToOSInterface::CreateDoubleMemoryMapper(void** pHandle, size_t *pMaxExecu
int fd = -1;
#endif

#ifndef TARGET_ANDROID
// Bionic doesn't have shm_{open,unlink}
// POSIX fallback
if (fd == -1)
{
Expand All @@ -64,6 +66,7 @@ bool VMToOSInterface::CreateDoubleMemoryMapper(void** pHandle, size_t *pMaxExecu
fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
shm_unlink(name);
}
#endif // !TARGET_ANDROID

if (fd == -1)
{
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/pal/src/configure.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -936,7 +936,8 @@ elseif(CLR_CMAKE_TARGET_HAIKU)
set(DEADLOCK_WHEN_THREAD_IS_SUSPENDED_WHILE_BLOCKED_ON_MUTEX 0)
set(HAVE_SCHED_OTHER_ASSIGNABLE 1)
else() # Anything else is Linux
if(NOT HAVE_LTTNG_TRACEPOINT_H AND FEATURE_EVENT_TRACE)
# LTTNG is not available on Android, so don't error out
if(NOT HAVE_LTTNG_TRACEPOINT_H AND NOT CLR_CMAKE_TARGET_ANDROID AND FEATURE_EVENT_TRACE)
unset(HAVE_LTTNG_TRACEPOINT_H CACHE)
message(FATAL_ERROR "Cannot find liblttng-ust-dev. Try installing liblttng-ust-dev (or the appropriate packages for your platform)")
endif()
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/pal/src/eventprovider/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
set(EVENT_MANIFEST ${VM_DIR}/ClrEtwAll.man)

if(CLR_CMAKE_HOST_LINUX)
# TODO: LTTNG is not supported on Android. We need a solution.
if(CLR_CMAKE_HOST_LINUX AND NOT CLR_CMAKE_TARGET_ANDROID)
add_subdirectory(lttngprovider)
else()
add_subdirectory(dummyprovider)
Expand Down
16 changes: 12 additions & 4 deletions src/coreclr/runtime.proj
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,24 @@
<ItemGroup Condition="('$(TargetsAndroid)' == 'true' or '$(TargetsLinuxBionic)' == 'true') and '$(ANDROID_NDK_ROOT)' != ''">
<_CoreClrBuildArg Include="-DCMAKE_TOOLCHAIN_FILE=$(ANDROID_NDK_ROOT)/build/cmake/android.toolchain.cmake"/>
<_CoreClrBuildArg Include="-DANDROID_NDK=$(ANDROID_NDK_ROOT)"/>
<_CoreClrBuildArg Include="-DANDROID_STL=none"/>
<_CoreClrBuildArg Include="-DANDROID_CPP_FEATURES=&quot;no-rtti no-exceptions&quot;"/>
<_CoreClrBuildArg Include="-DANDROID_STL=c++_static"/>
<_CoreClrBuildArg Include="-DANDROID_CPP_FEATURES=&quot;no-rtti exceptions&quot;"/>
Comment on lines -81 to +82
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this affect size of native AOT runtime packs? (Build with ./build.sh -ci -arch x64 -os linux-bionic -c Release /p:DotNetBuildRuntimeNativeAOTRuntimePack=true and check the size of libRuntime.WorkstationGC.a). We'll likely have to move this part of configuration someplace else, native AOT is the most size sensitive workload we have. Native AOT doesn't need C++ runtime library and doesn't need exceptions.

<_CoreClrBuildArg Include="-DANDROID_PLATFORM=android-$(AndroidApiLevelMin)"/>
<_CoreClrBuildArg Include="-DANDROID_NATIVE_API_LEVEL=$(AndroidApiLevelMin)"/>
<_CoreClrBuildArg Condition="'$(Platform)' == 'arm64'" Include="-DANDROID_ABI=arm64-v8a" />
<_CoreClrBuildArg Condition="'$(Platform)' == 'arm'" Include="-DANDROID_ABI=armeabi-v7a" />
<_CoreClrBuildArg Condition="'$(Platform)' == 'x86'" Include="-DANDROID_ABI=x86" />
<_CoreClrBuildArg Condition="'$(Platform)' == 'x64'" Include="-DANDROID_ABI=x86_64" />

<!-- No LTTNG on Android -->
<_CoreClrBuildArg Include="-cmakeargs -DFEATURE_EVENT_TRACE=0"/>
<!--
TODO: No LTTNG on Android, it's disabled at the eventprovider level. Will need an answer.
Disabling FEATURE_EVENT_TRACE is too wide.
-->
<!--
Unsure if something like this is actually defined. We need this to differentiate between
features that are enabled in mono android, but not in coreclr.
-->
<_CoreClrBuildArg Include="-cmakeargs -DRUNTIME_CORECLR=1" />
</ItemGroup>

<PropertyGroup>
Expand Down
22 changes: 19 additions & 3 deletions src/native/corehost/apphost/static/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@ set(HEADERS
../../fxr_resolver.h
)

add_compile_definitions(NATIVE_LIBS_EMBEDDED)
# TODO: Android uses a separate System.Security.Cryptography lib that does not have
# the exported functions the singlefilehost expects.
# Figure out how that's going to work and turn this back on.
if (NOT CLR_CMAKE_TARGET_ANDROID)
add_compile_definitions(NATIVE_LIBS_EMBEDDED)
endif()

include(../../fxr/files.cmake)
include(../../hostpolicy/files.cmake)
Expand Down Expand Up @@ -169,10 +174,21 @@ else()

System.Globalization.Native-Static
System.IO.Compression.Native-Static
System.Net.Security.Native-Static
System.Native-Static
System.Security.Cryptography.Native.OpenSsl-Static
)

if(NOT CLR_CMAKE_TARGET_ANDROID)
list(APPEND NATIVE_LIBS
System.Net.Security.Native-Static
System.Security.Cryptography.Native.OpenSsl-Static
)
else()
list(APPEND NATIVE_LIBS
System.Security.Cryptography.Native.Android-Static
)
endif()

list(APPEND NATIVE_LIBS
coreclrpal_dac
corguids
dbgutil
Expand Down
4 changes: 3 additions & 1 deletion src/native/eventpipe/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ check_symbol_exists(
HAVE_ACCEPT4)

# Use TCP for EventPipe on mobile platforms
if (CLR_CMAKE_HOST_IOS OR CLR_CMAKE_HOST_TVOS OR CLR_CMAKE_HOST_ANDROID)
#
# TODO: Resolve TCP/IP EventPipe support on CoreCLR Android
if (CLR_CMAKE_HOST_IOS OR CLR_CMAKE_HOST_TVOS OR (CLR_CMAKE_HOST_ANDROID AND NOT RUNTIME_CORECLR))
set(FEATURE_PERFTRACING_PAL_TCP 1)
set(FEATURE_PERFTRACING_DISABLE_DEFAULT_LISTEN_PORT 1)
endif()
Expand Down
9 changes: 9 additions & 0 deletions src/native/external/libunwind_extras/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ add_definitions(-DPACKAGE_STRING="")
add_definitions(-DPACKAGE_BUGREPORT="")
add_definitions(-DHAVE_DL_ITERATE_PHDR=1)



if(CLR_CMAKE_HOST_UNIX)
if (CLR_CMAKE_HOST_ARCH_AMD64)
set(arch x86_64)
Expand Down Expand Up @@ -165,12 +167,19 @@ if(CLR_CMAKE_HOST_WIN32)
set_source_files_properties(${LIBUNWIND_SOURCES} PROPERTIES COMPILE_FLAGS /TC) # compile all files as C
endif(CLR_CMAKE_HOST_WIN32)

if(CLR_CMAKE_TARGET_ANDROID)
# Instead of patching libunwind, don't treat the handful of warnings it has as errors
add_compile_options(-Wno-error)
endif()

if(CLR_CMAKE_HOST_UNIX)
if(CLR_CMAKE_HOST_OSX)
add_library(libunwind_dac OBJECT ${LIBUNWIND_SOURCES})
else()
add_library(libunwind OBJECT ${LIBUNWIND_SOURCES})
endif(CLR_CMAKE_HOST_OSX)


else(CLR_CMAKE_HOST_UNIX)
set_source_files_properties(${CLR_DIR}/pal/src/exception/remote-unwind.cpp PROPERTIES COMPILE_FLAGS /TP INCLUDE_DIRECTORIES ${CLR_DIR}/inc)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,8 @@ target_link_libraries(System.Security.Cryptography.Native.Android
set_target_properties(System.Security.Cryptography.Native.Android PROPERTIES OUTPUT_NAME "System.Security.Cryptography.Native.Android")
set_target_properties(System.Security.Cryptography.Native.Android-Static PROPERTIES OUTPUT_NAME "System.Security.Cryptography.Native.Android")

install_with_stripped_symbols (System.Security.Cryptography.Native.Android PROGRAMS .)
install (TARGETS System.Security.Cryptography.Native.Android-Static DESTINATION .)
if (GEN_SHARED_LIB)
install_with_stripped_symbols (System.Security.Cryptography.Native.Android PROGRAMS .)
endif()

install (TARGETS System.Security.Cryptography.Native.Android-Static DESTINATION ${STATIC_LIB_DESTINATION} COMPONENT libs)
Loading