graalvm-mobile

Benjamin C 2021-11-27T16:54:23.006400Z

@smith.adriane I would be interested, thanks!

phronmophobic 2021-11-27T17:56:19.007Z

Awesome! The basic plan is pretty simple. You compile your uberjar with native-image as a native library and communicate with the android app via JNI. If you search some combination of jni, android, and ndk, there should be lots of examples of working with native libraries. native-image requires a bunch of special flags, especially when targeting mobile. I followed the example from https://github.com/gluonhq/gluon-samples/tree/master/HelloGluon to find the flags for iOS. It's been a while, but there's a way to view all of the build logs and they print the full native-image command somewhere in the logs. I combined those args with the arglist that's usually required to make clojure compile. You can see the iOS script at https://github.com/phronmophobic/mobiletest/blob/main/scripts/compile-shared#L28.

phronmophobic 2021-11-27T17:58:34.007500Z

I know that's a bit vague, but I'm out of town at the moment. I'm happy to answer more questions since that description is light on details.

phronmophobic 2021-11-27T18:04:10.007700Z

The C interface that your clojure program exposes will use graal's C API, https://www.graalvm.org/reference-manual/native-image/C-API/. To use that from clojure, I use https://github.com/cnuernber/dtype-next/. See https://github.com/phronmophobic/mobiletest/blob/main/src/com/phronemophobic/mobiletest.clj#L87

Benjamin C 2021-11-27T18:36:02.008100Z

Nice, thanks for the lead!

frankitox 2022-01-21T20:18:20.004500Z

@smith.adriane, by any chance you remember what the https://github.com/phronmophobic/mobiletest/tree/main/conf/capcache is about? Or how you generate it? while trying to adapt the code to android I tried using the capcache folder from a fresh HelloGloun project, but when running https://github.com/phronmophobic/mobiletest/blob/main/scripts/compile-shared#L28 I'm getting the error

Missing CAP cache value for: NativeCodeInfo:PosixDirectives:ConstantInfo:LC_ADDRESS
If using the capcache of mobiletest I get another error
Missing CAP cache value for: NativeCodeInfo:AArch64LibCHelperDirectives:StructInfo:CPUFeatures:StructFieldInfo:fDCPOP

phronmophobic 2022-01-21T20:24:31.004700Z

I don't really know what the capcache is. I just copied the args and configs from the gluon project.

phronmophobic 2022-01-21T20:25:05.004900Z

Did you compile an android project successfully with HelloGluon?

phronmophobic 2022-01-21T20:26:18.005100Z

I don't remember where the capcache files come from. It's possible that they might be different depending on the compiler platform or target platform

phronmophobic 2022-01-21T20:27:01.005300Z

I compiled an iOS project using the HelloGluon script and then used the same flags that the HelloGluon script used by looking at the build logs.

frankitox 2022-01-21T20:27:02.005500Z

Oh alright, you copied the capcache files from a HelloGluon project?

👍 1
frankitox 2022-01-21T20:27:16.005700Z

I think I compiled it successfully, but I'll check just in case

phronmophobic 2022-01-21T20:31:36.006Z

Almost all the flags I use in compile-shared are copied from the HelloGluon script. I think only flags I added for clojure are:

--report-unsupported-elements-at-runtime \
    --initialize-at-build-time="$INITIALIZE_AT_BUILD_TIME" \
    --no-fallback \
    --no-server \
... and
    -J-Dclojure.spec.skip-macros=true \
    -J-Dclojure.compiler.direct-linking=true \
    -J-Dtech.v3.datatype.graal-native=true \
# non-clojure related, but probably added by me
    -J-Xmx20G \
    -J-XX:MaxDirectMemorySize=8G \

frankitox 2022-01-21T21:07:05.006200Z

Yes! Those are more or less the flags that I'm using

frankitox 2022-01-21T21:07:36.006700Z

Should I first modify the code in src folder before even attempting to run native-image?

phronmophobic 2022-01-21T21:12:08.006900Z

The compile script uses https://github.com/frankitox/graal-android/blob/main/src/com/phronemophobic/mobiletest.clj as the main which should work regardless of platform

frankitox 2022-01-21T21:13:00.007200Z

nice, thanks!

phronmophobic 2022-01-21T21:13:32.007400Z

and you would probably get a different error. Excited to see clojure on android! 🤞

frankitox 2022-01-21T21:15:09.007600Z

haha very unlikely 😂, but thank you for the encouragement

frankitox 2022-01-06T20:17:57.000100Z

@smith.adriane I'm trying to run the compile-shared script and it throws an error while running the line

clojure -X com.phronemophobic.mobiletest/compile-interface-class
The error is
Syntax error (ClassNotFoundException) compiling at (com/phronemophobic/mobiletest.clj:1:1).
org.graalvm.nativeimage.c.function.CEntryPointLiteral
By any chance, you know what I could be doing wrong? I didn't run download-deps .

phronmophobic 2022-01-06T20:19:07.000300Z

It's been a while since I've looked at this. Let me check!

frankitox 2022-01-06T20:21:12.000500Z

thank you! the troublesome line is https://github.com/phronmophobic/mobiletest/blob/main/src/com/phronemophobic/mobiletest.clj#L6

phronmophobic 2022-01-06T20:21:20.000800Z

I think the current error you're running into is because the graalvm classes aren't available. You need to compile using graalvm's jdk to make classes like CEntryPointLiteral available.

phronmophobic 2022-01-06T20:21:55.001Z

however, I don't think you'll get very far without doing the prerequisites, https://github.com/phronmophobic/mobiletest#prerequisites

phronmophobic 2022-01-06T20:23:03.001300Z

Setting up graalvm is step #2 of the prerequisites

frankitox 2022-01-06T20:26:13.001600Z

ahh I see, so before even attempting to run compile-shared I need to compile the project with graal?

phronmophobic 2022-01-06T20:28:23.001800Z

compile-shared will compile the project, but compilation uses graalvm, graalvm's llvm-toolchain, and java's arm64 static libraries

frankitox 2022-01-06T20:31:01.002300Z

Yes!! Thanks, I had to setup the $PATH to use graal before running clojure -X com.phronemophobic.mobiletest/compile-interface-class

frankitox 2022-01-06T20:31:42.002500Z

Sorry about the dummy question 😅

phronmophobic 2022-01-06T20:33:10.002700Z

no problem!

phronmophobic 2022-01-06T20:41:01.002900Z

are you trying to compile clojure for android?

phronmophobic 2022-01-06T20:42:51.003100Z

If so, then the static libraries that download-deps fetches aren't the right ones. You'll need to get the corresponding android deps.

frankitox 2022-01-06T20:50:27.003300Z

Yes, I was just trying to run native-image using the flags you suggested extracting from the HelloGluon project

frankitox 2022-01-06T20:50:54.003500Z

Those static libraries are needed to run native-image or later in the process?

phronmophobic 2022-01-06T20:57:03.003700Z

I think you'll get linker errors if you don't have them, but I think that's one of the last steps within the native-image compilation process

phronmophobic 2022-01-06T21:01:00.003900Z

so if you get that far, you're at least headed in the right direction

Benjamin C 2021-11-27T06:54:42.001300Z

I am curious if this also works on Android, or if it is currently iOS only.

phronmophobic 2021-11-27T07:15:18.005400Z

The demo project is iOS only, but I plan on extending it to android at some point. If someone was interested in giving it a shot, I could provide some pointers on how to get started and what the basic structure would look like.