web-dev-qa-db-ja.com

AndroidのOpenSSHのクロスコンパイル

Androidに基づいて Stack Overflowでのこの回答 )のOpenSSHのコンパイルに取り組んでいます。

これが私がこれまでにしたことです:

  • Ubuntu 14.04AMD64でのビルド。
  • apt-get install build-essential gcc-arm-linux-androideabi

Zlibをダウンロードして、次の手順を実行します。

cd zlib-1.2.8
./configure --prefix=/vagrant/build
make CC=arm-linux-androideabi-gcc
make install

これはmakeステップで失敗します。

gcc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map -O3  -fPIC -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN -o libz.so.1.2.8 adler32.lo crc32.lo deflate.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo zutil.lo compress.lo uncompr.lo gzclose.lo gzlib.lo gzread.lo gzwrite.lo  -lc
/usr/bin/ld: crc32.lo: Relocations in generic ELF (EM: 40)
crc32.lo: error adding symbols: File in wrong format
collect2: error: ld returned 1 exit status
make: *** [libz.so.1.2.8] Error 1

ここで何が欠けていますか? zlibをビルドできるようにするために知っておく必要のあることは他にありますか?

次のプロセスは、OpenSSLを構築することです。

cd openssl-1.0.1h/
./Configure dist --prefix=/vagrant/build/
make CC="arm-linux-androideabi-gcc" AR="arm-linux-androideabi-ar r" RANLIB="arm-linux-androideabi-ranlib"
make install

これもmakeステップで失敗します。

