メインコンテンツまでスキップ

ARM/Androidのクロスコンパイルとデバッグ

まず、GNでビルドすることができることを確認します。

次に、android.gclient構成ファイルに追加します。

target_os = ['android']  # Android関連のものがチェックアウトされるように追加。

target_osフィールドはリストですので、もし同時にunix上でビルドする場合は以下のようになります:

target_os = ['android', 'unix']  # 複数のターゲットOS。

gclient syncを実行すると、./third_party/android_tools配下に大規模なチェックアウトが行われます。

スマートフォンやタブレットで開発者モードを有効にし、USBデバッグをオンにしてください。手順についてはこちらをご覧ください。また、便利なadbツールをパスに追加してください。adbはチェックアウト内の./third_party/android_sdk/public/platform-toolsにあります。

gmの使用

tools/dev/gm.pyスクリプトを使用して、V8のテストを自動的にビルドし、デバイスで実行できます。

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

このコマンドは、バイナリとテストをデバイスの/data/local/tmp/v8ディレクトリに送ります。

手動ビルド

v8gen.pyを使用してARMのリリースまたはデバッグビルドを生成します:

tools/dev/v8gen.py arm.release

次にgn args out.gn/arm.releaseを実行し、以下のキーが含まれていることを確認してください:

target_os = "android"      # 以下の行は手動で変更する必要があります
target_cpu = "arm" # v8gen.pyはシミュレーター用ビルドを想定しています。
v8_target_cpu = "arm"
is_component_build = false

デバッグビルドでもキーは同じです。Pixel Cのような32ビットと64ビットの両方のバイナリをサポートするarm64デバイスの場合、キーは以下のようになります:

target_os = "android"      # 以下の行は手動で変更する必要があります
target_cpu = "arm64" # v8gen.pyはシミュレーター用ビルドを想定しています。
v8_target_cpu = "arm64"
is_component_build = false

次にビルドします:

ninja -C out.gn/arm.release d8

adbを使用してバイナリとスナップショットファイルを電話にコピーします:

adb shell 'mkdir -p /data/local/tmp/v8/bin'
adb push out.gn/arm.release/d8 /data/local/tmp/v8/bin
adb push out.gn/arm.release/icudtl.dat /data/local/tmp/v8/bin
adb push out.gn/arm.release/snapshot_blob.bin /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!'
"w00t!"
d8>

デバッグ

d8

Androidデバイスでのd8のリモートデバッグは比較的簡単です。まず、Androidデバイスでgdbserverを起動します:

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

次に、ホストデバイスでサーバーに接続します。

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

gdbgdbserverは互換性がある必要があります。疑問がある場合はAndroid NDKのバイナリを使用してください。デフォルトでd8バイナリはストリップされています(デバッグ情報が削除されています)が、$OUT_DIR/exe.unstripped/d8にはストリップされていないバイナリが含まれています。

ロギング

デフォルトでは、d8の一部のデバッグ出力はAndroidシステムログに記録されます。logcatを使用してログをダンプできます。しかし、特定のデバッグ出力がシステムログとadbの間で分割されたり、完全に欠落しているように見える場合があります。これらの問題を回避するために、以下の設定をgn argsに追加することをお勧めします:

v8_android_log_stdout = true

浮動小数点の問題

V8 Arm GCストレスボットで使用されるgn args設定arm_float_abi = "hard"は、GCストレスボットが使用しているハードウェアとは異なるハードウェア(例: Nexus 7)で、全く意味不明なプログラム動作を引き起こす可能性があります。

Sourcery G++ Liteの使用

Sourcery G++ Liteクロスコンパイラスイートは、CodeSourceryが提供するSourcery G++の無料版です。ARMプロセッサ用GNU Toolchainのページがあります。ホストとターゲットの組み合わせに必要なバージョンを決定してください。

以下の手順では、ARM GNU/Linux用の2009q1-203を使用しています。別のバージョンを使用する場合は、以下のURLとTOOL_PREFIXを変更してください。

ホストとターゲットでのインストール

最も簡単な設定方法は、完全なSourcery G++ Liteパッケージをホストとターゲットの両方に同じ場所にインストールすることです。これにより必要なすべてのライブラリが両方で利用可能になります。ホストでデフォルトライブラリを使用する場合、ターゲット側には何もインストールする必要はありません。

次のスクリプトは/opt/codesourceryにインストールします:

#!/bin/sh

sudo mkdir /opt/codesourcery
cd /opt/codesourcery
sudo chown "$USERNAME" .
chmod g+ws .
umask 2
wget http://www.codesourcery.com/sgpp/lite/arm/portal/package4571/public/arm-none-linux-gnueabi/arm-2009q1-203-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
tar -xvf arm-2009q1-203-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2

プロファイル

  • バイナリをコンパイルし、デバイスにプッシュし、ホストにもそのコピーを保持する:

    adb shell cp /data/local/tmp/v8/bin/d8 /data/local/tmp/v8/bin/d8-version.under.test
    cp out.gn/arm.release/d8 ./d8-version.under.test
  • プロファイリングログを取得し、それをホストにコピーする:

    adb push benchmarks /data/local/tmp
    adb shell cd /data/local/tmp/benchmarks; ../v8/bin/d8-version.under.test run.js --prof
    adb shell /data/local/tmp/v8/bin/d8-version.under.test benchmark.js --prof
    adb pull /data/local/tmp/benchmarks/v8.log ./
  • お好きなエディタでv8.logを開き、最初の行を編集して、作業中のワークステーション上にあるd8-version.under.testバイナリのフルパスに一致させます(デバイス上では/data/local/tmp/v8/bin/パスでした)

  • ホストのd8と適切なnmバイナリを使用してティックプロセッサを実行する:

    cp out/x64.release/d8 .  # 一度だけ必要
    cp out/x64.release/natives_blob.bin . # 一度だけ必要
    cp out/x64.release/snapshot_blob.bin . # 一度だけ必要
    tools/linux-tick-processor --nm=$(pwd)/third_party/android_ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-nm