These instructions show you how to build D command-line executables and OpenGL ES GUI apps for Android, either by using the desktop D compilers for Windows, Mac, or linux available here or a native Android compiler. There are separate steps for cross-compilation, ie building apps on a Windows/linux PC or Mac and running the app on Android, versus native compilation, both building and running on your Android device itself.

Since you cannot install the Android SDK on Android, I end by showing how to package a GUI Android app, a zip file called an .apk, from scratch, by using the tools available in the Termux app for Android, a terminal emulator app and open-source package manager/repository for Android devices.

CMake and either Make or Ninja are required to build the D runtime libraries for Android. There are instructions below on setting these tools up for Windows, Mac, and linux.

Android, whether a device or emulator, to run your D code

The SDK comes with an emulator. I use actual hardware, so that's what I'll discuss.

If using a device, you need some way to transfer the app over. There are several ways to do this, here are a few I've tried:

Install an ssh server app on your Android device and scp the app over. Alternately, set up an ssh server on your host PC/Mac, and use an ssh/scp client on Android to get the app. This is what I do, by using the OpenSSH package in Termux.

Host the app in a web server and get it by using your Android browser or a downloader app.

Native compilation

Setup

Once you're at a command prompt or have the Termux app installed, get the ldc compiler for your OS and the NDK for cross-compilation, set some needed environment variables, and generate the runtime libraries for Android.

Cross-compilation

Windows

Download CMake and the zip files for one of the Android NDKs for Windows, the latest ldc, and either Make or Ninja (the following instructions assume Ninja). You will need 7-Zip to unpack recent ldc releases. Make sure unzip is available to unpack the rest of the build tools, then add them to your path, set the path of the NDK and its C cross-compiler, and run ldc-build-runtime. I show the commands for 64-bit Windows, should be similar for 32-bit, except the Ninja zip only comes with a 64-bit version.

cddroid# assuming all the zip files have been placed in a folder called droidunzipcmake-3.11.4-win64-x64.zip7zxldc2-1.11.0-windows-x64.7zunzipandroid-ndk-r17b-windows-x86_64.zipunzipninja-win.zipsetPATH=%PATH%;C:\Users\you\droid\cmake-3.11.4-win64-x64\bin;C:\Users\you\droid\ldc2-1.11.0-windows-x64\bin;C:\Users\you\droidldmd2--version# run this to check that ldc is in your pathsetCC=C:\Users\you\droid\android-ndk-r17b\toolchains\llvm\prebuilt\windows-x86_64\bin\clangldc-build-runtime--ninja--targetPreset=Android-arm--dFlags="-w;-mcpu=cortex-a8"--buildDir=droid32ldc-build-runtime--ninja--targetPreset=Android-aarch64--buildDir=droid64setNDK=C:\Users\you\droid\android-ndk-r17b

Mac

Download CMake, the zip file for the Android NDK, the latest ldc, and either Make or Ninja (the following instructions assume Ninja). CMake and Ninja can be installed from a package manager like Homebrew, but I'll show the manual install here. Make sure unzip is available to unpack the NDK and tar for everything else. After unpacking, add these tools to your path, including setting the path of the NDK and its C cross-compiler, and run ldc-build-runtime.

linux

Install needed packages, including optionally Ninja, as shown here for Ubuntu. You will need tar to unpack ldc and unzip for the NDK. Add ldc to your path and export the path of the NDK and its C cross-compiler, as shown here for bash, and run ldc-build-runtime.

Set the APK_DIR environment variable to the right platform for your device:

32-bit ARM

exportAPK_DIR=armeabi-v7a

64-bit ARM

exportAPK_DIR=arm64-v8a

Build a command-line executable

Now that we have a D compiler and runtime libraries for Android, let's try building a small program, the classic Sieve of Eratosthenes single-core benchmark, which finds all prime numbers up to a number you choose. Install the curl package in Termux if you're natively compiling, apt install curl.

Cross-compilation

Copy this sieve program onto an Android device or emulator and set its permissions with the chmod command. Here's how I do it in Termux, with an ssh server running on the host PC/Mac with IP address 192.168.1.37:

