Cross-compiling and debugging for ARM/Android

First, make sure you can build with GN.

Then, add android to your .gclient configuration file.

target_os = ['android']  # Add this to get Android stuff checked out.

The target_os field is a list, so if you're also building on unix it'll look like this:

target_os = ['android', 'unix']  # Multiple target OSes.

Run gclient sync, and you’ll get a large checkout under ./third_party/android_tools.

Enable developer mode on your phone or tablet, and turn on USB debugging, via instructions here. Also, get the handy adb tool on your path. It’s in your checkout at ./third_party/android_sdk/public/platform-tools.

Using gm #

Use the tools/dev/ script to automatically build V8 tests and run them on the device.

alias gm=/path/to/v8/tools/dev/
gm android_arm.release.check

This command pushes the binaries and tests to the /data/local/tmp/v8 directory on the device.

Manual build #

Use to generate an ARM release or debug build:

tools/dev/ arm.release

Then run gn args and make sure you have the following keys:

target_os = "android"      # These lines need to be changed manually
target_cpu = "arm" # as assumes a simulator build.
v8_target_cpu = "arm"
is_component_build = false

The keys should be the same for debug builds. If you are building for an arm64 device like the Pixel C, which supports 32bit and 64bit binaries, the keys should look like this:

target_os = "android"      # These lines need to be changed manually
target_cpu = "arm64" # as assumes a simulator build.
v8_target_cpu = "arm64"
is_component_build = false

Now build:

ninja -C d8

Use adb to copy the binary and snapshot files to the phone:

adb shell 'mkdir -p /data/local/tmp/v8/bin'
adb push /data/local/tmp/v8/bin
adb push /data/local/tmp/v8/bin
adb push /data/local/tmp/v8/bin
rebuffat:~/src/v8$ adb shell
bullhead:/ $ cd /data/local/tmp/v8/bin
bullhead:/data/local/tmp/v8/bin $ ls
v8 icudtl.dat snapshot_blob.bin
bullhead:/data/local/tmp/v8/bin $ ./d8
V8 version 5.8.0 (candidate)
d8> 'w00t!'

Debugging #

d8 #

Remote debugging d8 on an Android device is relatively simple. First start gdbserver on the Android device:

bullhead:/data/local/tmp/v8/bin $ gdbserver :5039 $D8 <arguments>

Then connect to the server on your host device.

adb forward tcp:5039 tcp:5039
gdb $D8
gdb> target remote :5039

gdb and gdbserver need to be compatible with each other, if in doubt use the binaries from the Android NDK. Note that by default the d8 binary is stripped (debugging info removed), $OUT_DIR/exe.unstripped/d8 contains the unstripped binary though.

Logging #

By default, some of d8’s debugging output ends up in the Android system log, which can be dumped using logcat. Unfortunately, sometimes part of a particular debugging output is split between system log and adb, and sometimes some part seems to be completely missing. To avoid these issues, it is recommended to add the following setting to the gn args:

v8_android_log_stdout = true

Floating-point issues #

The gn args setting arm_float_abi = "hard", which is used by the V8 Arm GC Stress bot, can result in completely nonsensical program behavior on hardware different from the one the GC stress bot is using (e.g. on Nexus 7).

Using Sourcery G++ Lite #

The Sourcery G++ Lite cross compiler suite is a free version of Sourcery G++ from CodeSourcery. There is a page for the GNU Toolchain for ARM Processors. Determine the version you need for your host/target combination.

The following instructions use 2009q1-203 for ARM GNU/Linux, and if using a different version please change the URLs and TOOL_PREFIX below accordingly.

Installing on host and target #

The simplest way of setting this up is to install the full Sourcery G++ Lite package on both the host and target at the same location. This will ensure that all the libraries required are available on both sides. If you want to use the default libraries on the host there is no need the install anything on the target.

The following script installs in /opt/codesourcery:


sudo mkdir /opt/codesourcery
cd /opt/codesourcery
sudo chown "$USERNAME" .
chmod g+ws .
umask 2
tar -xvf arm-2009q1-203-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2

Profile #