Android valgrind构建失败

时间:2013-05-08 21:38:26

标签: android macos android-ndk valgrind configure

您好我正在尝试为android-arm构建valgrind。在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 

我该怎么做才能解决这个问题?或者,我可以使用任何预先构建的android-arm valgrind二进制文件吗?

5 个答案:

答案 0 :(得分:18)

要构建和安装Valgrind for Android,请使用下面的bash脚本,我更喜欢将其命名为 build_valgrind.sh

要使用RUN_HELLO_JNI_THROUGH_VALGRIND = true运行,您需要在运行以下脚本的目录中添加两个额外的脚本( bootstrap_valgrind.sh start_valgrind.sh )。

使用RUN_HELLO_JNI_THROUGH_VALGRIND = true标志运行脚本将从Android NDK HOME中的samples目录构建hello-jni应用程序,将其部署到手机并使用callgrind或memcheck工具通过Valgrind运行,您可以使用在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)

我已经在三星Galaxy Nexus设备上使用CyanogenMod 10.2.1和Android 4.3.1以及CyanogenMod 11 20140804快照,Android 4.4.4测试了它的工作(memcheck和callgrind工具)

您可以使用以下代码查看生成的输出的文件大小:adb shell ls -lR "/sdcard/*grind*"

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 

答案 1 :(得分:2)

这可以在linux上为我编译valgrind。 (使用android-ndk-r8e和valgrind-3.8.1)

因为我从网站上下载了tar球,所以没有必要运行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上,我可以通过更改configure脚本检查内核版本的方式来编译直到unknown type uint32_t部分。

在配置脚本中搜索行kernel=`uname -r`并将其更改为kernel=3.9.2。 (如果您愿意,有两条kernel=`uname -r`行替换第一行或两行;

这会阻止configure脚本在决定如何构建valgrind时查看主机内核。 (uname -r抓取主机内核)

我认为将#include <stdint.h>添加到elf.h应该适用于mac,但我还没有测试过。

答案 2 :(得分:2)

在Android教程中

错过了一个选项 RANLIB,在我设置之后 - 我终于在osx上编译了valgrind-3.11.0 for 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

答案 3 :(得分:1)

我遇到的问题是配置脚本忽略了环境变量。要配置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。

答案 4 :(得分:-1)

当我尝试使用r8e构建时,我收到此错误。但是,如果您使用 rXb-ndk r7b或r8b ),则此错误消息不会出现。