4

I am trying to compile Unison, which is written in OCaml, for Android.

The only two OCaml toolchains for Android that I am aware of are opam-cross-android and opam-android-repository. However, they have been unmaintained since 2018 and 2014, respectively, and the OCaml versions they support no longer meet the minimum version requirements of the latest Unison version. I also remember coming across an OCaml compiler which generates Java bytecode, which is also unmaintained by now.

I have managed to compiled Unison into a static binary for the intended ABI using a foreign chroot, albeit for a Linux target rather than an Android one. The resulting binary starts up on Android but on certain operations exits with code 159, indicating abnormal termination with signal 31, presumably due to a system call that is not allowed by the seccomp-bpf policy in Android 8 and higher (source).

Regarding file permissions, the app has WRITE_EXTERNAL_STORAGE permission, thus it should have access to all of /sdcard. (Yes, this is nowadays restricted to apps with limited use cases, and only an issue if you want to get the app on the Play store, as the OS itself treats it like any other permission. Even then, Google considers file managers a valid use case, thus chances are the same applies to file sync tools.)

Question: How can I compile OCaml into a binary (executable or library) which runs on Android?

Do the problematic system calls come from the compiler or in the linker? Or rather: would they come from the OCaml-specific part of the toolchain, or from a generic one (for which one could then substitute the appropriate NDK counterpart)?

Are there other alternatives which are still being maintained and work with code expecting to be built on a somewhat recent OCaml version? Such as tools which modify an existing Linux binary, rewriting system calls so they comply with Android’s seccomp policies? Or a OCaml compiler which generates Java bytecode?


For now, please ignore the fact that Android has begun to restrict execution of native binaries in their own process. This could be alleviated by refactoring the executable into a library, but the build target problem would still remain. For now, apps targeting API 28 or lower can still execute native binaries in a separate process, albeit they won’t get accepted on the Play Store, and future Android version may introduce further restrictions even for legacy apps. This, as well as security implications, is for the individual developer/organization to decide.

user149408
  • 5,385
  • 4
  • 33
  • 69
  • Besides the compilation step itself, I think a big issue is that Android handles permissions quite differently than other platforms (ie. which directories you have access to, how you ask the permission to gain that access, etc) which is probably why you get abnormal terminations. I'm not sure there is an automated solution that will turn any program in a program Android compatible. – jthulhu Jun 16 '23 at 20:25
  • Shouldn’t be an issue with `WRITE_EXTERNAL_STORAGE` permissions (which should be OK for a file sync tool even according to Play Store policies), as long as the caller side ensures the permission is granted prior to calling the native code. Same goes for other permissions which may be needed. – user149408 Jun 16 '23 at 21:50
  • 1
    If you are trying to run Unison / OCaml code on Android, you'll have to provide your own proot as [Android is not POSIX compliant](https://stackoverflow.com/q/27604455/295004). Assuming Unison works in Termux, one path would be to [embed Termux with your Android app](https://github.com/termux/termux-app/issues/1983) but be aware of [their conditions for package hosting](https://wiki.termux.com/wiki/FAQ#Can_I_use_Termux_packages_in_my_own_project) The other alternative maybe OCaml to C and then compiling the C code in NDK and working through the errors there (elbow grease work regardless). – Morrison Chang Jun 17 '23 at 03:37
  • Any tools for OCaml to C? I came across something, but iirc that project has long been abandoned. – user149408 Jun 17 '23 at 08:46

0 Answers0