I'm eyeing this Programming Praxis exercise as one to tackle next but there's a catch before I can start programming. TinyScheme, my current Scheme Interpreter of choice, doesn't have support for generating random numbers, and the exercise requires this.
I could hack something together using TinyScheme (and probably the Programming Praxis Standard Prelude). Or, I could do as John Cowen suggested, and try out a different implementation. He suggested Chibi-Scheme. Chibi Scheme is lightweight, but unlike TinyScheme, it's also quite modern. This means, among other things, it should give me easy access to the SRFI-27: Sources of Random Bits library. Longer term, it would be ideal to have access to R7RS features and other modern niceties.
I busted out my cell phone and hardware keyboard. I opened up Termux and went to work. Here's my attempt at getting chibi-scheme running on Android:
Let's be clever and build this on the SD card. [localhost]{~}(1)$ cd storage/external-1/src [localhost]{src}(1)$ git clone https://github.com/ashinn/chibi-scheme.git Cloning into 'chibi-scheme'... remote: Counting objects: 18101, done. remote: Compressing objects: .... Receiving objects: 100% Resolving deltas: 0% [localhost]{src}(1)$ cd chibi-scheme [localhost]{chibi-scheme}(1)$ ./configure bash: ./configure: /bin/sh: bad interpreter: Permission denied D'oh. OK, don't panic. [localhost]{chibi-scheme}(1)$ sh configure Autoconf is an evil piece bloatware encouraging cargo-cult programming. Make, on the other hand, is a beautiful little prolog for the filesystem. Just run 'make'. Oooh, sassy software. I like it. [localhost]{chibi-scheme}(1)$ make The program 'make' is not installed. Install it by executing: pkg install make No problem, I'll just do what Termux tells me to do... [localhost]{chibi-scheme}(1)$ pkg install make Building dependency tree... Reading state information... All packages are up to date. The following packages were automatically installed and are no longer required: binutils libandroid-support-dev libffi libllvm ndk-stl ndk-sysroot Use 'apt autoremove' to remove them. The following NEW packages will be installed: make 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Need to get 76.5 kB of archives. After this operation, 246 kB of additional disk space will be used. Get:1 https://termux.net stable/main aarch64 make aarch64 4.2.1 [76.5 kB] Preparing to unpack .../make_4.2.1_aarch64.deb ... [localhost]{chibi-scheme}(1)$ make echo '#define sexp_so_extension "'.so'"' > include/chibi/install.h echo '#define sexp_default_module_path "'/data/data/com.termux/files/usr/share/chibi:/data/data/com.termux/files/usr/lib/chibi'"' >> include/chibi/install.h echo '#define sexp_platform "'android'"' >> include/chibi/install.h echo '#define sexp_version "'0.8.0'"' >> include/chibi/install.h echo '#define sexp_release_name "'`cat RELEASE`'"' >> include/chibi/install.h cc -c -Iinclude -Wall -g -g3 -O3 -o main.o main.c make: cc: Command not found make: *** [Makefile:149: main.o] Error 127 Whoops. No compiler. After attempts to install 'gcc' and search for a compiler package in general I finally tripped over 'clang.' That will apparently install a C compiler. [localhost]{chibi-scheme}(1)$ pkg install clang The following NEW packages will be installed: clang 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Need to get 12.9 MB of archives. After this operation, 61.2 MB of additional disk space will be used. Get:1 https://termux.net stable/main aarch64 clang aarch64 6.0.0-1 [12.9 MB] Preparing to unpack .../clang_6.0.0-1_aarch64.deb ... [localhost]{chibi-scheme}(1)$ make cc -c -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o main.o main.c cc -c -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -fPIC -o gc.o gc.c It's working! It's really working! cc -c -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -fPIC -o sexp.o sexp.c cc -c -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -fPIC -o bignum.o bignum.c cc -c -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -fPIC -o gc_heap.o gc_heap.c cc -c -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -fPIC -o opcodes.o opcodes.c cc -c -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -fPIC -o vm.o vm.c cc -c -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -fPIC -o eval.o eval.c cc -c -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -fPIC -o simplify.o simplify.c cc -fPIC -shared -Wl,-soname,libchibi-scheme.so.0 -o libchibi-scheme.so.0.8.0 gc.o sexp.o bignum.o gc_heap.o opcodes.o vm.o eval.o simplify.o -ldl -lm ln -sf libchibi-scheme.so.0.8.0 libchibi-scheme.so.0 ln: libchibi-scheme.so.0: Operation not permitted make: *** [Makefile:162: libchibi-scheme.so.0] Error 1 And it broke. Ugh. After a much debugging I realized that my issue was permission based. Apparently Android doesn't allow you to perform certain operations on your SD card. I moved the source tree to internal storage and tried again. [localhost]{chibi-scheme}(1)$ cd .. [localhost]{src}(1)$ mv chibi-scheme ~/ [localhost]{src}(1)$ cd [localhost]{~}(1)$ cd chibi-scheme [localhost]{chibi-scheme}(1)$ make ln -sf libchibi-scheme.so.0.8.0 libchibi-scheme.so.0 ln -sf libchibi-scheme.so.0 libchibi-scheme.so It's working again. Whooo! cc -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o chibi-scheme main.o -L. -lchibi-scheme LD_LIBRARY_PATH=".:/data/data/com.termux/files/usr/lib" DYLD_LIBRARY_PATH=".:" CHIBI_MODULE_PATH=lib ./chibi-scheme -q tools/chibi-ffi lib/chibi/filesystem.stub cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/chibi/filesystem.so lib/chibi/filesystem.c -L. -lchibi-scheme cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/chibi/weak.so lib/chibi/weak.c -L. -lchibi-scheme cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/chibi/heap-stats.so lib/chibi/heap-stats.c -L. -lchibi-scheme cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/chibi/disasm.so lib/chibi/disasm.c -L. -lchibi-scheme cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/chibi/ast.so lib/chibi/ast.c -L. -lchibi-scheme LD_LIBRARY_PATH=".:/data/data/com.termux/files/usr/lib" DYLD_LIBRARY_PATH=".:" CHIBI_MODULE_PATH=lib ./chibi-scheme -q tools/chibi-ffi lib/chibi/emscripten.stub cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/chibi/emscripten.so lib/chibi/emscripten.c -L. -lchibi-scheme LD_LIBRARY_PATH=".:/data/data/com.termux/files/usr/lib" DYLD_LIBRARY_PATH=".:" CHIBI_MODULE_PATH=lib ./chibi-scheme -q tools/chibi-ffi lib/chibi/process.stub cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/chibi/process.so lib/chibi/process.c -L. -lchibi-scheme LD_LIBRARY_PATH=".:/data/data/com.termux/files/usr/lib" DYLD_LIBRARY_PATH=".:" CHIBI_MODULE_PATH=lib ./chibi-scheme -q tools/chibi-ffi lib/chibi/time.stub cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/chibi/time.so lib/chibi/time.c -L. -lchibi-scheme LD_LIBRARY_PATH=".:/data/data/com.termux/files/usr/lib" DYLD_LIBRARY_PATH=".:" CHIBI_MODULE_PATH=lib ./chibi-scheme -q tools/chibi-ffi lib/chibi/system.stub cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/chibi/system.so lib/chibi/system.c -L. -lchibi-scheme LD_LIBRARY_PATH=".:/data/data/com.termux/files/usr/lib" DYLD_LIBRARY_PATH=".:" CHIBI_MODULE_PATH=lib ./chibi-scheme -q tools/chibi-ffi lib/chibi/stty.stub cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/chibi/stty.so lib/chibi/stty.c -L. -lchibi-scheme LD_LIBRARY_PATH=".:/data/data/com.termux/files/usr/lib" DYLD_LIBRARY_PATH=".:" CHIBI_MODULE_PATH=lib ./chibi-scheme -q tools/chibi-ffi lib/chibi/net.stub cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/chibi/net.so lib/chibi/net.c -L. -lchibi-scheme LD_LIBRARY_PATH=".:/data/data/com.termux/files/usr/lib" DYLD_LIBRARY_PATH=".:" CHIBI_MODULE_PATH=lib ./chibi-scheme -q tools/chibi-ffi lib/chibi/io/io.stub cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/chibi/io/io.so lib/chibi/io/io.c -L. -lchibi-scheme cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/chibi/optimize/rest.so lib/chibi/optimize/rest.c -L. -lchibi-scheme cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/chibi/optimize/profile.so lib/chibi/optimize/profile.c -L. -lchibi-scheme LD_LIBRARY_PATH=".:/data/data/com.termux/files/usr/lib" DYLD_LIBRARY_PATH=".:" CHIBI_MODULE_PATH=lib ./chibi-scheme -q tools/chibi-ffi lib/chibi/crypto/crypto.stub cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/chibi/crypto/crypto.so lib/chibi/crypto/crypto.c -L. -lchibi-scheme cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/srfi/27/rand.so lib/srfi/27/rand.c -L. -lchibi-scheme cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/srfi/151/bit.so lib/srfi/151/bit.c -L. -lchibi-scheme cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/srfi/39/param.so lib/srfi/39/param.c -L. -lchibi-scheme cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/srfi/69/hash.so lib/srfi/69/hash.c -L. -lchibi-scheme cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/srfi/95/qsort.so lib/srfi/95/qsort.c -L. -lchibi-scheme cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/srfi/98/env.so lib/srfi/98/env.c -L. -lchibi-scheme LD_LIBRARY_PATH=".:/data/data/com.termux/files/usr/lib" DYLD_LIBRARY_PATH=".:" CHIBI_MODULE_PATH=lib ./chibi-scheme -q tools/chibi-ffi lib/srfi/144/math.stub cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/srfi/144/math.so lib/srfi/144/math.c -L. -lchibi-scheme cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/scheme/time.so lib/scheme/time.c -L. -lchibi-scheme cc -fPIC -shared -DSEXP_USE_INTTYPES -Iinclude -Wall -g -g3 -O3 -o lib/srfi/18/threads.so lib/srfi/18/threads.c -L. -lchibi-scheme echo "# pkg-config" > chibi-scheme.pc echo "prefix=/data/data/com.termux/files/usr" >> chibi-scheme.pc echo "exec_prefix=\${prefix}" >> chibi-scheme.pc echo "libdir=/data/data/com.termux/files/usr/lib" >> chibi-scheme.pc echo "includedir=\${prefix}/include" >> chibi-scheme.pc echo "version=0.8.0" >> chibi-scheme.pc echo "" >> chibi-scheme.pc cat chibi-scheme.pc.in >> chibi-scheme.pc find lib/chibi/ -name \*.sld | \ LD_LIBRARY_PATH=".:/data/data/com.termux/files/usr/lib" DYLD_LIBRARY_PATH=".:" CHIBI_MODULE_PATH=lib ./chibi-scheme tools/generate-install-meta.scm 0.8.0 > lib/.chibi.meta find lib/srfi/ -name \*.sld | \ LD_LIBRARY_PATH=".:/data/data/com.termux/files/usr/lib" DYLD_LIBRARY_PATH=".:" CHIBI_MODULE_PATH=lib ./chibi-scheme tools/generate-install-meta.scm 0.8.0 > lib/.srfi.meta find lib/scheme/ -name \*.sld | \ LD_LIBRARY_PATH=".:/data/data/com.termux/files/usr/lib" DYLD_LIBRARY_PATH=".:" CHIBI_MODULE_PATH=lib ./chibi-scheme tools/generate-install-meta.scm 0.8.0 > lib/.scheme.meta Amazing - it built without issue. How about installing, will that work? [localhost]{chibi-scheme}(1)$ make install install -d /data/data/com.termux/files/usr/bin install -m0755 chibi-scheme /data/data/com.termux/files/usr/bin/ install -m0755 tools/chibi-ffi /data/data/com.termux/files/usr/bin/ install -m0755 tools/chibi-doc /data/data/com.termux/files/usr/bin/ install -m0755 tools/snow-chibi /data/data/com.termux/files/usr/bin/ install -m0755 tools/snow-chibi.scm /data/data/com.termux/files/usr/bin/ many boring 'install' lines removed. You're welcome. if type ldconfig >/dev/null 2>/dev/null; then ldconfig; fi echo "Generating images" Generating images cd / && LD_LIBRARY_PATH="/data/data/com.termux/files/usr/lib:/data/data/com.termux/files/usr/lib" DYLD_LIBRARY_PATH="/data/data/com.termux/files/usr/lib:" /data/data/com.termux/files/usr/bin/chibi-scheme -d /data/data/com.termux/files/usr/share/chibi/chibi.img cd / && LD_LIBRARY_PATH="/data/data/com.termux/files/usr/lib:/data/data/com.termux/files/usr/lib" DYLD_LIBRARY_PATH="/data/data/com.termux/files/usr/lib:" /data/data/com.termux/files/usr/bin/chibi-scheme -xscheme.red -d /data/data/com.termux/files/usr/share/chibi/red.img cd / && LD_LIBRARY_PATH="/data/data/com.termux/files/usr/lib:/data/data/com.termux/files/usr/lib" DYLD_LIBRARY_PATH="/data/data/com.termux/files/usr/lib:" /data/data/com.termux/files/usr/bin/chibi-scheme -mchibi.snow.commands -mchibi.snow.interface -mchibi.snow.package -mchibi.snow.utils -d /data/data/com.termux/files/usr/share/chibi/snow.img Holy smokes, it's done. Let's see if it really worked. [localhost]{chibi-scheme}(1)$ cd [localhost]{~}(1)$ chibi-scheme > (+ 1 2 3) 6 We have scheme! Let's try something a bit more advanced > (import (srfi 27) (srfi 1)) > (random-integer 100) 56 > The R7RS library functionality is working and srfi's are installed by default. We have success!
And here are some screenshots to show this really was all executed on my Galaxy S9 Plus:
On my blog, I discussed installation of Guile Scheme and Chez Scheme on an Android tablet. See HERE, HERE and HERE. I am delighted with my current setup.
ReplyDeleteThanks for sharing -- chibi-scheme seems like a hit but I do appreciate the other options.
ReplyDeleteGNUroot is amazing, but I found that Termux was just a tad bit more useful for me. The biggest issue I had with GNUroot was an android quirk: the only way I could get back to a GNUroot instance was through the notification menu. I couldn't link a keystroke to it. That always irked me.
Termux also has some interesting paid addons, which are a fun way to support the author. You can add commands to your home screen, for example.
Regardless, it's amazing the options you have for running bash and related tools on Android.