make[2]: Entering directory `/vagrant/openssl-1.0.1h/apps'
( :; LIBDEPS="${LIBDEPS:--L.. -lssl  -L.. -lcrypto }"; LDCMD="${LDCMD:-cc}"; LDFLAGS="${LDFLAGS:--O}"; LIBPATH=`for x in $LIBDEPS; do echo $x; done | sed -e 's/^ *-L//;t' -e d | uniq`; LIBPATH=`echo $LIBPATH | sed -e 's/ /:/g'`; LD_LIBRARY_PATH=$LIBPATH:$LD_LIBRARY_PATH ${LDCMD} ${LDFLAGS} -o ${APPNAME:=openssl} openssl.o verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o gendh.o errstr.o ca.o pkcs7.o crl2p7.o crl.o rsa.o rsautl.o dsa.o dsaparam.o ec.o ecparam.o x509.o genrsa.o gendsa.o genpkey.o s_server.o s_client.o speed.o s_time.o apps.o s_cb.o s_socket.o app_Rand.o version.o sess_id.o ciphers.o nseq.o pkcs12.o pkcs8.o pkey.o pkeyparam.o pkeyutl.o spkac.o smime.o cms.o Rand.o engine.o ocsp.o prime.o ts.o srp.o ${LIBDEPS} )
/usr/bin/ld: openssl.o: Relocations in generic ELF (EM: 40)
/usr/bin/ld: openssl.o: Relocations in generic ELF (EM: 40)
openssl.o: error adding symbols: File in wrong format
collect2: error: ld returned 1 exit status
make[2]: *** [link_app.] Error 1
make[2]: Leaving directory `/vagrant/openssl-1.0.1h/apps'
make[1]: *** [openssl] Error 2
make[1]: Leaving directory `/vagrant/openssl-1.0.1h/apps'
make: *** [build_apps] Error 1

繰り返しますが、同じ問題が発生しているようで、書き込んだファイルを読み取ることができません。

私はまだOpenSSHをコンパイルする最終ステップに到達していませんが、これは私がそれを行うと私が想定している方法です。

cd openssh-6.6p1
./configure --Host=arm-linux --with-libs --with-zlib=$HOME/zlibArm --with-ssl-dir=$HOME/opensslArm --disable-etc-default-login CC=gcc-arm-linux-gnueabi-gcc AR=gcc-arm-linux-gnueabi-ar
make

arm-linux-androideabiでコンパイルするときに、上記のコンパイルがZlibとOpenSSLで失敗するのはなぜですか? ARMでAndroid)用にOpenSSH(特にクライアントとエージェント)をコンパイルするにはどうすればよいですか?

6
Naftuli Kay

ビルドが失敗する理由は、Makeがプラットフォームのリンカー(/ usr/bin/ld)を使用して、arm-linux-androideabi-gccが生成するオブジェクトファイルをリンクしているためです。正しいツールを探すようにconfigureに指示してから、コンパイルを再試行する必要があります。また、Android NDKをどこかにインストールし、NDK_ROOTをその場所にポイントする必要があります。これはAndroidターゲット用にプログラムをコンパイルするために使用する小さなスクリプトです。 。

これはかなり遅い応答だと思いますが、とにかく誰かに役立つことを願っています。

#!/bin/bash
unset CFLG CXXFLG LIBS CFLAGS LDFLAGS CXXFLAGS CPPFLAGS SYSROOT ALT_TOOLCHAIN DO_CONFIG NEWARGV PRINT_CONFIG HOSTARG OLDDIR NOHOST NO_ARGS 

# Set default values here
STL="gnustl_shared"
Arch="armeabi-v7a"
PLATFORM="Android-15"
Host="arm-none-linux"
CONFIG_SCRIPT="./configure"
CROSS_COMPILE="arm-linux-androideabi"
NDK_ROOT=${NDK_ROOT:-"/opt/Android-ndk-r10e"}


PLAT_CHOICES=$(eval "echo -n Android-{3,4,5,8,9,{12..19},21}")
Arch_CHOICES="arm armeabi armeabi-v7a armeabi-v7a-hard"
STL_CHOICES=$(eval "echo -n gnustl_{static,shared} stlport_{static,shared} gabi++_{static,shared} c++_{static,shared}")
STL_DEFS="gnustl stlport gabi++ c++ libstdc++"
WARN="-Wformat -Werror=format-security -Werror"
PIC="-fpic -DPIC"
DEF_Arch=$Arch
SED="sed"


usage() {
    echo "Usage: "
    echo -n "  `basename $0` [-Nhwe]"
    echo "[-H Host] [-I include] [-D def] [-U undef] [-L libdir]"
    printf '          %-18s\n' \
        "[-l lib] [-c conf_args] [-v gccver] [-a Arch] [-b path]" \
        "[-p platform] [-s cxx_stl] [-f script] [-P prefix]" \
        "[-n nohost] [-d chdir] [-t target] [-x crossprefix]" \
        "[VAR=VALUE...] [--<configure-option>...] "
    echo
    echo "Note: All unprocessed arguments are passed through to the configure script"
    echo
    echo "Options:"
    printf '  %s, %-18s %s\n' "-a" "--Arch" "specify the target Arch (see note 2)"
    printf '  %s, %-18s %s\n' "-b" "--toolchain-bin" "specify the location of an alternate toolchain to be added to \$PATH"
    printf '  %s, %-18s %s\n' "-c" "--config-args" "args to pass through to the configure script, to avoid conflicts with this script's arg parser. (see note 2)"
    printf '  %s, %-18s %s\n' "-d" "--chdir" "directory to change to before doing anything"
    printf '  %s, %-18s %s\n' "-D" "--define" "list of symbols, as either -Dname=value, or -Dname, to be added to cflags as -D<sym> (see note 2)"
    printf '  %s, %-18s %s\n' "-e" "--echo" "print configure args instead of executing command"
    printf '  %s, %-18s %s\n' "-f" "--config-script" "name of the configure script to execute"
    printf '  %s, %-18s %s\n' "-h" "--help" "show this help message"
    printf '  %s, %-18s %s\n' "-H" "--Host" "use an alternate Host for configure script"
    printf '  %s, %-18s %s\n' "-I" "--include" "list of directories to add to cflags as -I<dir> (see note 2)"
    printf '  %s, %-18s %s\n' "-l" "--libs" "list of libraries to add to ldflags as -l<lib> (see note 2)"
    printf '  %s, %-18s %s\n' "-L" "--libdir" "list of directories to add to ldflags as -L<dir> (see note 2)"
    printf '  %s, %-18s %s\n' "-n" "--nohost" "omit the --Host=<Host> option when echoing commands or calling configure"
    printf '  %s, %-18s %s\n' "-N" "--noargs" "omit all --options when echoing commands"
    printf '  %s, %-18s %s\n' "-p" "--platform" "specify the Android platform to target. may be <Android-N> or just <N>, where N is the api level"
    printf '  %s, %-18s %s\n' "-P" "--prefix" "specify the installation prefix. passed to configure as --prefix=<prefix>"
    printf '  %s, %-18s %s\n' "-s" "--stl" "specify the standard c++ lib to use (see note 3)"
    printf '  %s, %-18s %s\n' "-t" "--target" "specify the target to compile for with this option instead of --Host; e.g. --target=build produces --build=<Host>"
    printf '  %s, %-18s %s\n' "-U" "--undefine" "list of symbols to undefine, added to cppflags as -U<sym> (see note 2)"
    printf '  %s, %-18s %s\n' "-v" "--gccversion" "specify the version of gcc to use when targeting the Android ndk. must be 4.8 or 4.9"
    printf '  %s, %-18s %s\n' "-w" "--warn" "add compiler warning flags to cflags"
    printf '  %s, %-18s %s\n' "-x" "--crossprefix" "prefix to use when cross compiling. default = arm-linux-androideabi"
    printf '  %-22s %s\n' "--cflags" "flags to be added directly to the CFLAGS variable"
    printf '  %-22s %s\n' "--ldflags" "flags to be added directly to the LDFLAGS variable"
    printf '  %-22s %s\n' "--cxxflags" "flags to be added directly to the CXXFLAGS variable"
    printf '  %-22s %s\n' "--cppflags" "flags to be added directly to the CPPFLAGS variable"
    printf '  %-22s %s\n' "--sysroot" "change the compiler sysroot, added to CC and CXX as --sysroot=<arg>"
    printf '  %-22s %s\n' "--pic" "add -fpic and -DPIC to cflags"
    echo
    printf '  %-38s\n' "Note 1:Mode may be one of the following: <armeabi,armeabi-v7a,armeabi-v7a-hard>" 
    printf '  %-38s\n' "and may be abbriviated as: <arm, armeabi, armhf, armv7a[-hard], armv7-a[-hard], armeabi-v7a[-hard]>"
    printf '  %-38s\n' "Note 2:These options allow multiple arguments to be specified, either by specifying the option multiple times," 
    printf '  %-38s\n' "or by using a list delimited by ':' , ';' , or ','"
    printf '  %-38s\n' "Note 3:This must be one of <${STD_DEFS}>, to use a static version, add _static," 
    printf '  %-38s\n' "otherwise the shared version is used. gnustl_shared is the default when this option is omitted. "
    printf '  %-38s\n' "License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>"
    printf '  %-38s\n' "This is free software: you are free to change and redistribute it."
    printf '  %-38s\n' "There is NO WARRANTY, to the extent permitted by law."
    printf '  %-38s\n' "Copyright (C) 2015 Matt Johnson"
    exit $1
}


error() {
    echo -n "[Error]: " 2>&1
    while [ "$#" != "0" ]; do 
        echo "$1"
        shift
    done
    usage 1
}

exists() {
    local args="$@"
    local not_found=()
    for arg in ${args}; do
        local tmp_res=`${arg} 2>&1 >>/dev/null`
        if [ "$?" == "127" ]; then
            not_found+=("$arg")
        else
            local prog=`which $arg`
            if [ -z "$prog" ]; then
                not_found+=("$arg")
            else
                local progname=$(echo $arg|tr '[[:lower:]]' '[[:upper:]]')
                eval "${progname}=\${prog}"
            fi
        fi
    done
    if [ "${#not_found[@]}" -gt "0" ]; then
        local missing="${not_found[@]}"
        error "Could not find these required program(s): [ $missing ]" "Make sure they are installed before running this script again"
    fi
}

exists sed grep getopt expr mktemp

set_toolchain() {
    TC_BIN="$1"; shift
    TC_ROOT="$TC_BIN/.."
    if [ -x "$TC_BIN/$CROSS_COMPILE-gcc" ]; then
        ALT_TOOLCHAIN="$TC_BIN"
        unset TC_BIN
    else
        error "Invalid toolchain specified at $TC_BIN."
    fi
}

in_list() {
    local k=$1; shift
    local _list=$@
    for _v in ${_list}; do
        if [ "${_v}" == "${k}" ]; then
            return 0
        fi
    done
    return 1
}

set_platform() {
    local API=$(${EXPR} "$1" : '^[^0-9]*\([[:digit:]]\{1,2\}\)$')
    [ -z "$API" ] && error "Invalid platform: $1"
    local plat="Android-${API}"
    if in_list ${plat} ${PLAT_CHOICES}; then
        PLATFORM=${plat}
    else
        error "Invalid platform: $API"
    fi
}

set_stl() {
    local choice=$1
    if [ "$choice" == "libstdc++" ]; then
        STL=$choice
        return
    Elif in_list $choice $STL_DEFS ; then
        STL="${choice}_shared"
        return
    Elif in_list $choice $STL_CHOICES ; then
        STL="${choice}"
        return
    fi
    error "Invalid value for --stl: $1" "Must be one of [ $STL_CHOICES ]"
}

set_Arch() {
    local Arch_arg=$1
    case "$Arch_arg" in
        arm)
            Arch=arm ;;
        armeabi)
            Arch=armeabi ;;
        armv7a?*|armeabi-v7a*|armv7-a*)
            case "$Arch_arg" in
                *hard)
                    Arch=armeabi-v7a-hard ;;
                *)
                    Arch=armeabi-v7a ;;
            esac ;;
        armhf)
            Arch=armeabi-v7a-hard ;;
        *)
            error "Invalid value for --Arch: $1" "Must be one of [ $Arch_CHOICES ]"
    esac
}

add_args() {
    local var=$1; shift
    local args=$@
    arglist=$(echo $args | tr ":;" " ")
    eval ${var}+=\" \${arglist}\"
}

add_list() {
    local item=$1 ; shift
    local var=$1 ; shift
    local flag=$1
    inclist=$(echo $item | tr ":;" " ")
    for i in ${inclist}; do
        local _thisflag=`echo $i | ${SED} -E -e "s/^[-]?${flag}?(.*)/-${flag}\1/"`
        eval ${var}+=\" \${_thisflag}\"
    done 
}



EXARGS=$(mktemp --tmpdir=/tmp argv-XXXXX.tmp)
LONGOPTS="help,noargs,nohost,warn,echo,pic,script:,crossprefix:,chdir:,target:,toolchain-bin:,prefix:,Host:,stl:,Arch:,platform:,gccversion:,config-args:,libdir:,cflags:,ldflags:,libs:,cxxflags:,cppflags:,include:,sysroot:,define:,undefine:"
OPTSTR="NhwenH:I:D:U:L:l:c:v:m:a:p:s:f:P:b:d:t:x:"
GETOPT=`which getopt`
TEMP=`${GETOPT} --longoptions ${LONGOPTS} --options ${OPTSTR} -n ndk-fix -- "$@" 2>${EXARGS}`
while read LINE; do
    case "$LINE" in
        *unrecognized*)
            option=$(echo $LINE | ${SED} -r -e "s/^.+ '(--[^']+)'$/\1/")
            add_args "NEWARGV" "$option"
            ;;
        *)
            opt_char=$(echo $LINE | ${SED} -r -e "s/^.+ '([^'])'$/-\1/")
            echo "[Warning]: Ignoring invalid short option -- '$opt_char'"
            ;;
    esac
done<$EXARGS
unset option opt_char
rm $EXARGS
eval set -- "$TEMP"
while true; do
    case "$1" in
        -h|--help)
            usage
            ;;
        -w|--warn)
            CFLG+=" $WARN"
            CXXFLG+=" $WARN" 
            ;;
        --pic)
            add_args "CFLG" "$PIC"
            add_args "CXXFLG" "$PIC" 
            ;;
        -H|--Host)
            Host="$2" ; shift 
            ;;
        -N|--noargs)
            NO_ARGS=1
            ;;
        -t|--target)
            HOSTARG="--$(${EXPR} "$2" : "^-\?-\?\(.\+\)\$")" ; shift
            ;;
        -d|--chdir)
            OLDDIR=$(pwd)
            cd $2 ; shift
            ;;
        -e|--echo)
            PRINT_CONFIG=1 
            ;;
        -n|--nohost)
            NOHOST=1
            ;;
        -f|--script)
            CONFIG_SCRIPT="$2"
            DO_CONFIG=1 ; shift 
            ;;
        -P|--prefix)
            add_args "NEWARGV" "--prefix=$2" ; shift
            ;;
        -x|--crossprefix)
            CROSS_COMPILE="$2" ; shift 
            ;;
        -b|--toolchain-bin)
            set_toolchain "$2" ; shift 
            ;;
        -s|--stl)
            set_stl "$2" ; shift 
            ;;
        -a|--Arch)
            set_Arch "$2" ; shift 
            ;;
        -p|--platform)
            set_platform "$2" ; shift 
            ;;
        -c|--config-args)
            add_args "NEWARGV" "$2" ; shift 
            ;;
        -I|--include)
            add_list "$2" "CFLG" "I" ; shift 
            ;;
        -L|--libdir)
            add_list "$2" "LIBS" "L" ; shift 
            ;;
        -D|--define)
            add_list "$2" "CFLG" "D" ; shift 
            ;;
        -l|--libs)
            add_list "$2" "LIBS" "l" ; shift 
            ;;
        -U|--undefine)
            add_list "$2" "CFLG" "U" ; shift 
            ;;
        --cflags)
            add_args "CFLG" "$2" ; shift 
            ;;
        --ldflags)
            add_args "LIBS" "$2" ; shift 
            ;;
        --cppflags)
            add_args "CPPFLAGS" "$2" ; shift
            ;;
        --cxxflags)
            add_args "CXXFLG" "$2" ; shift 
            ;;
        --sysroot)
            SYSROOT=$1 ; shift 
            ;;
        -v|--gccversion)
            if [ "$2" == "4.9" ] || [ "$2" == "4.8" ]; then
                TCVER="$2"
            else
                echo "Invalid argument to -v or --gccversion: <$2>"
                echo "Must be either 4.8 or 4.9. defaulting to 4.8"
                TCVER="4.8"
            fi
            shift 
            ;;
        --)
            shift ; break 
            ;;
        *)
            echo "Should not have gotten here."
            echo "Error in parsing arguments -- Unexpected argument found before end-of-args: $1"
            usage
            finish
            ;;
    esac
    shift
done

TCVER=${TCVER:-4.8}
CXXVER=${TCVER:-4.8}


if [ -z "$ALT_TOOLCHAIN" ]; then
    NDK=${NDK_ROOT}/toolchains/arm-linux-androideabi-${TCVER}/prebuilt/linux-$(uname -m)/bin
    SYSROOT=${SYSROOT:-${NDK_ROOT}/platforms/${PLATFORM}/Arch-arm}
else
    NDK="$ALT_TOOLCHAIN"
    SYSROOT=${SYSROOT:-/opt/sysroot}
fi

if [ -z "$NOHOST" ]; then
    HOSTARG=${HOSTARG:---Host=$Host}
fi

declare -A cxxflag
cxxflag[armeabi]="-no-canonical-prefixes -march=armv5te -mtune=xscale -msoft-float -frtti -fexceptions -O2 -g -DNDEBUG -fomit-frame-pointer -DANDROID "
cxxflag[armeabi-v7a]="-no-canonical-prefixes -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -frtti -fexceptions -O2 -g -DNDEBUG -fomit-frame-pointer -DANDROID "
cxxflag[armeabi-v7a-hard]="-no-canonical-prefixes -march=armv7-a -mfpu=vfpv3-d16 -mhard-float -D_NDK_MATH_NO_SOFTFP=1 -frtti -fexceptions -O2 -g -DNDEBUG -fomit-frame-pointer -DANDROID  "
cxxflag[arm]=" -DANDROID -mandroid -fomit-frame-pointer"

declare -A cflag
cflag[arm]=" -DANDROID -mandroid -fomit-frame-pointer"
cflag[armeabi]="-no-canonical-prefixes -march=armv5te -msoft-float -O2 -g -DNDEBUG -fomit-frame-pointer -DANDROID "
cflag[armeabi-v7a]="-no-canonical-prefixes -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -O2 -g -DNDEBUG -fomit-frame-pointer -DANDROID "
cflag[armeabi-v7a-hard]="-no-canonical-prefixes -march=armv7-a -mfpu=vfpv3-d16 -mhard-float -D_NDK_MATH_NO_SOFTFP=1 -O2 -g -DNDEBUG -fomit-frame-pointer -DANDROID "

declare -A cxxinclude
cxxinclude[gnustl]="-I${NDK_ROOT}/sources/cxx-stl/gnu-libstdc++/${TCVER}/include -I${NDK_ROOT}/sources/cxx-stl/gnu-libstdc++/${TCVER}/libs/${Arch}/include -I${NDK_ROOT}/sources/cxx-stl/gnu-libstdc++/${TCVER}/include/backward"
cxxinclude[stlport]="-I${NDK_ROOT}/sources/cxx-stl/stlport/stlport -I${NDK_ROOT}/sources/cxx-stl/gabi++/include"
cxxinclude[stdc++]="-I${NDK_ROOT}/sources/cxx-stl/system/include"
cxxinclude[gabi++]="-I${NDK_ROOT}/sources/cxx-stl/gabi++/includexx/include -I${NDK_ROOT}/sources/cxx-stl/llvm-libc++abi/libcxxabi/include"
cxxinclude[c++]="-I${NDK_ROOT}/sources/cxx-stl/llvm-libc++/libcxx/include"

declare -A cxxlib
cxxlib[gnustl]="-L${NDK_ROOT}/sources/cxx-stl/gnu-libstdc++/${TCVER}/libs/${Arch}"
cxxlib[gabi++]="-L${NDK_ROOT}/sources/cxx-stl/gabi++/libs/${Arch}"
cxxlib[stlport]="-L${NDK_ROOT}/sources/cxx-stl/stlport/libs/${Arch}"
cxxlib[stdc++]=" "
cxxlib[c++]="-L${NDK_ROOT}/sources/cxx-stl/llvm-libc++/libs/${Arch}"

declare -A ldflag
ldflag[arm]="-lgcc -lc -lm -fpic"
ldflag[armeabi]="-fpic -no-canonical-prefixes -Wl,--no-undefined -Wl,-z,noexecstack -lgcc -lc -lm"
ldflag[armeabi-v7a]="-fpic -lgcc -no-canonical-prefixes -march=armv7-a -Wl,--fix-cortex-a8  -Wl,--no-undefined -Wl,-z,noexecstack -lc -lm"
ldflag[armeabi-v7a-hard]="-fpic -lgcc -no-canonical-prefixes -march=armv7-a -Wl,--fix-cortex-a8 -Wl,--no-warn-mismatch -lm_hard  -Wl,--no-undefined -Wl,-z,noexecstack -lc -lm"

CPPFLAGS+=" ${CFLG}"
CFLG+=" ${cflag[${Arch}]}"
STL_BASE=${STL%_shared}
STL_BASE=${STL_BASE%_static}
CXXFLG+=" ${cxxflag[${Arch}]} ${cxxinclude[${STL_BASE}]} ${cxxlib[${STL_BASE}]} -l${STL}"


CC="${CROSS_COMPILE}-gcc --sysroot=${SYSROOT}"
CXX="${CROSS_COMPILE}-g++ --sysroot=${SYSROOT}"
AR="${CROSS_COMPILE}-ar"
LD="${CROSS_COMPILE}-ld"
NM="${CROSS_COMPILE}-nm"
CPP="${CC} -E"
STRIP="${CROSS_COMPILE}-strip --strip-unneeded"
OBJDUMP="${CROSS_COMPILE}-objdump"
RANLIB="${CROSS_COMPILE}-ranlib"
LIBS+=" ${ldflag[${Arch}]}"

prints() {
    _str="$@"
    echo "$_str"
    echo "$_str" >>$LOG
}


LOG=$PWD/prepare.log
echo "Preparing source files for compilation on $Host..." >$LOG

edit_line() {
    regex=`echo $1`; shift
    rfile=$1; shift
    sed -i -r -e "$regex" $rfile 2>>$LOG 1>>$LOG
}

finish() {
    if [ ! -z "$OLDDIR" ]; then
        cd $OLDDIR
    fi
    exit 0
}

fix_makefile() {
    mkfile=$1
    cp $mkfile $mkfile.bak
    HAS_CC=$(${GREP} -E '^CC[ ]?=.*' $mkfile)
    if [ "${HAS_CC}X" == "X" ]; then
        LINE=$(${GREP} -n -E '^[^#]+' $mkfile | head -n 1 | ${GREP} -o -E '^[0-9]+')
        ${SED} -i -r -e "$LINE iCC= " $mkfile
    fi
    edit_line "s:^(CC\s?=\s?).*:\1 ${CC} :" $mkfile
    edit_line "s:^(AR\s?=\s?)[^ ]*:\1 ${AR} :" $mkfile
    edit_line "s:^(CFLAGS|CCOPT)(\s?=\s?):\1\2 ${CFLG} :" $mkfile
    edit_line "s:^(LDFLAGS\s?=\s?):\1 ${LIBS} :" $mkfile
    edit_line "s:^(RANLIB\s?=\s?).*:\1 ${RANLIB} :" $mkfile
    edit_line "s:^(CXX\s?=\s?).*:\1 ${CXX} :" $mkfile
    edit_line "s:^(LD\s?=\s?)[^ ]*:\1 ${LD} :" $mkfile
    edit_line "s:^(OBJDUMP\s?=\s?)[^ ]*:\1 ${OBJDUMP} :" $mkfile
    edit_line "s:^(NM\s?=\s?)[^ ]*:\1 ${NM} :" $mkfile
    edit_line "s:^(OBJDUMP\s?=\s?).*:\1 ${STRIP} :" $mkfile
    edit_line "s:^(CPP\s?=\s?)[^ ]*:\1 ${CPP} :" $mkfile
}

custom_conf() {
    SUBMK=$(find . -name Makefile -print)
    for mk in ${SUBMK}; do
        prints "Fixing makefile at: $mk..."
        prints "Backup made at: $mk.bak"
        fix_makefile $mk
    done
}

add_once() {
    if [ -n "$(echo $PATH | ${GREP} $NDK)" ]; then
        PATH=${NDK}:${PATH}
        export PATH NDK
    fi
}



cat >$(pwd)/env.sh <<EOF
#!/bin/bash
NDK=${NDK_ROOT}/toolchains/arm-linux-androideabi-${TCVER}/prebuilt/linux-\$(uname -m)/bin
if [ -z "\$(echo \$PATH | fgrep \$NDK)" ]; then
    PATH=\${NDK}:\${PATH}
    export PATH NDK
fi
EOF
chmod 0755 env.sh

. env.sh

if [ -n "$PRINT_CONFIG" ]; then
    if [ -n "$NO_ARGS" ]; then
        unset HOSTARG NEWARGV
    fi
    echo CPPFLAGS=\"${CPPFLAGS}\" CFLAGS=\"${CFLG}\" CXXFLAGS=\"${CXXFLG}\" LDFLAGS=\"${LIBS}\" CC=\"${CC}\" CXX=\"${CXX}\" LD=\"${LD}\" AR=\"${AR}\" RANLIB=\"${RANLIB}\" NM=\"${NM}\" STRIP=\"${STRIP}\" CPP=\"${CPP}\" ${NEWARGV} $@ ${HOSTARG}
    finish
fi


if [ -f "$CONFIG_SCRIPT" ] || [ -n "$DO_CONFIG" ]; then
    $CONFIG_SCRIPT CPPFLAGS="${CPPFLAGS}" CFLAGS="${CFLG}" CXXFLAGS="${CXXFLG}" LDFLAGS="${LIBS}" CC="${CC}" CXX="${CXX}" LD="${LD}" AR="${AR}" RANLIB="${RANLIB}" NM="${NM}" STRIP="${STRIP}" CPP="${CPP}" $NEWARGV $@ $HOSTARG
    echo "Make sure ${NDK} is in your \$PATH before running make."
    echo "A script called env.sh has been created in the current directory. Sourcing it will make sure the toolchain is in your path"
    if [ "$?" != "0" ]; then
        echo "[ERROR]: Configure failed with return code: $?"
        export CPPFLAGS="${CPPFLAGS}" CFLAGS="${CFLG}" CXXFLAGS="${CXXFLG}" LDFLAGS="${LIBS}" CC="${CC}" CXX="${CXX}" LD="${LD}" AR="${AR}" RANLIB="${RANLIB}" NM="${NM}" STRIP="${STRIP}" CPP="${CPP}"

    fi
else
    prints "No configure script found in current directory: $(pwd)"
    echo "Type 'y' to attempt to modify any makefiles in this directory, and any other key to abort..."
    echo -n "Continue?: "
    read ANS
    if [ "$ANS" == "y" ]; then
        custom_conf
    fi
fi
finish
5
Matt Johnson