拒绝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已经被设定好了)
就是几个环境变量的事儿。
第1行是自动取最大Android API Level。可以强制改成14(表示Android4.0)之类的特定值。
第3行里的androideabi-*的*是gcc版本号,自动取最大号。可以强制换成4.8之类的。
STL_ROOT那两行是为了C++的stl库的,用得着时就去掉注释。
然后就可以用$CC和$CXX来编译C和C++ ($CC也能编译C++但是和$CXX有微妙区别)。
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是自动取得最大的Android API level,不满意的就自己换个固定数值。
2016/07/28: 上面的make...sh报警将要过时,所以最后一句改成make.....py了:
然后,最好把toolchain里的bin目录加到PATH里。
可以测试一下其中的gcc用起来不需要--sysroot=...参数的。
然后,该干嘛干嘛。例如,交叉编译ffmpeg:
注意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目录了。例如:
具体的例子在这儿。
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
具体的例子在这儿。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories