Cross-compilation e depuração para ARM/Android
Primeiro, certifique-se de que você pode compilar com GN.
Em seguida, adicione android
ao seu arquivo de configuração .gclient
.
target_os = ['android'] # Adicione isso para fazer o checkout de coisas do Android.
O campo target_os
é uma lista, então se você também estiver construindo em Unix ficará assim:
target_os = ['android', 'unix'] # Múltiplos sistemas operacionais alvo.
Execute gclient sync
, e você obterá um grande checkout em ./third_party/android_tools
.
Habilite o modo desenvolvedor no seu telefone ou tablet, e ative a depuração USB, seguindo as instruções aqui. Também tenha à mão a ferramenta adb
no seu caminho. Ela está no seu checkout em ./third_party/android_sdk/public/platform-tools
.
Usando gm
Use o script tools/dev/gm.py
para compilar automaticamente os testes do V8 e executá-los no dispositivo.
alias gm=/path/to/v8/tools/dev/gm.py
gm android_arm.release.check
Este comando envia os binários e testes para o diretório /data/local/tmp/v8
no dispositivo.
Compilação manual
Use v8gen.py
para gerar uma compilação de release ou debug para ARM:
tools/dev/v8gen.py arm.release
Em seguida, execute gn args out.gn/arm.release
e certifique-se de ter as seguintes chaves:
target_os = "android" # Essas linhas precisam ser alteradas manualmente
target_cpu = "arm" # pois o v8gen.py assume uma construção de simulador.
v8_target_cpu = "arm"
is_component_build = false
As chaves devem ser as mesmas para compilações de debug. Se você estiver compilando para um dispositivo arm64, como o Pixel C, que suporta binários de 32 bits e 64 bits, as chaves devem ser assim:
target_os = "android" # Essas linhas precisam ser alteradas manualmente
target_cpu = "arm64" # pois o v8gen.py assume uma construção de simulador.
v8_target_cpu = "arm64"
is_component_build = false
Agora, compile:
ninja -C out.gn/arm.release d8
Use adb
para copiar os arquivos binários e de snapshot para o telefone:
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>
Depuração
d8
Depurar remotamente o d8
em um dispositivo Android é relativamente simples. Primeiro, inicie o gdbserver
no dispositivo Android:
bullhead:/data/local/tmp/v8/bin $ gdbserver :5039 $D8 <arguments>
Depois, conecte-se ao servidor no dispositivo host.
adb forward tcp:5039 tcp:5039
gdb $D8
gdb> target remote :5039
gdb
e gdbserver
precisam ser compatíveis entre si; em caso de dúvida, use os binários do Android NDK. Observe que, por padrão, o binário d8
é despojado (informações de depuração removidas), mas $OUT_DIR/exe.unstripped/d8
contém o binário sem despojar.
Logs
Por padrão, algumas saídas de depuração do d8
acabam no log do sistema Android, o qual pode ser visualizado usando logcat
. Infelizmente, às vezes uma parte de uma saída de depuração específica é dividida entre o log do sistema e adb
, e outras vezes parece estar completamente ausente. Para evitar esses problemas, recomenda-se adicionar a seguinte configuração aos gn args
:
v8_android_log_stdout = true
Problemas com ponto flutuante
A configuração gn args
arm_float_abi = "hard"
, que é usada pelo V8 Arm GC Stress bot, pode resultar em comportamentos completamente sem sentido quando utilizado em hardware diferente do usado pelo GC stress bot (por exemplo, no Nexus 7).
Usando Sourcery G++ Lite
O pacote de compilador cruzado Sourcery G++ Lite é uma versão gratuita do Sourcery G++ da CodeSourcery. Há uma página para o GNU Toolchain for ARM Processors. Determine a versão de que você precisa para sua combinação de host e alvo.
As instruções a seguir usam 2009q1-203 para ARM GNU/Linux, e, se estiver usando uma versão diferente, altere os URLs e TOOL_PREFIX
abaixo de acordo.
Instalando no host e no alvo
A maneira mais simples de configurar isso é instalar o pacote completo do Sourcery G++ Lite tanto no host quanto no alvo, na mesma localização. Isso garantirá que todas as bibliotecas necessárias estejam disponíveis em ambos os lados. Se você quiser usar as bibliotecas padrão no host, não é necessário instalar nada no alvo.
O script a seguir é instalado em /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
Perfil
-
Compile um binário, envie-o para o dispositivo e mantenha uma cópia dele no host:
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 -
Obtenha um log de perfilamento e copie-o para o host:
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 ./ -
Abra o arquivo
v8.log
no seu editor favorito e edite a primeira linha para corresponder ao caminho completo do bináriod8-version.under.test
na sua estação de trabalho (em vez do caminho/data/local/tmp/v8/bin/
que estava no dispositivo) -
Execute o processador de ticks com o
d8
do host e um binárionm
apropriado:cp out/x64.release/d8 . # necessário apenas uma vez
cp out/x64.release/natives_blob.bin . # necessário apenas uma vez
cp out/x64.release/snapshot_blob.bin . # necessário apenas uma vez
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