All Manuals > LispWorks User Guide and Reference Manual > 38 The HCL Package




Deliver LispWorks for Android. Implemented only in LispWorks for Android Runtime.




deliver-to-android-project function project-path level &key library-name using-ndk no-sub-dir studio-p &allow-other-keys



A symbol.


A pathname designator.


An integer in the inclusive range [0, 5].


A string.


A boolean.


A pathname or a string specifying a directory, or t or nil.


A boolean.


The function deliver-to-android-project delivers a LispWorks runtime for the Android platform.

deliver-to-android-project creates two files, a Lisp heap and a dynamic library, that needs to be part of an Android project to be used on Android. It does some Android-specific processing, and then calls deliver.

If function is non-nil it is the restart function which is called after the LispWorks runtime finishes initializing. It is called on another process (by funcall-async), and its return value is not used. By the time the function function is called, LispWorks is ready to receive calls from Java, and a call from function to Java may be used to inform Java that LispWorks is ready instead of the reporter argument to com.lispworks.Manager.init (or in parallel to it). The function function should return in short time, If you want it to linger, use process-run-function to start another with a function that lingers, and return from function.

project-path is the path of the Android project, except when no-sub-dir is supplied, when it defines a directory to put the files. When delivering into an Android Studio project, project-path can be either the root of the project or the "main" directory (the location of the file AndroidManifest.xml).

level is the delivery level. It is passed to deliver. See the documentation for deliver for details.

library-name when supplied must be a string, and defines the base name of the files. The call to com.lispworks.Manager.init which initializes LispWorks must match library-name. The default value of library-name is "LispWorks".

Note: Actually the call com.lispworks.Manager.init uses the name to find the files, so if you rename the files com.lispworks.Manager.init must match the names of the files, rather than library-name.

using-ndk needs to be true if the Android project is built using Eclipse and uses NDK to build C code. The default value of using-ndk is nil.

no-sub-dir, when non-nil, tells deliver-to-android-project that the project-path argument is the directory where the files need to go, rather than a project path. In this case deliver-to-android-project does not look for sub-directories. If no-sub-dir is a pathname or string, it specifies a directory where the heap should go. If this directory is relative, it is relative to the project-path directory. If no-sub-dir is t, it specifies that the heap should go at top level in project-path. When no-sub-dir is passed, it is your responsibility to ensure that the files end up in the right place in the Android project. no-sub-dir is useful when the delivery cannot be done directly into the Android Project, for example when it is on a different machine or there are permissions issues. It may also be useful if you have a project with a directory structure that does not match the structure that deliver-to-android-project expects. The default value of no-sub-dir is nil.

studio-p tells deliver-to-android-project whether the target Android project is built with Android Studio or not, which is used to decide where the files go. When studio-p is not passed, deliver-to-android-project tries to determine whether it is Android Studio as described below.

deliver-to-android-project first decides the names of the files to generate and where they should go.

The two files that deliver-to-android-project generates are named lib<library-name>.so.lwheap for the heap file, and lib<library-name>.so for the dynamic library, so by default the names are and

The directory or directories where the files go are determined as follows:

  1. When no-sub-dir is nil (the default), it first checks whether the project-path contains a file named AndroidManifest.xml.
  2. a) If the file AndroidManifest.xml exists, then this is the "main" path. If studio-p was not supplied, it sets studio-p to t if there is a directory called "java" in the "main" directory", otherwise it sets studio-p to nil.

    b) If there is no AndroidManifest.xml file, it checks whether inside the project-path there is a sub-sub-sub-directory app/src/main, and whether AndroidManifest.xml exists in it. If so, it takes the sub-sub-sub-directory as the "Main" directory, and sets studio-p to t (ignoring any supplied value).

    Once it decided where the "Main" directory is, it puts the heap in its "assets" sub-directory, and the dynamic library in its "jni libs" sub-directory. The "jni libs" directory is:

    (i) If studio-p is t it is "jniLibs/armeabi-v7a".

    (ii) Otherwise if using-ndk is nil it is "libs/armeabi-v7a".

    (iii) Otherwise it is "jni".

  3. If no-sub-dir is non-nil, then the dynamic library is put in the project-path directory. If no-sub-dir is t, the heap is put in the same place. Otherwise, the directory specified by no-sub-dir is merged with the project-path to create the path where the heap goes.
  4. Note: If no-sub-dir is a pathname or string it must specify a directory, which can be an absolute path.

After deliver-to-android-project determines the names of the files and where they go, it calls deliver, passing function, the appropriate path, level, the Delivery keywords :split, :exe-file, :dll-exports and :image-type with the correct values for Android, and all the keyword arguments it was supplied except library-name, using-ndk, studio-p and no-sub-dir. The keywords that deliver-to-android-project passes explicitly should not be used, but the rest of the Deliver keywords can be used and are interpreted in the standard way (see the LispWorks Delivery User Guide for details). However, since CAPI is not available on Android, all keywords related to CAPI are not useful.

  1. With Android Studio you do not need using-ndk. You need it when you use ndk-build to build dynamic libraries in your project. In Eclipse that is normally done by the CDT builder. You need using-ndk because the ndk-build removes all dynamic libraries from the libs sub-directory and its sub-directories, including the LispWorks dynamic library. The solution for this is to pass a true value for using-ndk to deliver-to-android-project, and add to the file in the jni sub-directory the lines that are required to copy the LispWorks dynamic library to libs/armeabi-v7a. Assuming you do not pass library-name, these lines in should be:
    LOCAL_MODULE := LispWorks

    If you pass library-name, you need to change the lines above to match your change. There can be other solutions, for example you can deliver elsewhere, and add a build step that copies the LispWorks files into the project after the CDT builder (on Eclipse). If the build in Eclipse is changed not to delete files from the libs directory, then using-ndk is not needed.

  3. Like deliver, deliver-to-android-project cannot be called with multiprocessing running, and is best called inside a script that is passed to LispWorks by the command line argument -build.
  4. deliver-to-android-project is available only in the Android delivery image lispworks-7-1-0-arm-linux-android. This image is an ARM image, and must be run on ARM architecture. That can be either an ARM machine, or an ARM emulator.
  5. To deliver a LispWorks for Android Runtime image with a delivery script that calls deliver-to-android-project using the QEMU emulator, use the shell script examples/android/, which passes its arguments to lispworks-7-1-0-arm-linux-android: -build /path/to/delivery-script.lisp

  6. The algorithm for finding the directories will work for Eclipse and for Android Studio with the default settings. Android Studio is very flexible and still in flux, so may change. It seems unlikely that the names of the sub-directories (assets, jniLibs and java) will change, but the main directory may move around. Supplying the actual main directory rather than the root should still work. If this does not work, you can supply no-sub-dir to either put the files in the right directories, or just put it in some directory and copy it to the right place.
See also

Android interface
LispWorks Delivery User Guide

LispWorks User Guide and Reference Manual - 20 Sep 2017