您的位置:首页 > 移动开发 > Android开发

拒绝ndk-build (Android Native Development Kit)

2015-06-10 00:00 651 查看
摘要: 什么破东西,为了做一个和java毫无关系的lib,exe之类的东西,还非得把代码放在jni目录下。不想忍受这点的人,有轻微强迫症的,或者非要使用configure自动工具的人,可以直接用NDK里的gcc或者toolchain......

Eclipse或者Android Studio里都不能调试C, 实际还得在gdb命令行里做,那这些代码放在Eclipse里毫无用处。虽然据说新的Android Studio里集成了C/C++开发,但是到什么程度还不知道。

废话少说,

直接用NDK里的gcc是这样的: (假设NDK_ROOT已经被设定好了)

就是几个环境变量的事儿。

MAX_API_LVL=`cd $NDK_ROOT/platforms && ls -d android-?? | tail -n 1 | sed s/android-//`
SYS_ROOT=$NDK_ROOT/platforms/android-$MAX_API_LVL/arch-arm
TOOL_CHAIN_DIR=`ls -d $NDK_ROOT/toolchains/arm-linux-androideabi-*/prebuilt/* | tail -n 1`
CC="$TOOL_CHAIN_DIR/bin/arm-linux-androideabi-gcc --sysroot=$SYS_ROOT"

CXX="$TOOL_CHAIN_DIR/bin/arm-linux-androideabi-g++ --sysroot=$SYS_ROOT"
CXX="$CXX -fno-rtti -fno-exceptions"

##STL_ROOT=`ls -d $NDK_ROOT/sources/cxx-stl/gnu-libstdc++/?.? | tail -n 1` || exit 1
##CXX="$CXX -I$STL_ROOT/include -I $STL_ROOT/libs/armeabi/include"

第1行是自动取最大Android API Level。可以强制改成14(表示Android4.0)之类的特定值。
第3行里的androideabi-*的*是gcc版本号,自动取最大号。可以强制换成4.8之类的。
STL_ROOT那两行是为了C++的stl库的,用得着时就去掉注释。

然后就可以用$CC和$CXX来编译C和C++ ($CC也能编译C++但是和$CXX有微妙区别)。

$CC a.c
$CXX a.cc

2016/07/28: 最新的[NDK里关于NDK的官方利用说明:Standalone Toolchain](https://developer.android.com/ndk/guides/standalone_toolchain.html) 里也提到了上述简化利用方法,说得更全面。

小菜都可以这样干,只是一些庞大的auto config之类交叉编译的时候,就有include和lib以及附属编译工具误用本机之类的问题,手动硬搞很辛苦。

所以还是得先生成一个正规的交叉编译用的一套东西(toolchain),里面就会包含gcc,include,lib等东西,当使用其中的gcc时,它会自动使用自己身边的include,lib作为系统目录,所以其中的bin/arm-linux-androideabi-gcc等工具可以直接使用而无须末尾指定--sysroot=...参数,配套工具都会自动从自己身旁找,不容易和本机的工具混淆。

正规的交叉编译用的toolchain的生成方法(只一次):例如生成到./std_toolchain目录下。

MAX_API_LVL=`cd $NDK_ROOT/platforms && ls -d android-?? | tail -n 1 | sed s/android-//`
$NDK_ROOT/build/tools/make-standalone-toolchain.sh --install-dir=./std_toolchain --platform=android-$MAX_API_LVL

同理,MAX_API_LVL是自动取得最大的Android API level,不满意的就自己换个固定数值。

2016/07/28: 上面的make...sh报警将要过时,所以最后一句改成make.....py了:

$NDK_ROOT/build/tools/make_standalone_toolchain.py --install-dir ./std_toolchain --arc arm --api $MAX_API_LVL

然后,最好把toolchain里的bin目录加到PATH里。

export PATH="$PWD/std_toolchain/bin:$PATH"

可以测试一下其中的gcc用起来不需要--sysroot=...参数的。

arm-linux-androideabi-gcc  a.c
arm-linux-androideabi-g++  a.cc

然后,该干嘛干嘛。例如,交叉编译ffmpeg:

OTHER_FFMPEG_OPTIONS="--disable-everything --disable-doc --enable-protocol=pipe --enable-filter=scale --enable-filter=crop --enable-filter=transpose --enable-demuxer=rawvideo --enable-decoder=rawvideo --enable-muxer=image2 --enable-muxer=image2pipe --enable-muxer=mjpeg --enable-encoder=mjpeg --enable-encoder=png"

./configure --enable-cross-compile --cross-prefix=arm-linux-androideabi- \
--target-os=linux --arch=arm \
$OTHER_FFMPEG_OPTIONS

注意cross-prefix设定成了"arm-linux-androideabi-",这个才是接口之处,所有的gcc等命令名都会被插入这个前缀。如果不把toolchain的bin目录加到PATH里,那么cross-prefix得加上全路径,例如$PWD/std_toolchain/bin/arm-linux-androideabi-。

显然toolchain方法更加靠谱,不用指定那什么sysroot了。

2016/07/28:发现ndk-build可以通过选项指定不用那破jni目录了。例如:

ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk

具体的例子在这儿
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息