Introduction

PariDroid is a port of PARI/GP to Android, started by Charles Boyd and currently maintained by Andreas Enge and Laurent Facq. It is distributed under the GNU General Public License, either version 3 of the licence, or (at your option) any later version (GPLv3+).

Installing PariDroid

Ready to use packages in the .apk format can be found in the download section. They are also available via the F-Droid and the Google Play stores. The remainder of this page describes how to compile the source code for yourself; there is no need to do so if you are happy with the provided binaries.

Installing a command line development environment

The following section describes how to set up a reproducible environment in which to compile PariDroid from the command line. This is how we currently produce the .apk package for distribution on a headless server. Instead of using an emulator, we directly test on a physical device.

Installing the Android SDK 24.4.1

This is the last SDK version that contains the necessary files for building with Ant, in particular the tools/ subdirectory with the files tools/ant/build.xml and tools/ant/uibuild.xml.

Download the Android SDK r24.4.1 and unpack it into $HOME/local/android-sdk-r24.4.1:

mkdir -p $HOME/local/bin
cd $HOME/local
wget http://dl.google.com/android/android-sdk_r24.4.1-linux.tgz -O - | tar zx
mv android-sdk-linux android-sdk-r24.4.1

Add $HOME/local/bin to your path, for instance by executing

export PATH=$HOME/local/bin:$PATH

Make a symbolic link to the android binary

export SDK=$HOME/local/android-sdk-r24.4.1
ln -s $SDK/tools/android bin/

Install Android platform tools by downloading and unpacking a software archive as follows:

wget http://dl.google.com/android/repository/platform-tools_r29.0.1-linux.zip
unzip platform-tools_r29.0.1-linux.zip
mv platform-tools $SDK/
rm -f platform-tools_r29.0.1-linux.zip

Install Android build tools by downloading and unpacking a software archive as follows:

wget http://dl.google.com/android/repository/build-tools_r29.0.1-linux.zip
unzip build-tools_r29.0.1-linux.zip
mkdir $SDK/build-tools
mv android-10 $SDK/build-tools/
rm -f build-tools_r29.0.1-linux.zip

The previous steps have populated $SDK/platform-tools and $SDK/build-tools. Link adb, apksigner and zipalign:

ln -s $SDK/platform-tools/adb bin/
ln -s $SDK/build-tools/android-10/zipalign bin/
ln -s $SDK/build-tools/android-10/apksigner bin/

Install an Android platform by downloading and unpacking a software archive as follows:

wget http://dl.google.com/android/repository/android-19_r04.zip
unzip android-19_r04.zip
mkdir $SDK/platforms
mv android-4.4.2 $SDK/platforms/
rm -f android-19_r04.zip

Installing the Android NDK

To later compile and integrate the PARI C library into the project, download the Android NDK; for instance, Linux 64bit r13b. (This is the last version where the include files are still contained in the platforms/ subdirectory, instead of in sysroot/. Version r17c is the last version that ships the GCC cross compiler. Version r18b contains a compiler named gcc, but which in reality is clang.) Unpack it and move it, for instance, to $HOME/local/android-ndk-r13b:

cd $HOME/local
wget https://dl.google.com/android/repository/android-ndk-r13b-linux-x86_64.zip
unzip android-ndk-r13b-linux-x86_64.zip
rm -f android-ndk-r13b-linux-x86_64.zip

Set the environment variable NDK to contain the path to the Android NDK, which is used by our Makefile:

export NDK=$HOME/local/android-ndk-r13b

Setting up the PariDroid project

The following steps need to be executed only once. Download PariDroid from its git repository:

git clone http://pari.math.u-bordeaux.fr/git/paridroid.git
cd paridroid/PariDroid

Prepare the Android project:

android update project --target android-19 -s -p .
cd ..

The PARI source code will be fetched automatically from the git server and placed into the ../srclib/pari directory, next to the PariDroid sources, when invoking make for the first time. The Makefile also contains the logic to check out the correct PARI version depending on the PariDroid version number: its first three fields specify the PARI version. If it corresponds to a released version, the corresponding git tag is checked out. Otherwise, the latest git master is fetched.

The Makefile is set up to create an apk in release mode, which is then signed with a debug key. On the first run, this key needs to be created by doing a debug build:

cd PariDroid
ant debug
cd ..

Building PariDroid

A call to

make

configures and compiles the GMP and PARI libraries and compiles the PariDroid project into the package PariDroid-VERSION.apk, signed with a debug key and aligned.

The unsigned and unaligned package resides in PariDroid/bin/PariDroid-release-unsigned.apk, the signed and unaligned package in PariDroid/bin/PariDroid-release-unaligned.apk.

Once the libraries have been compiled, it is faster to only call

make apk-fast

to run the NDK and Android builds on a potentially changed PariDroid code.

make distclean

removes the generated files. The final package can be tested by installing it in a device that is connected by USB in debug mode:

adb install PariDroid-VERSION.apk

The package can be uninstalled using

adb uninstall fr.ubordeaux.math.paridroid

or, more easily, an installed package can be overwritten with

adb install -r PariDroid-VERSION.apk

For debugging purposes, it may be useful to launch the command

adb logcat

in a separate terminal window.

Installing Android Studio on GNU Guix

Installing Android Studio entails a certain loss of reproducibility: It consists essentially of running an install script, that directly afterwards downloads the actual software and later continuously downloads further updates to an ever shifting environment. On the positive side, the integrated development environment and emulator ease the Android development process. While purportedly being free software, Android Studio is delivered as opaque binaries with hard-coded execution paths, which makes it difficult to deploy on GNU/Linux distributions that are not compliant with the file system hierarchy.

