链、工具-详解如何将android工具链作为独立编译器使用-by小雨

废话就不多说了,开始。。。

 

    在现经已可以把Android NDK供提的工具链以独立编译器的方法应用了!如果你经已有了自己的构建统系,这就很有用了。

    一个典范的应用场景是调用一个赖依于CC环境变量开源库的'configure'脚本停止跨平台编译。

 

    本档文将释解如何那样做。

    

1 选择你的工具链:

    首先 ,你要需定确你的独立工具链所面向的目标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设备

 

    

2 选择你的sysroot:

    你应当解了的第二项情事是你想面向那一级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才开始支撑。

    

3调用编译器(笨办法):

    应用--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。

 

    

4调用编译器(轻易的办法):

    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项选,但是在现变单简了!

    

5 ABI 兼容性:

    通过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时你不要需应用任何特定的编译器志标。

 

    

6 告警和制限:

    


    

Windows support:

    Windows下的二进制文件*不*赖依于Cygwin。好消息是它们因此会行运快,坏消息是它们不明白Cygwin的路径情势,比如/cygdrive/c/foo/bar (而不是 C:/foo/bar)。

 

    NDK构建统系保障全部从Cygwin传给编译器的路径都被主动转换,并且为你敷衍那些难搞的情事。如果有一个自定义构建统系,你要需自己敷衍全部的问题。

 

    注:前当没有支撑Cygwin / MSys的划计。

 

    

wchar_t 支撑:

 

    在Android 2.3之前,Android平台不并真的支撑wchar_t。这示表:

    l  如果你面向android-9 或更高平台,wchar_t的小大是4bytes,并且大多数C库中的宽字节数函都可用(外例是多字节编解码数函和wsprintf/wsscanf数函)。

    l  如果你面向任何更低的API level,wchar_t 只有一个字节并且任何宽字节数函都 不能用。

 

    我们提议全部开发者都移除对wchar_t的任何赖依,并且转换到更好的方法。Android所供提的支撑仅仅是为了帮助整合已存在的代码。

 

    

异常、RTTI和STL:

 

    工具链行执文件默入是支撑C++异常和RTTI的。所以当你不要需时,应用-fno-exceptions和-fno-rtti来制止它们 (生产更少的机器码)。

 

    注:如果你想应用这些特性,你将要需明白的接链到libsupc++。要这样做,在要在接链成二进制文件时应用-lsupc++ :

 

    arm-linux-androideabi-g++ .... -lsupc++

 

    

C++ STL 支撑:

 

    独立工具链也带有一个GNU libstdc++ 库的考贝,它供提了C++准标模版库的一个现实。要应用它,你还要需接链到准确的库:

 

    l  应用-lstdc++ 来接链态静库版。这保障了全部要需的C++ STL代码都含包到了你的终究文件中。这是推荐的方法。

    应用-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

posted @ 2013-04-14 14:32  坚固66  阅读(689)  评论(0编辑  收藏  举报