Skip to content

Commit f0ed1bc

Browse files
committed
Quick start instructions for Android
1 parent 393a205 commit f0ed1bc

File tree

1 file changed

+74
-5
lines changed

1 file changed

+74
-5
lines changed

README.md

Lines changed: 74 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,81 @@ version of the OCaml 4.x compiler on a non-Windows machine. The central Opam
1616
repository only introduced the DkML distribution in OCaml 5.x generally and
1717
OCaml 4.14 for Windows specifically.
1818

19-
## Packages that rely on dkml-compiler
19+
## Quick Start
2020

21-
* dkml-component-ocamlcompiler
22-
* dkml-component-ocamlrun
23-
* dkml-component-opam
24-
* dkml-runtime-apps
21+
### Android Cross-Compiler
22+
23+
NOTE 1: There are a couple major patches done by DkML to the OCaml compiler to support Android 32-bit. And the cross-compiler support is not standard (or supported) in the official OCaml compiler. Do not expect to replicate these instructions using the generic OCaml compiler.
24+
25+
NOTE 2: We'll use a Docker container for convenience with Windows and macOS users, and also because it is easy to get the Android NDK from CircleCI, but you can do this directly on a Linux machine.
26+
27+
NOTE 3: Since Apple Silicon does not support 32-bit, and since cross-compiling OCaml requires the same bitness
28+
for the build machine and the target machine, Apple Silicon users cannot compile [Android `armeabi-v7a`](https://developer.android.com/ndk/guides/abis)
29+
(aka. DkML `android_arm32v7a`).
30+
31+
```console
32+
$ docker run -it --rm cimg/android:2024.10.1-ndk
33+
34+
# Install opam if you don't have it
35+
circleci:~/project$ sudo apt-get update && sudo apt-get install build-essential curl git patch rsync unzip -y
36+
circleci:~/project$ echo /usr/local/bin | sudo bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.2.1"
37+
38+
# Initialize opam if you haven't already. No sandboxing is needed in containers.
39+
circleci:~/project$ opam init --cli=2.1 --no-setup --bare --disable-sandboxing
40+
41+
# Two Android options to set. ANDROID_PLATFORM is the minimum API level ("targetSdkVersion" in the Android manifest)
42+
circleci:~/project$ opam var --cli=2.1 --global ANDROID_NDK=/home/circleci/android-sdk/ndk/27.1.12297006
43+
circleci:~/project$ opam var --cli=2.1 --global ANDROID_PLATFORM=android-34
44+
45+
# PICK ONE: Android arm64-v8a switch
46+
circleci:~/project$ opam switch create android34-ndk27-arm64-v8a --cli=2.1 \
47+
--packages dkml-base-compiler,dkml-host-abi-linux_x86_64,dkml-target-abi-android_arm64v8a,ocamlfind,conf-dkml-cross-toolchain \
48+
--repos default,diskuv-4d79e732=git+https://github.com/diskuv/diskuv-opam-repository.git#4d79e732
49+
50+
# PICK ONE: Android armeabi-v7a switch. You will need a 32-bit C/C++ compiler.
51+
circleci:~/project$ sudo apt-get install gcc-multilib g++-multilib -y
52+
circleci:~/project$ opam switch create android34-ndk27-armeabi-v7a --cli=2.1 \
53+
--packages dkml-base-compiler,dkml-host-abi-linux_x86,dkml-target-abi-android_arm32v7a,ocamlfind,conf-dkml-cross-toolchain \
54+
--repos default,diskuv-4d79e732=git+https://github.com/diskuv/diskuv-opam-repository.git#4d79e732
55+
56+
# PICK ONE: Android x86_64 switch
57+
circleci:~/project$ opam switch create android34-ndk27-x86_64 --cli=2.1 \
58+
--packages dkml-base-compiler,dkml-host-abi-linux_x86_64,dkml-target-abi-android_x86_64,ocamlfind,conf-dkml-cross-toolchain \
59+
--repos default,diskuv-4d79e732=git+https://github.com/diskuv/diskuv-opam-repository.git#4d79e732
60+
61+
# THEN: Get and cross-compile your source code. Here we use Dune and assume 'android34-ndk27-arm64-v8a'
62+
circleci:~/project$ opam install --cli=2.1 --switch android34-ndk27-arm64-v8a dune
63+
circleci:~/project$ git clone https://github.com/avsm/hello-world-action-ocaml hello
64+
circleci:~/project$ cd hello
65+
circleci:~/project/hello$ opam exec --cli=2.1 --switch android34-ndk27-arm64-v8a -- dune build -x android_arm64v8a world.exe
66+
circleci:~/project/hello$ file _build/default*/world.exe
67+
_build/default.android_arm64v8a/world.exe: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, with debug_info, not stripped
68+
_build/default/world.exe: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=1731ad9ce0fdeff69df28af0b1217e843eabe26e, for GNU/Linux 3.2.0, with debug_info, not stripped
69+
70+
# You can also directly use the ocamlfind -toolchain
71+
circleci:~/project$ opam exec --cli=2.1 --switch android34-ndk27-arm64-v8a -- ocamlfind ocamlc -config-var native_c_compiler
72+
gcc -O2 -fno-strict-aliasing -fwrapv -pthread -fPIC -D_FILE_OFFSET_BITS=64
73+
circleci:~/project$ opam exec --cli=2.1 --switch android34-ndk27-arm64-v8a -- ocamlfind -toolchain android_arm64v8a ocamlc -config-var native_c_compiler
74+
/home/circleci/android-sdk/ndk/27.1.12297006/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android34-clang -O2 -fno-strict-aliasing -fwrapv -pthread -fPIC -D_FILE_OFFSET_BITS=64
75+
```
76+
77+
DkML supports three out of the four supported Android ABIs.
78+
The three ABIs (all but `x86`) were chosen based on [statistics for a large game on Aug 29, 2023](https://github.com/android/ndk/issues/1772#issuecomment-1697831518):
79+
80+
| Arch | Percent |
81+
| ----------- | ------- |
82+
| arm64-v8a | 68.66 |
83+
| armeabi-v7a | 30.38 |
84+
| x86_64 | 0.71 |
85+
| x86 | 0.26 |
86+
87+
and also [Google's recommendation](https://android-developers.googleblog.com/2022/10/64-bit-only-devices.html):
88+
89+
> **Note**: While 64-bit-only devices will grow in popularity with phones joining Android Auto in this group, 32-bit-only devices will continue to be important for Android Go, Android TV, and Android Wear. Please continue supporting 32-bit ABIs; Google Play will continue serving 32-bit apps to 32-bit-only devices.
90+
91+
---
92+
93+
Finally, a word of **CAUTION**. The Android cross-compiler **can never** use OCaml 5+ because [OCaml 5 will never bring back the 32-bit instruction set](https://discuss.ocaml.org/t/32-bit-native-code-support-for-ocaml-5/12583/13?u=jbeckford). That means if you don't want to drop a large percent of your users or drop new Android categories over the next five (?) years, you will have a critical dependency on DkML.
2594

2695
## Directory Structure
2796

0 commit comments

Comments
 (0)