Installing Android Studio

I have used the following approach described by Julien Lepiller to install Android Studio on the GNU Guix distribution, with a few adaptations and the additional installation of an Android NDK.

I chose to install everything Android into $HOME/Android. Unless told otherwise, Android Studio downloads everything related to the SDK and the NDK into $HOME/Android/Sdk, and I downloaded and unpacked Android Studio into $HOME/Android/Studio; in particular, the launcher script is $HOME/Android/Studio/bin/studio.sh.

Then I prepared an environment containing the dependencies (that is, essentially, the dynamic libraries to which the Android Studio binaries expect to link) in the following file $HOME/Android/studio-manifest.scm:

(use-package-modules base bash compression gcc gl glib linux nss pulseaudio
                     version-control virtualization xml xorg java file)
(packages->manifest
  (list bash git which dbus
        (list gcc "lib")
        coreutils grep sed findutils xmessage
        (list openjdk14 "jdk")
        file glibc
        ;; for running the android virtual devices (AVD):
        e2fsprogs qemu-minimal
        alsa-lib expat libxcomposite libxcursor libxi libxtst
        mesa nss pulseaudio (list util-linux "lib") libx11 zlib))

Compared to Julien's environment, I added the jdk output of the openjdk package at version 14 (the most recent version available in Guix at the time of writing), which automatically provides the environment with the corresponding java, javac and other executables. I also added file and glibc for debugging purposes: In particular ldd of the glibc package helps to distinguish binaries for 32-bit architectures (that do not run on Guix) from those for 64-bit architectures (which may run). (Additionally I had the impression that glibc was needed to link with some of the binaries, but later tests seem to imply that it is not actually needed.) Furthermore, coreutils, grep, sed, findutils and xmessage provide binaries that the studio.sh looks for in its first few lines.

On my machine, I also had to enable virtualisation support in the BIOS to be able to run the emulator; otherwise the corresponding kernel module would not be loaded and /dev/kvm would be absent from the system.

The next step is to create the environment and memorise its location, to be able to pass some directories it contains to the actual later invocation:

cd $HOME
export PROFILE=$(guix environment -C -N -m $HOME/Android/studio-manifest.scm \\
  -- bash -c 'echo $GUIX_ENVIRONMENT')

Now the environment variable $PROFILE contains something like /gnu/store/f994jk1i9g7lmf3zh5dak92hcimgw91r-profile with its bin, include, lib and so on subdirectories.

Then the environment is created in a container (-C) with network access (-N):

guix environment -C -N --share=$XAUTHORITY --share=/tmp/.X11-unix \\
    --share=/dev/shm --expose=/etc/machine-id --expose=$HOME \\
    --expose=$PROFILE/lib=/lib --expose=$PROFILE/lib=/lib64 \\
    --expose=$PROFILE/bin/bash=/bin/bash \\
    --share=/dev/kvm -m $HOME/Android/studio-manifest.scm

Parts of the surrounding system are passed into the container, as well as the lib and lib64 subdirectories of the profile, which inside the container are accessible as /lib and /lib64; this is the magic that makes the hard-coded paths in Android Studio work. Additionally to Julien's invocation, I had to pass in /bin/bash as well to be able to use the ndk-build script.

For reasons probably related to containers and that I do not know, it is important to carry out the cd $HOME as given above before entering the container; otherwise upon starting Android Studio complains that the directory $HOME/.config/Google/AndroidStudio4.1/ is read-only.

If everything goes well, the container is entered, which can be seen from the prompt being changed to [env]$. Julien succeeded in calling env upon entering the container, which made it possible to pass environment variables in; for unknown reasons this did not work for me. So I recorded the content of the environment variables $XAUTHORITY (/run/user/1001/gdm/Xauthority) and $DISPLAY (:1.0) outside the container; the first commands in the container set these variables to the same values, and also set LD_LIBRARY_PATH. To avoid that the C compiler from the NDK includes incompatible header files from the Guix glibc passed into the environment, we also need to forget C_INCLUDE_PATH:

export XAUTHORITY=/run/user/1001/gdm/Xauthority
export DISPLAY=:1.0
export LD_LIBRARY_PATH=/lib:/lib/nss:$HOME/Android/Sdk/emulator/lib64/qt/lib:$HOME/Android/Sdk/emulator/lib64
unset C_INCLUDE_PATH

Finally Android Studio can be started, and from there on it does its business of downloading things and setting them up:

$HOME/Android/Studio/bin/studio.sh

After downloading the SDK, Android Studio complained about something related to SD cards. It turns out there was a conflict between binaries for 32- and 64-bit architectures. So I removed the 32-bit binary $HOME/Android/Sdk/tools/mksdcard and replaced it by a symbolic link to $HOME/Android/Sdk/emulator/mksdcard. A similar looking problem still persists: After each start, Android Studio complains that file watcher failed to start; but here removing $HOME/Android/Studio/bin/fsnotifier and replacing it by a symlink to $HOME/Android/Studio/bin/fsnotifier64 did not solve the problem.

Setting up the PariDroid project

Here I cheated and simply copied the manually set up project to $HOME/Android/paridroid; then the subdirectory $HOME/Android/Project/paridroid/Paridroid can be opened as a project in Android Studio. Notice that $HOME/Android/Project/paridroid/ is a git checkout of the project sources (together with a few local files, see below), so one may easily change branches or make modifications in Android Studio and commit them to the git repository.

Calling make (more precisely, make pari) once from inside $HOME/Android/paridroid may be necessary to compile the gmp and pari libraries for the different architectures and to place them into the architecture-specific subdirectories of $HOME/Android/Project/paridroid/Paridroid/app/src/main/jni.