Difference between revisions of "Build LDC for Android"

From D Wiki
Jump to: navigation, search
(First draft of how to build ldc/druntime/phobos)
 
(Remove build instructions for ldc and future directions)
 
(34 intermediate revisions by 3 users not shown)
Line 1: Line 1:
This page will show you how to build a ldc cross-compiler for Android/ARM on linux, along with how to build and run both the druntime/phobos tests and an Android D app using the cross-compiler.
+
This page shows you how to build and run the standard library's tests using ldc on linux or Windows 10 (by using the new bash on linux subsystem), both as a command-line binary and as a GUI Android app.  [https://github.com/ldc-developers/ldc/releases Prebuilt binaries of ldc are available here].
  
Almost all the druntime/phobos unit tests pass on Android/ARM.  One of the native OpenGL sample apps from the Android NDK has been ported to D, I'll port some more soon.  Remaining work to be done is listed last.
+
All of the standard library's unit tests and most of the compiler testsuite passes on Android/ARM.
 
 
You can also try out [http://wiki.dlang.org/Build_DMD_for_Android dmd for Android/x86].
 
  
 
==Prerequisites==
 
==Prerequisites==
  
* linux host, where you'll build ldc
+
* linux/x64 shell, where you'll build and run ldc
 
** You can use a virtual machine like VirtualBox/VMware, with at least 512 MB of memory and 1 GB of swap, particularly if building the phobos unit tests, and 10 GB of disk space.
 
** You can use a virtual machine like VirtualBox/VMware, with at least 512 MB of memory and 1 GB of swap, particularly if building the phobos unit tests, and 10 GB of disk space.
* C++ compiler and toolchain, to build ldc
+
** Windows 10: You can alternately use Bash on Windows (the Windows Subsystem for Linux), [[#Notes_for_Bash_on_Ubuntu_on_Windows|see full steps below]]
* Common development tools, such as CMake and git, and ldc uses libconfig++
+
* A pre-built D compiler for linux, as the ldc frontend is written in D.
* ldc/druntime/phobos source
+
** You can get [http://dlang.org/download the official dmd release for linux] or [https://github.com/ldc-developers/ldc/releases one of the ldc releases for linux].  Many distros also have D compiler packages.
** Get the source using git, as these Android patches have only been tested on the master branch of each repo.
+
* Common development tools, such as CMake and ninja
* llvm 3.6 source, either from the official release or git
+
* Android native toolchain, [https://developer.android.com/ndk/index.html the NDK] and optionally [https://developer.android.com/studio/index.html the SDK]
** llvm 3.7 or later will work too, but you'll have to update the small llvm patch so it still applies.
+
** The SDK is only needed if you want to package a GUI app; the NDK is enough if you just want to build a command-line binary, such as a test runner.
* Android native toolchain, [http://developer.android.com/ndk/index.html the NDK] and optionally [http://developer.android.com/sdk/index.html the SDK]
 
** The SDK is only necessary if you want to package a GUI app; the NDK is enough if you just want to build a command-line binary, such as a test runner.  The "SDK Tools only" version of the SDK is all that's necessary, if you don't plan on using their IDE integration.  I will only write about using the command-line tools.  The SDK requires JDK 7: follow their instructions to make sure it's installed right.
 
 
* Android/ARM, whether a device or emulator
 
* Android/ARM, whether a device or emulator
** The SDK comes with an emulator.  I've only used actual hardware, so that's what I'll discuss.
+
** The SDK comes with an emulator.  I use actual hardware, so that's what I'll discuss.
  
==Build llvm==
+
===Notes for Bash on Ubuntu on Windows===
 +
* Necessary packages
 +
<syntaxhighlight lang=bash>
 +
sudo apt-get install build-essential
 +
sudo apt-get install git
 +
sudo apt-get install cmake
 +
sudo apt-get install unzip
 +
sudo apt-get install libconfig-dev
 +
</syntaxhighlight>
  
Get the source for llvm, either [http://llvm.org/releases/3.6.2/llvm-3.6.2.src.tar.xz the last official 3.6.2 release] or [https://android.googlesource.com/toolchain/llvm/ a git repository like the official Android llvm], which has some modifications but shouldn't really change much. [https://gist.github.com/joakim-noah/1fb23fba1ba5b7e87e1a Download the patch for llvm], apply it, and then [http://llvm.org/docs/GettingStarted.html#getting-started-quickly-a-summary build llvm normally] with the ARM target:
+
* DMD Compiler
 +
<syntaxhighlight lang=bash>
 +
cd ~
 +
curl -L -O http://downloads.dlang.org/releases/2.x/2.075.1/dmd_2.075.1-0_amd64.deb
 +
sudo dpkg -i dmd_2.075.1-0_amd64.deb
 +
</syntaxhighlight>
  
 +
* Android Native Development Kit
 
<syntaxhighlight lang=bash>
 
<syntaxhighlight lang=bash>
tar xvf llvm-3.6.2.src.tar.xz
+
sudo mkdir -p /opt/android-sdk/ndk-bundle
cd llvm-3.6.2.src
+
curl -L -O https://dl.google.com/android/repository/android-ndk-r15c-linux-x86_64.zip
curl -O https://gist.githubusercontent.com/joakim-noah/1fb23fba1ba5b7e87e1a/raw/4bc1439defd2bd962710e8710d3ac26d342f0b87/android_tls
+
sudo unzip android-ndk-r15c-linux-x86_64.zip 'android-ndk-r15c/*' -d /opt/android-sdk/ndk-bundle
git apply android_tls
+
export NDK=/opt/android-sdk/ndk-bundle/android-ndk-r15c
 +
</syntaxhighlight>
 +
 
 +
As Windows Subsystem for Linux does not support USB, you have to install Android SDK and Ant on your Windows system and execute the commands "android" and "ant" from your DOS console.
 +
 
 +
==Run the druntime and phobos unit tests==
 +
 
 +
You can build the druntime and phobos unit tests and run the command-line test runner binaries on Android (don't add the -j5 flag to build in parallel unless you have gigabytes of memory available, as compiling some of the phobos modules' tests takes a fair amount of RAM):
  
mkdir build
+
<syntaxhighlight lang=bash>
cd build
+
make druntime-test-runner phobos2-test-runner
cmake .. -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD=ARM
 
make -j5
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==Build ldc for Android/ARM==
+
Copy the test runners to your device and run them.  Assuming you have an SSH server set up on the computer where you're building with the linux shell and its IP address is 192.168.35.7, you can scp the binaries into [https://play.google.com/store/apps/details?id=com.termux&hl=en the Termux Android app] with these commands and run the tests:
  
Clone the ldc repository, check out the same commits that I built ldc/druntime/phobos with, [https://gist.github.com/joakim-noah/63693ead3aa62216e1d9 apply the Android patch], set the NDK environment variable to your NDK directory, and [http://wiki.dlang.org/Building_LDC_from_source build ldc as usual]:
+
<syntaxhighlight lang=bash>
 +
apt install openssh
 +
scp jo@192.168.35.7:"/path/to/your/ldc/build/runtime/{druntime,phobos2}-test-runner" .
 +
./druntime-test-runner
 +
./phobos2-testrunner
 +
</syntaxhighlight>
 +
 
 +
The tests take about 25 seconds to run on my quad-core tablet: all should pass.  One module, core.sync.semaphore, will fail for any Android older than 6.0, [https://github.com/D-Programming-Language/druntime/pull/784#issuecomment-42777328 because sem_destroy used to work differently in bionic].  You can also run the tests for specified modules by passing their names to the test runner:
 +
 
 +
<syntaxhighlight lang=bash>
 +
./druntime-test-runner core.thread core.sync.semaphore
 +
./phobos2-testrunner std.datetime std.random
 +
</syntaxhighlight>
 +
 
 +
==Run the druntime and phobos unit tests in an apk==
 +
 
 +
You can also run the tests as part of a GUI app, ie an apk, which is a slightly different runtime environment.  First, you can try [[Build D for Android#Build_a_sample_OpenGL_ES_1.0_GUI_app_ported_to_D|cross-compiling a sample GUI app from the NDK that has been translated from C to D, as shown here]].  That simple OpenGLES 1.0 GUI app can be modified to run all the tests, which is what we'll do next.  Clone my Android repo, if you haven't already, go to the native-activity sample app, and create the output directory the SDK expects:
  
 
<syntaxhighlight lang=bash>
 
<syntaxhighlight lang=bash>
cd ../..
+
cd ../../
git clone --recursive https://github.com/ldc-developers/ldc.git
+
git clone https://github.com/joakim-noah/android.git
cd ldc
 
git checkout -b android c769251cc
 
git submodule update
 
curl -O https://gist.githubusercontent.com/joakim-noah/63693ead3aa62216e1d9/raw/0c5e1e976c9c1781dc898a5fe1509f690b0b4324/ldc_android_arm
 
git apply ldc_android_arm
 
  
mkdir build
+
cd android/samples/native-activity/
cd build
+
mkdir -p libs/armeabi-v7a/
export NDK=/path/to/your/android-ndk-r10e
 
cmake .. -DLLVM_CONFIG=../../llvm-3.6.2.src/build/bin/llvm-config
 
make ldc2 -j5
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Download and apply [https://gist.github.com/joakim-noah/d936d6a339426ad1fac3 the patch for druntime] and [https://gist.github.com/joakim-noah/5c03801fa6c59b1e90df the patch for phobos] before building them:
+
Download and apply [https://gist.github.com/joakim-noah/8ba3cd4958266f357295 a small patch to have the sample app invoke the test runner] and [https://gist.github.com/joakim-noah/348edc378d47fb90e32708be19286a2e a patch for the test runner in druntime], then build the tests into a shared library this time:
  
 
<syntaxhighlight lang=bash>
 
<syntaxhighlight lang=bash>
cd ../runtime/druntime
+
curl -O https://gist.githubusercontent.com/joakim-noah/8ba3cd4958266f357295/raw/a52fcf1e63715f8b1bd3527afaa85872087b0f30/native_ldc_arm
curl -O https://gist.githubusercontent.com/joakim-noah/d936d6a339426ad1fac3/raw/ef212405065767e05c69dc6b67990ff56faf6a87/druntime_ldc_arm
+
git apply native_ldc_arm
git apply druntime_ldc_arm
 
  
cd ../phobos
+
cd ../../../ldc/runtime/druntime/
curl -O https://gist.githubusercontent.com/joakim-noah/5c03801fa6c59b1e90df/raw/27b8bd0b6f43e805df59c56e3c4b6acf8e95541e/phobos_ldc_arm
+
curl -O https://gist.githubusercontent.com/joakim-noah/348edc378d47fb90e32708be19286a2e/raw/2b473ff45ff4abc68852ebb1868354b8528026e0/druntime_1.3_ldc_arm
git apply phobos_ldc_arm
+
git apply druntime_1.3_ldc_arm
  
cd ../../build
+
cd ../../build/
make druntime-ldc phobos2-ldc -j5
+
make test-runner-apk
 +
</syntaxhighlight>
 +
 
 +
This assumes that the ldc and android repositories are in the same directory, as shown in these instructions.  If not, modify ANDROID_DIR in the CMake build script to use the path you want.
 +
 
 +
Finally, package the test runner apk:
 +
 
 +
<syntaxhighlight lang=bash>
 +
cd ../../android/samples/native-activity/
 +
export SDK=/path/to/your/android-sdk-linux
 +
$SDK/tools/android update project -p . -s --target 1
 +
ant debug
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==Build a command-line executable==
+
Transfer the resulting bin/NativeActivity-debug.apk to your device and install it.  Also, copy [https://github.com/joakim-noah/android/releases/download/tea/test.list the list of modules to test] to the /sdcard/ directory.  The app will append its results to /sdcard/test.log, so if you happen to have a file with that name, move it.
  
Let's try building a classic benchmark.
+
The app should show a black screen for about a minute, while all the tests run.  A touch after that and it should start flashing a bunch of colors.  If not, look at the output in /sdcard/test.log and check if the app hung after any particular tested module.  You can remove that module from test.list and try running again.
  
[[Category:LDC]]
+
[[Category: Android]]

Latest revision as of 10:39, 10 November 2018

This page shows you how to build and run the standard library's tests using ldc on linux or Windows 10 (by using the new bash on linux subsystem), both as a command-line binary and as a GUI Android app. Prebuilt binaries of ldc are available here.

All of the standard library's unit tests and most of the compiler testsuite passes on Android/ARM.

Prerequisites

  • linux/x64 shell, where you'll build and run ldc
    • You can use a virtual machine like VirtualBox/VMware, with at least 512 MB of memory and 1 GB of swap, particularly if building the phobos unit tests, and 10 GB of disk space.
    • Windows 10: You can alternately use Bash on Windows (the Windows Subsystem for Linux), see full steps below
  • A pre-built D compiler for linux, as the ldc frontend is written in D.
  • Common development tools, such as CMake and ninja
  • Android native toolchain, the NDK and optionally the SDK
    • The SDK is only needed if you want to package a GUI app; the NDK is enough if you just want to build a command-line binary, such as a test runner.
  • Android/ARM, whether a device or emulator
    • The SDK comes with an emulator. I use actual hardware, so that's what I'll discuss.

Notes for Bash on Ubuntu on Windows

  • Necessary packages
sudo apt-get install build-essential
sudo apt-get install git
sudo apt-get install cmake
sudo apt-get install unzip
sudo apt-get install libconfig-dev
  • DMD Compiler
cd ~
curl -L -O http://downloads.dlang.org/releases/2.x/2.075.1/dmd_2.075.1-0_amd64.deb
sudo dpkg -i dmd_2.075.1-0_amd64.deb
  • Android Native Development Kit
sudo mkdir -p /opt/android-sdk/ndk-bundle
curl -L -O https://dl.google.com/android/repository/android-ndk-r15c-linux-x86_64.zip
sudo unzip android-ndk-r15c-linux-x86_64.zip 'android-ndk-r15c/*' -d /opt/android-sdk/ndk-bundle
export NDK=/opt/android-sdk/ndk-bundle/android-ndk-r15c

As Windows Subsystem for Linux does not support USB, you have to install Android SDK and Ant on your Windows system and execute the commands "android" and "ant" from your DOS console.

Run the druntime and phobos unit tests

You can build the druntime and phobos unit tests and run the command-line test runner binaries on Android (don't add the -j5 flag to build in parallel unless you have gigabytes of memory available, as compiling some of the phobos modules' tests takes a fair amount of RAM):

make druntime-test-runner phobos2-test-runner

Copy the test runners to your device and run them. Assuming you have an SSH server set up on the computer where you're building with the linux shell and its IP address is 192.168.35.7, you can scp the binaries into the Termux Android app with these commands and run the tests:

apt install openssh
scp jo@192.168.35.7:"/path/to/your/ldc/build/runtime/{druntime,phobos2}-test-runner" .
./druntime-test-runner
./phobos2-testrunner

The tests take about 25 seconds to run on my quad-core tablet: all should pass. One module, core.sync.semaphore, will fail for any Android older than 6.0, because sem_destroy used to work differently in bionic. You can also run the tests for specified modules by passing their names to the test runner:

./druntime-test-runner core.thread core.sync.semaphore
./phobos2-testrunner std.datetime std.random

Run the druntime and phobos unit tests in an apk

You can also run the tests as part of a GUI app, ie an apk, which is a slightly different runtime environment. First, you can try cross-compiling a sample GUI app from the NDK that has been translated from C to D, as shown here. That simple OpenGLES 1.0 GUI app can be modified to run all the tests, which is what we'll do next. Clone my Android repo, if you haven't already, go to the native-activity sample app, and create the output directory the SDK expects:

cd ../../
git clone https://github.com/joakim-noah/android.git

cd android/samples/native-activity/
mkdir -p libs/armeabi-v7a/

Download and apply a small patch to have the sample app invoke the test runner and a patch for the test runner in druntime, then build the tests into a shared library this time:

curl -O https://gist.githubusercontent.com/joakim-noah/8ba3cd4958266f357295/raw/a52fcf1e63715f8b1bd3527afaa85872087b0f30/native_ldc_arm
git apply native_ldc_arm

cd ../../../ldc/runtime/druntime/
curl -O https://gist.githubusercontent.com/joakim-noah/348edc378d47fb90e32708be19286a2e/raw/2b473ff45ff4abc68852ebb1868354b8528026e0/druntime_1.3_ldc_arm
git apply druntime_1.3_ldc_arm

cd ../../build/
make test-runner-apk

This assumes that the ldc and android repositories are in the same directory, as shown in these instructions. If not, modify ANDROID_DIR in the CMake build script to use the path you want.

Finally, package the test runner apk:

cd ../../android/samples/native-activity/
export SDK=/path/to/your/android-sdk-linux
$SDK/tools/android update project -p . -s --target 1
ant debug

Transfer the resulting bin/NativeActivity-debug.apk to your device and install it. Also, copy the list of modules to test to the /sdcard/ directory. The app will append its results to /sdcard/test.log, so if you happen to have a file with that name, move it.

The app should show a black screen for about a minute, while all the tests run. A touch after that and it should start flashing a bunch of colors. If not, look at the output in /sdcard/test.log and check if the app hung after any particular tested module. You can remove that module from test.list and try running again.