-
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
Beginnings of native Android build #110471
base: main
Are you sure you want to change the base?
Changes from 12 commits
90c22cb
6f1b917
c25fbd9
bfcbb3e
97f2555
3d9da10
9e173df
bb9f323
b0f3d55
f9eb950
a69fcfd
54fbb50
061badd
343547d
d9d653a
be4941b
db133cb
6473af2
4d9f500
d5e0292
54d5725
7d78dec
7026cc8
9823a55
7797943
2e4c737
2516884
074a955
240ad01
34cdc56
c171ce3
a515ed8
3831805
9779aeb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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: There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perf is important, so I think the long-term solution should be that we have two builds of the runtime (alas): one with emulated TLS for the older devices (we mustn't ignore the older Android versions, 12.8% is still a lot of devices out there), and another targeting API 29 and onwards. It will increase nuget size and the runtime build times on CI, but I think it would be the best way forward. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd like to avoid runtime explosion if we can help it. |
||
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 | ||
|
@@ -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" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,32 @@ | |
</PropertyGroup> | ||
|
||
<!-- Add path globs specific to native binaries to exclude unnecessary files from packages. --> | ||
<Choose> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't this logic already exist? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't believe it exists elsewhere. I put this here because I found host / target confusion when crossgen2 was cross building android from a mac. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The logic we have is for the "target" platform, not the host (and it's right below this). |
||
<When Condition="$(HostOS.StartsWith('win'))"> | ||
<PropertyGroup> | ||
<HostLibSuffix>.dll</HostLibSuffix> | ||
<HostStaticLibSuffix>.lib</HostStaticLibSuffix> | ||
<HostSymbolsSuffix>.pdb</HostSymbolsSuffix> | ||
</PropertyGroup> | ||
</When> | ||
<When Condition="$(HostOS.StartsWith('osx'))"> | ||
<PropertyGroup> | ||
<HostLibPrefix>lib</HostLibPrefix> | ||
<HostLibSuffix>.dylib</HostLibSuffix> | ||
<HostStaticLibSuffix>.a</HostStaticLibSuffix> | ||
<HostSymbolsSuffix>.dwarf</HostSymbolsSuffix> | ||
</PropertyGroup> | ||
</When> | ||
<Otherwise> | ||
<PropertyGroup> | ||
<HostLibPrefix>lib</HostLibPrefix> | ||
<HostLibSuffix>.so</HostLibSuffix> | ||
<HostStaticLibSuffix>.a</HostStaticLibSuffix> | ||
<HostSymbolsSuffix>.dbg</HostSymbolsSuffix> | ||
</PropertyGroup> | ||
</Otherwise> | ||
</Choose> | ||
|
||
<Choose> | ||
<When Condition="$(PackageRID.StartsWith('win'))"> | ||
<PropertyGroup> | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -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' "> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
<ProjectReference Include="Microsoft.NETCore.TestHost\Microsoft.NETCore.TestHost.proj" /> | ||||||
</ItemGroup> | ||||||
|
||||||
<ItemGroup> | ||||||
<ItemGroup Condition=" '$(TargetsAndroid)' != 'true' "> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
<ProjectReference Include="Microsoft.NETCore.ILAsm\Microsoft.NETCore.ILAsm.proj" /> | ||||||
<ProjectReference Include="Microsoft.NETCore.ILDAsm\Microsoft.NETCore.ILDAsm.proj" /> | ||||||
</ItemGroup> | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we instead define a property for "build executables" instead of per-platform? |
||
add_subdirectory(ilasm) | ||
add_subdirectory(ildasm) | ||
endif(NOT CLR_CMAKE_TARGET_ANDROID) | ||
add_subdirectory(gcinfo) | ||
add_subdirectory(jit) | ||
add_subdirectory(vm) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,11 +16,17 @@ | |
|
||
#include <stdint.h> | ||
|
||
#ifdef __cplusplus | ||
#define CORECLR_HOSTING_API_LINKAGE extern "C" | ||
#else | ||
#define CORECLR_HOSTING_API_LINKAGE | ||
#endif | ||
Comment on lines
+19
to
+23
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FYI @elinor-fung |
||
|
||
// For each hosting API, we define a function prototype and a function pointer | ||
// The prototype is useful for implicit linking against the dynamic coreclr | ||
// library and the pointer for explicit dynamic loading (dlopen, LoadLibrary) | ||
#define CORECLR_HOSTING_API(function, ...) \ | ||
extern "C" int CORECLR_CALLING_CONVENTION function(__VA_ARGS__); \ | ||
CORECLR_HOSTING_API_LINKAGE int CORECLR_CALLING_CONVENTION function(__VA_ARGS__); \ | ||
typedef int (CORECLR_CALLING_CONVENTION *function##_ptr)(__VA_ARGS__) | ||
|
||
// | ||
|
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. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In lieu of a TODO, please file a github issue and provide a link in the comment. |
||||||
if(CLR_CMAKE_HOST_LINUX AND NOT CLR_CMAKE_TARGET_ANDROID) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should also use the host defines.
Suggested change
|
||||||
add_subdirectory(lttngprovider) | ||||||
else() | ||||||
add_subdirectory(dummyprovider) | ||||||
|
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -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="no-rtti no-exceptions""/> | ||||
<_CoreClrBuildArg Include="-DANDROID_STL=c++_static"/> | ||||
<_CoreClrBuildArg Include="-DANDROID_CPP_FEATURES="no-rtti exceptions""/> | ||||
Comment on lines
-81
to
+82
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this affect size of native AOT runtime packs? (Build with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it will affect the size, but less than if we included the shared libc++ (which is something we cannot do anyway) and I think we just need to pay the price. NativeAOT will be but one of the supported ways to build the application, we need to keep that in mind. I don't like the fact that CoreCLR needs exceptions (Android runtime doesn't use exceptions nor RTTI), but that's what we have and we need to support it (at least for the foreseeable future). Ideally, for NativeAOT we should be able to link the application .so at the app build time (from a set of .o or .a files), in which case this setting here won't matter at all. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My question is whether we could set this in the CMake files instead of as argument to CMake. That way pieces of this can still compile with exceptions turned off instead of globally forcing the VM policy. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure we can? The variables are used by the Android toolchain definition file - I think they need to be set on the command line for this to work. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah this needs to be set at the CMake build level sadly. There's not a supported way to do it per-target. We could likely manually set flags to do it if we figure out how the toolchain file sets flags. |
||||
<_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. | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above, please file an issue and add a link to the issue here. |
||||
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" /> | ||||
Comment on lines
+94
to
+98
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this used anywhere? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, one spot. Is there a better existing way to do this?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we add a general feature flag that the Mono vs CoreCLR builds would set? Is this expected to work for the NativeAOT build? |
||||
</ItemGroup> | ||||
|
||||
<PropertyGroup> | ||||
|
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.
this needs to be conditioned on CoreCLR so we don't change the Mono build. same in eng/native/build-commons.sh
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.
Should this be 28? @janvorli tested it recently with 28 https://github.com/dotnet/arcade/blob/88a10ba00ed798ee289d786db9f6339acd682a99/eng/common/cross/build-android-rootfs.sh#L24. We can provide a fallback for that glob API to further lower the requirement.
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 think 29 is necessary because that's the first that does not use emulated TLS.
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.
We can add a run-time check for emulated TLS selection and still lower the requirement.
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.
Did we add a workaround for that? When I ran things previously we only had that for NativeAOT. Assuming that's true, the build will fail.
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.
Emulated TLS works on linux-bionic and has been for a while, so in theory it should work on older Androids, newer ones can use the real TLS. I have recently dealt with Emulated TLS on riscv64 (and later switched to real TLS but still having some issues #111317 (comment)). We can tweak things in asm code to select which path to take
GETTHREAD_ETLS_1
vs.INLINE_GETTHREAD
. Right now it's under the build conditionFEATURE_EMULATED_TLS
.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.
It appears that there is going to be some amount of work to get this right < API level 29. My preference would be to do any of that work in a follow up.