apt install openssh
cd
scp jo@192.168.1.37:sieve .
chmod 700 sieve

Run the sieve program

The sieve program will tell you how many prime numbers there are in the first n integers, a limit you can specify. Run this command to find how many primes there are in the first million integers:

./sieve 1000000

If you built sieve successfully, it should return

78498 primes

Build a sample OpenGL ES 1.0 GUI app ported to D

Clone my android repository or download its source in a zip file, which contains several headers and sample OpenGL apps from the NDK translated to D, and build the Native Activity app, which is written completely in D. As you'll see below, D code for an apk must be compiled to a shared library, which the Android runtime will call.

On linux or the Termux app, you can just clone my git repo (the same can be done on Mac and Windows if you install git first):

Cross-compilation

Finally, package the app as the SDK directs: at this point, it's just like building a regular Android app. I document the older Ant approach, which is deprecated, replace it with the Gradle command from a newer SDK. With Ant on Mac or linux, set the path to your SDK, then run these commands:

Native compilation

Install and run the sample GUI app

Go to Settings->Security on your Android device and allow installation of apps from unknown sources, ie from outside the Play Store, then go to /sdcard/Download in your file manager and choose the NativeActivity-debug apk to install it. Open the app after installing or go to your app folder and run the app named NativeActivity: it'll show a black screen initially, then flash a bunch of colors when the screen is touched.

Build a sample OpenGL ES 2.0 GUI app mostly written in D, with some Java

This D app has not been ported to 64-bit Android/ARM yet, only 32-bit ARM compilation will work for now.

The app comes with a simple build script, which will build the D shared library for you, as long as the environment variables are set.

Here are the contents of that script, so you can see what it's doing. The Windows version, build-apk.bat, and the linux/macOS version, build-apk, only differ on the final link command, which I've pasted below.

Cross-compilation

Package this shared library into an apk by using the SDK, as you would normally, and try installing and running it on your device.

Native compilation

Install the right Eclipse Java compiler package for your device (the ecj4.6 package if you're running Android 5 or 6), the Android dex tool, and other packages needed to build an Android apk. Generate any Java files needed, compile and dex them, then package everything up into an apk and sign it.

This simple app only requires three files, AndroidManifest.xml, resources.arsc, and lib/$APK_DIR/libnative-activity.so, which you can check with the following aapt command.

aapt list NativeActivity-debug-unsigned.apk

Now let's generate a hashed manifest, just like a Java jar file, and sign the app. If you have your own Java Keystore already, just supply it to apksigner. If not, apksigner will generate a self-signed Keystore file, which we name debug.ks below, which is good enough to sign and install debug apps on your own Android device.

You should see three additional files in the apk, if you list its contents using the command above. At this point, you can install and run the signed app on your own device. If you modify the app, you'll need to build the manifest and sign it again: make sure you use the debug.ks you created before or Android won't allow you to reinstall the same app with a newly generated key, unless you first uninstall the app.

First, install the OpenSSL package in Termux. Then, this OpenSSL command will generate a self-signed debug certificate, apk.cert, and a 2048-bit RSA private key, key.pem, which isn't encrypted with a password. It will ask you for some signing info, for which I've shown what's used by the debug certificate in the Android SDK, but it doesn't matter what you enter, as it's ignored:

apt install openssl-tool
openssl req -x509 -nodes -newkey rsa:2048 -keyout key.pem -out apk.cert
....................................+++
writing new private key to 'key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code)[AU]:US
State or Province Name (full name)[Some-State]:.
Locality Name (eg, city)[]:
Organization Name (eg, company)[Internet Widgits Pty Ltd]:Android
Organizational Unit Name (eg, section)[]:
Common Name (e.g. server FQDN or YOUR name)[]:Android Debug
Email Address []:

Now that we have a certificate- self-signed in this case, use your actual release certificate if you want to release the app- and private key, we use them to sign the app. Since the apk is just a zip file, unzip it into a directory and use OpenSSL to generate a new signature file, CERT.RSA, then update the apk with the new signature, and copy the apk to a public user directory from which you can install it: