scripts for compiling Common Lisp games for Android with ECL

Name Last Update
app Loading commit data...
armeabi Loading commit data...
armeabi-v7a Loading commit data...
contrib Loading commit data...
licenses Loading commit data...
lisp Loading commit data...
.dir-locals.el Loading commit data...
.gitignore Loading commit data...
.gitmodules Loading commit data...
Android-2.mk Loading commit data...
README.org Loading commit data...
clear-fasls.sh Loading commit data...
cross-compile.patch Loading commit data...
cross.org Loading commit data...
export-build-script.sh Loading commit data...
foreign-2.lisp Loading commit data...
insert-upstream-gc.sh Loading commit data...
insert-upstream-libffi.sh Loading commit data...
project.org Loading commit data...
results.org Loading commit data...
tasks.org Loading commit data...

Building Common Lisp games for Android with ECL


This repository collects scripts and configurations for building Common Lisp games to run on Android via Embeddable Common Lisp’s ecl-android port and (optionally) the Commandergenius SDL1.2 Android port. SDL2 support is planned but not yet implemented.

This is a work in progress; bugs and incompatibilties are to be expected at this early stage. Please contact me at dto@xelf.me or on freenode #lispgames if needed.

Project status update, June 16 2016

  • The new ECL Quarterly newsletter is out, and I wrote a special feature (part 1 of 2) covering this game porting project. Please visit ECL Quarterly Issue IV to read more about what’s going on.
  • NEW! Achieved 60 frames per second! (still with GC pauses to be eliminated) See the YouTube video here.

A major milestone has been reached—the test game now runs at 60 frames per second, even with the slower vertex coloring and a good number of bricks onscreen (see video link above.) Further optimization should allow the game to run full speed with the full configuration.

Consing is still excessive, which leads to the GC pauses. To eliminate them I’ll have to switch from DFFI (FFI with dynamic runtime lookups) to inlined C/C++ style FFI. This works great on the PC but cross-compilation issues have made it tricky to get it working on the device. To the extent that the game still conses after that point, I will have to manage GC somehow (possibly by using the generational garbage collector and running frequent partial GC’s.)

I’ll update this space further as work continues.

Previous project updates can be found in the included file “results.org” in this repository.


  • Java 8
  • android-ndk-r9
  • android-sdk-r24 (tested with 24.4.1-linux)
  • capability to build/run 32-bit binaries on 64-bit linux system, if applicable
  • an android device (preferably rooted)
  • Slime 2.14 (for Emacs connectivity) https://github.com/slime/slime/
  • for building Xelf games, the “droid” branch of http://gitlab.com/dto/xelf.git See also clone-xelf.sh for more information.


You must use Slime 2.14 on your host Emacs to match the one included with ecl-android.


Step 1: Clone the repository

Issue the following commands to clone the repository and change the current directory to it.

git clone https://gitlab.com/dto/ecl-android-games-src/ src
cd ~/src

Step 2: Copy GLES shared library

The build procedure needs to link CL-OPENGL against an Android OpenGL ESv1 shared library, which is not provided by this project.

In order to proceed, you must find and place a copy of this shared object in the root directory of the repository. If your device is connected via ADB, the following command may work.

adb pull /system/lib/libGLESv1_CM.so

This shared object is used for linking purposes only, and will not be included in the resulting app.

Step 3: Set absolute path of FASL cache

Near the top of the file “project.org” you will see an area to edit a string called FASL-CACHE-PREFIX. You must set this to the correct value for your system. Retain the surrounding double-quotes, and do not use a trailing slash. Save your changes to project.org, and then you’re ready to start the build procedure.

Step 4: Start building

The included shell script “export-build-script.sh” will compile “project.org” out to a build script named “project.sh”.

sh -x export-build-script.sh   

You should examine “project.sh” before running it, to see which commands are run and in what order. When you’re ready:

sh -x project.sh 

That should trigger the entire build process. If the build succeeds, the final .apk will be built in the directory src/apk. You should return to the prompt with a message saying “jar signed”.

If everything went well:

adb install apk/MainActivity-debug.apk

to try it out. Please note, you should not install or use this testing APK on a “production” android system.

To remove the package, do:

adb uninstall org.lisp.ecl

ProTip: use TRAMP with ADB!

To make this useful you need a rooted android device.

Settings like the following will keep backup and autosave files on the local host.

(add-to-list 'tramp-default-user-alist '("adb" nil "root"))
(add-to-list 'tramp-backup-directory-alist (cons "." "~/.emacs.d/backups/"))
(setq tramp-auto-save-directory "~/.emacs.d/auto-saves/")

ProTip: use Emacs to inspect your APK package!

Yup, they’re just zip files. Missing libraries or assets? Check the APK by opening it as a file in GNU Emacs.


Special thanks to Daniel Kochmański and the #lispgames crew for helping in the development, debugging, and testing of these scripts.