废话就不多说了,开始。。。
在现经已可以把Android NDK供提的工具链以独立编译器的方法应用了!如果你经已有了自己的构建统系,这就很有用了。
一个典范的应用场景是调用一个赖依于CC环境变量开源库的'configure'脚本停止跨平台编译。
本档文将释解如何那样做。
首先 ,你要需定确你的独立工具链所面向的目标CPU加构,是ARM-based设备、x86-based设备,还是MIPS-based设备。个每架构对应不同的工具链名字:
* arm-linux-androideabi-4.6 => 面向ARM-based Android设备
* x86-4.6 => 面向x86-based Android设备
* mipsel-linux-android-4.6 => 面向MIPS-based Android设备
你应当解了的第二项情事是你想面向那一级Android nativeAPI 。每一级都供提了不同的API,它们被档文doc/STABLE-APIS.html所述描,并对应于$NDK/platforms的子文件夹。这使得你可以定义指向你的'sysroot'的路径 ,GCC路径下含包统系头文件和库。平日看起来像这样:
SYSROOT=$NDK/platforms/android-<level>/arch-<arch>/
<level> 是API level 数,<arch> 是系体结构("arm", "x86", 和"mips" 都可以作为值)。例如,如果你面向 Android2.2 (a.k.a. Froyo),你应应用:
SYSROOT=$NDK/platforms/android-8/arch-arm
注意:X86 和MIPS系体仅在android-9才开始支撑。
应用--sysroot项选调用编译器,以明表你所面向的平台的统系文件的路径。例如:
export CC="$NDK/toolchains/<name>/prebuilt/<system>/bin/<prefix>gcc--sysroot=$SYSROOT"
$CC -o foo.o -c foo.c
<name> 是工具链的名字,<system> 是宿主统系,<prefix> 是特定工具链的前缀。例如,如果你在Linux上应用NDK r5 工具链,你将应用:
exportCC="$NDK/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc--sysroot=$SYSROOT"
就像你看到的,这很啰嗦,但的确能作工!
注意:
直接应用NDK 工具链有具很多制限:
你不能应用任何C++ STL (无论是STLport 或GNU libstdc++) 。也不能应用异常和RTTI。
NDK 答应你创立一个"自定义的" 工具链并安装以使生活更单简。例如,面下的命令:
$NDK/build/tools/make-standalone-toolchain.sh --platform=android-5--install-dir=/tmp/my-android-toolchain
这将创立一个文件夹,名为 /tmp/my-android-toolchain,含包一个android-5/arch-armsysroot的考贝和工具链的行执文件。
注意,默许下,ARM-based GCC 4.6 工具链将被脚本所选择。应用'--arch=x86' 来指定x86-based 的GCC,应用'--arch=mips' 来指定MIPS-based 的GCC,或应用
'--toolchain=<name>'来指定。例如:
--toolchain=x86-4.4.3 # select x86 GCC 4.4.3 compiler
--toolchain=mipsel-linux-android-4.6 # select MIPS GCC 4.6compiler, same as --arch=mips
如果你想,可以通过添加 --llvm-version=3.1 来把clang/llvm3.1也考贝去过。你可以在后之直接应用它。就像:
exportPATH=/tmp/my-android-toolchain/bin:$PATH
exportCC=arm-linux-androideabi-gcc # or export CC=clang
exportCXX=arm-linux-androideabi-g++ # or export CXX=clang++
注意,不应用 --install-dir 项选,make-standalone-toolchain.sh将创立一个名为/tmp/ndk/<toolchain-name>.tar.bz2的tarball。这使你可以很轻易的存储并从新布发二进制工具包。
另一个主要的利益是这个独立的工具链将含包一个GNU libstdc++的考贝,它能支撑异常和RTTI (当你接链到libstdc++ 或 libsupc++)。
重点:工具链行执文件不赖依于或含包宿主上的特色路径,换句话说,它们可以被安装于任何位置,或移动到另外位置。
注意:你然依可以对新的工具链应用—sysroot项选,但是在现变单简了!
通过ARM 工具链生产的机器码应当与官方的Android 'armeabi' ABI兼容。推荐应用-mthumb 编译志标来强制生产16位Thumb-1令指 (默许是32-bit 的)。
如果你想面向'armeabi-v7a' ABI,你应当确保面下的志标被应用:
CFLAGS='-march=armv7-a-mfloat-abi=softfp -mfpu=vfpv3-d16'
注:第一个志标启用Thumb-2令指,第二个启用H/W FPU令指同时确保浮点参数被传入核心寄存器,这是ABI兼容的症结。*不要*离开应用这些志标!
如果你想应用Neon令指,你要需转变-mfpu编译志标:
CFLAGS='-march=armv7-a-mfloat-abi=softfp -mfpu=neon'
注意这会强制应用VFPv3-D32。
还要确保面下两个志标也供提给接链器:
LDFLAGS='-march=armv7-a-Wl,--fix-cortex-a8'
注:第一个志标示指接链器为armv7-a选择适合的libgcc.a、libgcov.a和crt*.o。第二个志标于用在某些Cortex-A8置装中绕过一个CPU bug。
如果下面这些还不能满意你,那么你最好不要用独立的工具链了,而是据守NDK构建统系,它将为你理处全部细节。
当你面向x86 ABI 或MIPS ABI时你不要需应用任何特定的编译器志标。
Windows下的二进制文件*不*赖依于Cygwin。好消息是它们因此会行运快,坏消息是它们不明白Cygwin的路径情势,比如/cygdrive/c/foo/bar (而不是 C:/foo/bar)。
NDK构建统系保障全部从Cygwin传给编译器的路径都被主动转换,并且为你敷衍那些难搞的情事。如果有一个自定义构建统系,你要需自己敷衍全部的问题。
注:前当没有支撑Cygwin / MSys的划计。
在Android 2.3之前,Android平台不并真的支撑wchar_t。这示表:
l 如果你面向android-9 或更高平台,wchar_t的小大是4bytes,并且大多数C库中的宽字节数函都可用(外例是多字节编解码数函和wsprintf/wsscanf数函)。
l 如果你面向任何更低的API level,wchar_t 只有一个字节并且任何宽字节数函都 不能用。
我们提议全部开发者都移除对wchar_t的任何赖依,并且转换到更好的方法。Android所供提的支撑仅仅是为了帮助整合已存在的代码。
工具链行执文件默入是支撑C++异常和RTTI的。所以当你不要需时,应用-fno-exceptions和-fno-rtti来制止它们 (生产更少的机器码)。
注:如果你想应用这些特性,你将要需明白的接链到libsupc++。要这样做,在要在接链成二进制文件时应用-lsupc++ :
arm-linux-androideabi-g++ .... -lsupc++
独立工具链也带有一个GNU libstdc++ 库的考贝,它供提了C++准标模版库的一个现实。要应用它,你还要需接链到准确的库:
l 应用-lstdc++ 来接链态静库版。这保障了全部要需的C++ STL代码都含包到了你的终究文件中。这是推荐的方法。
l 应用-lgnustl_shared 来接链态动库版。如果你应用此方法,你要需确保libgnustl_shared.so也被复制到你的设备中。此文件位于:
$TOOLCHAIN/arm-linux-androideabi/lib/ for ARM toolchains.
$TOOLCHAIN/i686-linux-android/lib/ for x86 ones.
$TOOLCHAIN/mipsel-linux-android/lib/ for MIPS toolchains.
态动库版的GNU libstdc++不叫libstdc++.so的原因是这将致导在行运时与统系自己的最小C++行运时(/system/lib/libstdc++.so)突冲。这对态静库就没影响了。
文章结束给大家分享下程序员的一些笑话语录: 一程序员告老还乡,想安度晚年,于是决定在书法上有所造诣。省略数字……,准备好文房4宝,挥起毛笔在白纸上郑重的写下:Hello World