Maxima-on-Android-AS
Maxima-on-Android-AS copied to clipboard
How did you cross compile Maxima?
I'm trying to figure out how to update the Maxima binaries to the latest version, but I have no idea how you cross compiled Maxima for Android. The instructions on https://sites.google.com/site/maximaonandroid/home/how-to-build-maxima-on-android seem to be outdated, as there seems to be no crosscmp.lsp
involved when cross compiling ECL anymore.
Oh, good question. That site you refer to is not updated for many years.
Still, the basic idea is the same.
- Cross compile ECL for Android is the first and most important step.
- Compiling Maxima as dynamic object (library) or a module is very difficult, so I would suggest you forget about that.
- It is easier to include all maxima source lisp files as if they were part of ECL. You may need to do adjustment here and there, such as file name collision between ECL and maxima.
- I always chosen to compile everything in a static linked executable.
- Don't forget about PIC and PIE treatment. That is mandatory since after Android 5 or 6.
Did you already succeed cross compiling ECL by yourself?
Thanks and best regards, Yasuaki Honda, Chiba, Japan
cross compiling ECL was pretty easy, so yes
by "include all maxima source lisp files as if they were part of ECL". You mean merge Maxima into the ECL source tree?
Or do you mean statically linking it with ECL?
Ok, I managed to figure out out to cross compile Maxima as a module using ASDF based off of the examples from EQL5-Android, but it involved patching ECL, as maxima::make-unspecial
uses ffi::c-inline
which doesn't work with the byte compiler, which is apparently needed to evaluate the Maxima code before cross compiling it.
these were the patches I used ecl.patch.gz maxima.patch.gz
also, I used the develop branch of ECL instead of 16.1.3, which I heard works with newer NDK
I picked the develop branch because that's what EQL5 did
also I had to set the logical host "SYS:**;*.*"
to the path where the modules are on the android side as I haven't figured out how to do that from the cross compile environment yet.
changed maxima.patch a bit.
maxima.patch.gz
to compile Maxima, after setting up the cross compile environment mentioned in the ECL manual, you'd set the environmental variable TOOLCHAIN_PATH to the one mentioned in the ECL manual when cross compiling ECL for Android and set ECL_ANDROID to the prefix you installed the Android binary to. then cd to the Maxima directory, then run ./configure --enable-ecl --host=arm-linux-android
then ${ECL_TO_RUN} --shell make.lisp
. Which will build both a static library and a cross compiled fasl which can be loaded as a module
So far, I've only tested this resulting binary in Termux, haven't got it to work in the Android app yet. But this is how far I got so far.
Wow, this is great. Congratulations!!
I do have couple of questions:
- Which OS did you use for host? MacOS, Ubuntu, CentOS,,,
- Which version of NDK do you use?
- Did you make 32bit binary, or 64bit binary? (file command can tell you).
- Did you encounter trouble on compiling bdwgc?
- Did you encounter combin file name collision?
BTW, someone on the ecl-devel mailing list says the development branch is going to become ECL 20 soon and it is already in final testing phase. So picking it rather than 16.1.3 should be a good choice.
I used Arch Linux as the host, I used 19c for the ndk, I made a 32bit binary just so I could test it in Termux. Didn't have much trouble compiling bdwgc, but enabling generational garbage collection caused it to segfault. I didn't really run into any file name collision because I ended up compiling ECL and Maxima separately but statically linked them together using libmaxima.a, which is done by make.lisp that I put in the Maxima directory, although for some reason, the script sometimes complains about not being able to delete a fasc file that doesn't exist (no idea why it's doing that) but I managed to workaround that by using (si:install-bytecodes-compiler)
then (asdf:load-system :maxima)
before running make.lisp.
Did you make any changes to Maxima or ECL before packaging it for the Android app? As I didn't make any changes to it other than getting it to run in Termux.
btw, make.lisp is based on the examples EQL5-Android gave
Specifically, it is based on this script here https://gitlab.com/eql/EQL5-Android/-/blob/master/examples/REPL/make.lisp It was the easiest way to get it to cross compile for Android that I could think of. I suspect that the method for cross compiling ECL and Common Lisp applications for Android has changed a bit since you ported Maxima to Android, which would explain why you had trouble creating a fasl file for it, since that method didn't exist yet.
Hi, I have a bit of time due to COVID19 and stay at home, and started working on compiling the latest Maxima (5.43.3) in the latest ECL (20.4.24). I will study what you have written so far above to reproduce your result.
Thanks for your valuable information!!
I have successfully compiled Maxima-5.43.2 on ECL 20.4.24 using Android NDK r21 on Debian Linux 10 as a shared object (dynamic library).
I have created a Gist to share how to do this as step by step instructions. How to cross compile Maxima for Android
I keep getting this when I try to run your build
$ maxima/bin/rmaxima
rlwrap: warning: On this system rlwrap cannot follow the rlwrapped command's working directory:
filename completion will only be relative to rlwrap's own working directory
warnings can be silenced by the --no-warnings (-n) option
Condition of type: SIMPLE-PROGRAM-ERROR
Wrong number of arguments passed to function #<compiled-function EXT:FUNCTION-LAMBDA-LIST 0xb40dfc60>.
No restarts available.
Top level in: #<process TOP-LEVEL 0xb3e6ffc0>.
>
At least when trying to run it in Termux. I'm not sure what changes I need to make to the files in this repo to create the apk. I tried simply zipping the new binaries of the resulting Maxima up, but that didn't seem to work
ok, seems to be from trying to use NDK r21. NDK 19c works though
Did you make the maxima binary work in either Termux or adb shell?
One important diffs of this maxima binary from past one is that this one is dynamic link while past binaries were static linked. As such, just replacing a single binary file were sufficient to make things work. In this situation, other shared object such as libecl.so needs to be installed in the directory and also LD_LIBRARY_PATH environment variable needs to be correctly set up. I would believe the following is a way to try:
/data/data/jp.yhonda/files/maxima to be a shell script setting up LD_LIBRARY_PATH and then call the actual binary somewhere in the additions directory.
I managed to get it to work in Termux after using NDK 19c and setting (logical-pathname-translations "SYS")
to where ECL keeps its fasls it require
s
Is there any way to get Android apps to give terminal output? I'm used to the environment giving me more detailed error messages.
ok, how do you update the version number for the apk? because I sorta got it working, but it seems to think it's the older version
I tried greping the repo for 5\.41\.0
but couldn't find anything
ok, just found out it's getting the startup message from maxima_svg.html
, not maxima itself
ok, apparently it was stored as 3 separate integers, which is why grep didn't work
tbh, it was a lot easier for me to figure out how to develop for Termux than for regular Android, and I'm kinda stuck.
Can you even run a shell script like a regular executable in Android?