Android valgrind построить не удается
Здравствуйте, я пытаюсь построить valgrind для android-arm. На Linux Mint 13 это не удается с:
$ make
echo "# This is a generated file, composed of the following suppression rules:" > default.supp
echo "# " exp-sgcheck.supp xfree-3.supp xfree-4.supp glibc-2.X-drd.supp glibc-2.34567-NPTL-helgrind.supp glibc-2.X.supp >> default.supp
cat exp-sgcheck.supp xfree-3.supp xfree-4.supp glibc-2.X-drd.supp glibc-2.34567-NPTL-helgrind.supp glibc-2.X.supp >> default.supp
make all-recursive
make[1]: Entering directory `/home/matt/Desktop/valgrind/valgrind-3.8.1'
Making all in include
make[2]: Entering directory `/home/matt/Desktop/valgrind/valgrind-3.8.1/include'
make[2]: Nothing to be done for `all'.
make[2]: Leaving directory `/home/matt/Desktop/valgrind/valgrind-3.8.1/include'
Making all in VEX
make[2]: Entering directory `/home/matt/Desktop/valgrind/valgrind-3.8.1/VEX'
make all-am
make[3]: Entering directory `/home/matt/Desktop/valgrind/valgrind-3.8.1/VEX'
gcc -DHAVE_CONFIG_H -I. -I.. -I.. -I../include -I../VEX/pub -DVGA_arm=1 -DVGO_linux=1 -DVGP_arm_linux=1 -DVGPV_arm_linux_vanilla=1 -Ipriv -m32 -O2 -g -Wall -Wmissing-prototypes -Wshadow -Wpointer-arith -Wstrict-prototypes -Wmissing-declarations -Wno-format-zero-length -fno-strict-aliasing -fno-builtin -marm -mcpu=cortex-a8 -Wbad-function-cast -Wcast-qual -Wcast-align -fstrict-aliasing -Wno-long-long -Wno-pointer-sign -fno-stack-protector -MT libvex_arm_linux_a-main_globals.o -MD -MP -MF .deps/libvex_arm_linux_a-main_globals.Tpo -c -o libvex_arm_linux_a-main_globals.o `test -f 'priv/main_globals.c' || echo './'`priv/main_globals.c
gcc: warning: ‘-mcpu=’ is deprecated; use ‘-mtune=’ or ‘-march=’ instead
cc1: error: unrecognised command line option ‘-marm’
priv/main_globals.c:1:0: error: bad value (cortex-a8) for -mtune= switch
make[3]: *** [libvex_arm_linux_a-main_globals.o] Error 1
make[3]: Leaving directory `/home/matt/Desktop/valgrind/valgrind-3.8.1/VEX'
make[2]: *** [all] Error 2
make[2]: Leaving directory `/home/matt/Desktop/valgrind/valgrind-3.8.1/VEX'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/matt/Desktop/valgrind/valgrind-3.8.1'
make: *** [all] Error 2
Я использую ndk-r8e и valgrind 3.8.1. Настройка заканчивается на:
Maximum build arch: arm
Primary build arch: arm
Secondary build arch:
Build OS: linux
Primary build target: ARM_LINUX
Secondary build target:
Platform variant: vanilla
Primary -DVGPV string: -DVGPV_arm_linux_vanilla=1
Default supp files: exp-sgcheck.supp xfree-3.supp xfree-4.supp glibc-2.X-drd.supp glibc-2.34567-NPTL-helgrind.supp glibc-2.X.supp
Что я могу сделать, чтобы исправить это? Кроме того, есть ли готовые бинарные файлы valgrind для android-arm, которые я могу использовать?
5 ответов:
Для сборки и установки Valgrind для Android используйте скрипт bash ниже, который я предпочитаю называть build_valgrind.sh
Для работы с RUN_HELLO_JNI_THROUGH_VALGRIND=true вам потребуются два дополнительных скрипта (bootstrap_valgrind.sh, start_valgrind.sh ) в каталоге, из которого вы запускаете приведенный ниже скрипт.
Запуск скрипта с флагом RUN_HELLO_JNI_THROUGH_VALGRIND=true позволит построить приложение hello-jni из каталога samples внутри Android NDK HOME, разверните его на телефоне и запустите через Valgrind, используя либо callgrind, либо memcheck tool, который вы можете указать в start_valgrind.sh сценарий.
Два других сценария описаны здесь: https://stackoverflow.com/a/19235439/313113
Вот моя структура каталогов:
|-- build_valgrind.sh (the script below) |-- bootstrap_valgrind.sh (second script from https://stackoverflow.com/a/19235439/313113) |-- start_valgrind.sh (first script from https://stackoverflow.com/a/19235439/313113) |-- valgrind-3.10.0 (will be extracted by build_valgrind.sh) `-- valgrind-3.10.0.tar.bz2 (will be downloaded by build_valgrind.sh)
Я проверил, что его работа (memcheck и callgrind tools) на устройстве Samsung Galaxy Nexus с CyanogenMod 10.2.1 и Android 4.3.1 и CyanogenMod 11 20140804 снимок, Android 4.4.4
Вы можете увидеть размер файла сгенерированного вывода с помощью:
adb shell ls -lR "/sdcard/*grind*"
The build_valgrind.sh сценарий:
#!/usr/bin/env bash #set -x function extract() { if [ -f "$1" ] ; then case "$1" in *.tar.bz2) tar xvjf "$1" ;; *.tar.gz) tar xvzf "$1" ;; *.bz2) bunzip2 "$1" ;; *.rar) unrar x "$1" ;; *.gz) gunzip "$1" ;; *.tar) tar xvf "$1" ;; *.tbz2) tar xvjf "$1" ;; *.tgz) tar xvzf "$1" ;; *.zip) unzip "$1" ;; *.Z) uncompress "$1" ;; *.7z) 7z x "$1" ;; *) echo "$1 cannot be extracted via >extract<" ;; esac else echo "'$1' is not a valid file" fi } RUN_HELLO_JNI_THROUGH_VALGRIND=true VALGRIND_VERSION="3.10.0" VALGRIND_EXTENSION=".tar.bz2" VALGRIND_DIRECTORY="valgrind-${VALGRIND_VERSION}" VALGRIND_TARBALL="valgrind-${VALGRIND_VERSION}${VALGRIND_EXTENSION}" # Only download Valgrind tarball again if not already downloaded if [[ ! -f "${VALGRIND_TARBALL}" ]]; then wget -v -nc "http://valgrind.org/downloads/${VALGRIND_TARBALL}" fi # Only extract Valgrind tarball again if not already extracted if [[ ! -d "$VALGRIND_DIRECTORY" ]]; then extract "$VALGRIND_TARBALL" fi # Ensure ANDROID_NDK_HOME is set if [[ ! -z "$ANDROID_NDK_HOME" ]]; then export ANDROID_NDK_HOME="$HOME/Software/Android/android-ndk-r10c" fi # Ensure ANDOID_SDK_HOME is set if [[ ! -z "$ANDROID_SDK_HOME" ]]; then export ANDROID_SDK_HOME="$HOME/Software/Android/android-sdk/" fi if [[ ! -d "$VALGRIND_DIRECTORY" ]]; then echo "Problem with extracting Valgrind from $VALGRIND_TARBALL into $VALGRIND_DIRECTORY!!!" exit -1 fi # Move to extracted directory cd "$VALGRIND_DIRECTORY" # ARM Toolchain ARCH_ABI="arm-linux-androideabi-4.9" export AR="$ANDROID_NDK_HOME/toolchains/${ARCH_ABI}/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar" export LD="$ANDROID_NDK_HOME/toolchains/${ARCH_ABI}/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ld" export CC="$ANDROID_NDK_HOME/toolchains/${ARCH_ABI}/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc" export CXX="$ANDROID_NDK_HOME/toolchains/${ARCH_ABI}/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++" [[ ! -d "$ANDROID_NDK_HOME" || ! -f "$AR" || ! -f "$LD" || ! -f "$CC" || ! -f "$CXX" ]] && echo "Make sure AR, LD, CC, CXX variables are defined correctly. Ensure ANDROID_NDK_HOME is defined also" && exit -1 # Configure build export HWKIND="nexus_s" ANDROID_PLATFORM=android-18 export CPPFLAGS="--sysroot=$ANDROID_NDK_HOME/platforms/${ANDROID_PLATFORM}/arch-arm -DANDROID_HARDWARE_$HWKIND" export CFLAGS="--sysroot=$ANDROID_NDK_HOME/platforms/${ANDROID_PLATFORM}/arch-arm" # BUG: For some reason file command is unable to detect if the file does not exist with ! -f , it says it doesn't exist even when it does!!! BUILD=false if [[ "${VALGRIND_DIRECTORY}/Inst/data/local/Inst/bin/valgrind" = *"No such file or directory"* ]]; then BUILD=true fi if [[ "$BUILD" = true ]]; then ./configure --prefix="/data/local/Inst" \ --host="armv7-unknown-linux" \ --target="armv7-unknown-linux" \ --with-tmpdir="/sdcard " [[ $? -ne 0 ]] && echo "Can't configure!" && exit -1 # Determine the number of jobs (commands) to be run simultaneously by GNU Make NO_CPU_CORES=$(grep -c ^processor /proc/cpuinfo) if [ $NO_CPU_CORES -le 8 ]; then JOBS=$(($NO_CPU_CORES+1)) else JOBS=${NO_CPU_CORES} fi # Compile Valgrind make -j "${JOBS}" [[ $? -ne 0 ]] && echo "Can't compile!" && exit -1 # Install Valgrind locally make -j "${JOBS}" install DESTDIR="$(pwd)/Inst" [[ $? -ne 0 ]] && echo "Can't install!" && exit -1 fi # Push local Valgrind installtion to the phone if [[ $(adb shell ls -ld /data/local/Inst/bin/valgrind) = *"No such file or directory"* ]]; then adb root adb remount adb shell "[ ! -d /data/local/Inst ] && mkdir /data/local/Inst" adb push Inst / adb shell "ls -l /data/local/Inst" # Ensure Valgrind on the phone is running adb shell "/data/local/Inst/bin/valgrind --version" # Add Valgrind executable to PATH (this might fail) adb shell "export PATH=$PATH:/data/local/Inst/bin/" fi if [ $RUN_HELLO_JNI_THROUGH_VALGRIND = true ]; then PACKAGE="com.example.hellojni" # The location of the Hello JNI sample application HELLO_JNI_PATH="$ANDROID_NDK_HOME/samples/hello-jni" pushd "$HELLO_JNI_PATH" # Update build target to the desired Android SDK version ANDROID_PROJECT_TARGET="android-18" android update project --target "$ANDROID_PROJECT_TARGET" --path . --name hello-jni --subprojects # Enable Android NDK build with Ant echo '<?xml version="1.0" encoding="utf-8"?> <project name="HelloJni" basedir="." default="debug"> <target name="-pre-build"> <exec executable="${ndk.dir}/ndk-build" failonerror="true"/> </target> <target name="clean" depends="android_rules.clean"> <exec executable="${ndk.dir}/ndk-build" failonerror="true"> <arg value="clean"/> </exec> </target> </project> ' > "custom_rules.xml" # Set NDK HOME for Ant (only if not already set) if ! grep -P -q "ndk.dir=.+" "local.properties" ; then echo -e "\nndk.dir=$ANDROID_NDK_HOME" >> "local.properties" fi # Fix for Java 8 warning (warning: [options] source value 1.5 is obsolete and will be removed in a future release) echo "java.compilerargs=-Xlint:-options" >> "ant.properties" # Workaround INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES error adb uninstall "$PACKAGE" # Build Hello JNI project in debug mode and install it on the device ant clean && ant debug && ant installd popd cd .. # Start HelloJNI app adb shell am start -a android.intent.action.MAIN -n $PACKAGE/.HelloJni # Make the script executable chmod a+x bootstrap_valgrind.sh # Run application through Valgrind on the phone /usr/bin/env bash bootstrap_valgrind.sh adb shell ls -lR "/sdcard/*grind*" adb shell ls -lR "/storage/sdcard0/*grind*" adb shell ls -lR "/storage/sdcard1/*grind*" fi exit 0
Это заставляет valgrind компилировать для меня на linux. (используя android-ndk-r8e и valgrind-3.8.1)
Не было никакой необходимости бежать. autogen.sh с тех пор, как я скачал смоляной шар с сайта.
Также убедитесь, что строка
TOOLCHAIN=
указывает на допустимую цепочку инструментов.export NDK_HOME=$HOME/Downloads/android-ndk-r8e export HWKIND=generic export TOOLCHAIN=$NDK_HOME/toolchains/arm-linux-androideabi-4.7/prebuilt/linux-x86_64/bin/arm-linux-androideabi export AR=$TOOLCHAIN-ar export LD=$TOOLCHAIN-ld export CC=$TOOLCHAIN-gcc CPPFLAGS="--sysroot=$NDK_HOME/platforms/android-14/arch-arm -DANDROID_HARDWARE_$HWKIND" \ CFLAGS="--sysroot=$NDK_HOME/platforms/android-14/arch-arm" \ ./configure --prefix=/data/local/Inst \ --host=armv7-unknown-linux --target=armv7-unknown-linux \ --with-tmpdir=/sdcard make
В конце концов он пришел с ошибкой компиляции, говоря
$NDK_HOME/platforms/android-14/arch-arm/usr/include/elf.h:58:3: error: unknown type name 'uint32_t'
Похоже, кто-то забыл добавить
#include <stdint.h>
где-то. Чтобы исправить это, я отредактировал$NDK_HOME/platforms/android-14/arch-arm/usr/include/elf.h
и добавил#include <stdint.h>
в раздел include этого заголовка. Примечание: это, вероятно, не лучшее исправление, но это тот, который я придумал, что исправил ошибки компиляции.
На mac я смог заставить его компилироваться вплоть до части
unknown type uint32_t
, изменив способ проверки версии ядра скриптом configure.Внутри скрипта configure найдите строку
kernel=`uname -r`
и измените ее наkernel=3.9.2
. (Есть две строкиkernel=`uname -r`
, замените первую или обе, Если вам так хочется)Это останавливает сценарий configure от просмотра хоста ядро при принятии решения о том, как оно должно строить valgrind. (
uname -r
захватывает ядро хоста)Я считаю, что добавление
#include <stdint.h>
кelf.h
должно работать на mac, но я его не тестировал.
В Android tutorial один вариант пропущен RANLIB, после того как я установил его-я, наконец, скомпилировал valgrind-3.11.0 на osx для android
#/bin/sh echo "NKDROOT: " $NDKROOT export ANRDOID_TOOLCHAIN="arm-linux-androideabi-4.9" # Set up toolchain paths. # # For ARM export AR=$NDKROOT/toolchains/$ANRDOID_TOOLCHAIN/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-ar export LD=$NDKROOT/toolchains/$ANRDOID_TOOLCHAIN/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-ld export CC=$NDKROOT/toolchains/$ANRDOID_TOOLCHAIN/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc export CXX=$NDKROOT/toolchains/$ANRDOID_TOOLCHAIN/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-g++ export RANLIB=$NDKROOT/toolchains/$ANRDOID_TOOLCHAIN/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-ranlib echo "AR: " $AR echo "LD: " $LD echo "CC: " $CC echo "CXX: " $CXX [[ ! -d "$NDKROOT" || ! -f "$AR" || ! -f "$LD" || ! -f "$CC" || ! -f "$CXX" ]] && echo "Make sure AR, LD, CC, CXX variables are defined correctly. Ensure NDKROOT is defined also" && exit -1 ./autogen.sh #if [ $? -ne 0 ] #then # exit 1 #else # echo "autogen success!" #fi # for ARM ANDROID_PLATFORM=android-3 ANDROID_SYSROOT="$NDKROOT/platforms/${ANDROID_PLATFORM}/arch-arm" echo "SYSROOT: " $ANDROID_SYSROOT export HWKIND=generic export CPPFLAGS="--sysroot=$ANDROID_SYSROOT -DANDROID_HARDWARE_$HWKIND" export CFLAGS="--sysroot=$ANDROID_SYSROOT -DANDROID_HARDWARE_$HWKIND" export LDFLAGS="--sysroot=$ANDROID_SYSROOT -DANDROID_HARDWARE_$HWKIND" export ARFLAGS="--sysroot=$ANDROID_SYSROOT -DANDROID_HARDWARE_$HWKIND" ./configure \ --prefix=/data/local/Inst \ --host=armv7-unknown-linux --target=armv7-unknown-linux \ --with-tmpdir=/sdcard if [ $? -ne 0 ] then exit 1 else echo "configure success!" fi # note: on android emulator, android-14 platform was also tested and works. # It is not clear what this platform nr really is. make -j7 if [ $? -ne 0 ] then exit 1 else echo "build success!" fi make -j7 install DESTDIR=`pwd`/Inst
Проблема заключалась в том, что сценарий configure игнорировал переменные окружения. Для настройки файла make я сделал следующее:
sudo ./configure --prefix=/data/local/Inst --host=armv7-unknown-linux --target=armv7-unknown-linux --with-tmpdir=/sdcard0 CPPFLAGS="--sysroot=$NDKROOT/platforms/android-3/arch-arm -DANDROID_HARDWARE_$HWKIND" CFLAGS="--sysroot=$NDKROOT/platforms/android-3/arch-arm" CC=$CC LD=$LD AR=$AR
Это гарантирует, что переменные установлены правильно и работает с Linux Mint 13. Однако он не работает на OSX Mountain Lion. Я бы посоветовал всем, кто использует OSX без доступа к установке linux, попробовать использовать linux на виртуальной машине.