转自:http://blog.sina.com.cn/s/blog_4a0a39c30101q1u4.html
http://www.linuxidc.com/Linux/2014-11/109905.htm
android源码在 prebuilts 目录已经自带有交叉编译工具链,但这个还不是一个标准的可直接编译代码的编译器,还需要依赖android ndk 的头文件及库文件,才能进行编译和链接,且版本也比较保守(4.0源码自带的是gcc 4.4.3,4.1的源码才内置gcc 4.6的编译器),还有一个问题,只有linux的版本,windows用户没法用,只能用NDK来创建。
android ndk 好象从 r5b 开始,就在 build/tools 目录准备了一个 make-standalone-toolchain.sh 的程序来让用户创建标准的交叉编译工具链(Cross Toolchain),以最新的ndk r8e为例,一般建议在ndk的要目录运行如下命令:
$ ./build/tools/make-standalone-toolchain.sh
Auto-config: –toolchain=arm-linux-androideabi-4.6
Copying prebuilt binaries…
Copying sysroot headers and libraries…
Copying libstdc++ headers and libraries…
Creating package file: /tmp/ndk-Administrator/arm-linux-androideabi-4.6.tar.bz2
Cleaning up…
Done.
直接将交叉编译工具链(Cross Toolchain)打包在文件 /tmp/ndk-Administrator/arm-linux-androideabi-4.6.tar.bz2,将这个工具链解压到任意目录即可用来编译 c/c++ 源码,不用指定任何其他的参数,这也就是所谓的标准的交叉编译工具链(Cross Toolchain)!命令如下:
mkdir /toolchains m k d i r / t o o l c h a i n s cd ~/toolchains
tar−xvjf/tmp/ndk−Administrator/arm−linux−androideabi−4.6.tar.bz2 t a r − x v j f / t m p / n d k − A d m i n i s t r a t o r / a r m − l i n u x − a n d r o i d e a b i − 4.6. t a r . b z 2 export PATH=/home/Administrator/toolchains/arm-linux-androideabi-4.6/bin: PATH P A T H arm-linux-androideabi-gcc test.c -o test
test.c 是准备的一个非常简单的 c 程序,当然也可以是一个 c++ 程序,命令就要换成:
$ arm-linux-androideabi-g++ test.cpp -o test
简单看一下 cross toolchain 的目录结构:
$ ls -l
总用量 52
drwx——+ 1 Administrator None 0 五月 18 13:37 arm-linux-androideabi
drwx——+ 1 Administrator None 0 五月 18 13:37 bin
-rwx—— 1 Administrator None 18002 三月 15 15:46 COPYING
-rwx—— 1 Administrator None 26527 三月 15 15:46 COPYING.LIB
drwx——+ 1 Administrator None 0 六月 17 00:12 include
drwx——+ 1 Administrator None 0 五月 18 13:37 lib
drwx——+ 1 Administrator None 0 五月 18 13:37 lib32
drwx——+ 1 Administrator None 0 五月 18 13:37 libexec
-rwx—— 1 Administrator None 1939 三月 15 15:46 SOURCES
drwxr-xr-x+ 1 Administrator None 0 六月 17 00:11 sysroot
大家注意下 sysroot 这个目录,其实就是从 ndk 的platforms 的某一个目录复制而来,包含了编译android所需要的头文件和库文件,所以在编译时可参直接编译,而不需要指定头文件及库文件的路径就可以直接编译成功,定制标准的交叉编译工具链的参数,可以通过如下命令来查看:
$ ./build/tools/make-standalone-toolchain.sh –help
Usage: make-standalone-toolchain.sh [options]
Generate a customized Android toolchain installation that includes
a working sysroot. The result is something that can more easily be
used as a standalone cross-compiler, e.g. to run configure and
make scripts.
Valid options (defaults are in brackets):
–help Print this help.
–verbose Enable verbose mode.
–toolchain= Specify toolchain name
–llvm-version= Specify LLVM version
–arch= Specify target architecture [arm]
–ndk-dir= Take source files from NDK at [.]
–system= Specify host system [windows]
–package-dir= Place package file in [/tmp/ndk-Administrator]
–install-dir= Don’t create package, install files to instead.
–platform= Specify target Android platform/API level. [android-3]
当不指定 platform 时,此脚本是直接复制 android-3 的文件到交叉编译工具链,如果想用一些android的新特性,建议指定 platform 为 android-9 或更高,当然也可以指定最新的 gcc 4.7 或 llvm 编译器,只要设置 toolchain 或 llvm-version 即可,生成其他架构的工具链,请指定 arch 参数,脚本默认是 arm 架构的。设置不同的参数,大家可以创建不同类型及版本的标准的交叉编译工具链(Cross Toolchain)。
在之前的文章中提到了用arm-none-linux-gnueabi-gcc交叉编译移植程序到Android平台上。也提到了,Android中没有glibc,所以arm-none-linux-gnueabi-gcc编译出来的程序需要在编译时指明连接器,并且将所需要的动态库拷贝到Android机器中。
详见:http://www.linuxidc.com/Linux/2014-03/97499.htm
所以为了能够更方便的使用交叉编译器移植我们所需要的程序或者库到Android平台上,我们一般采用ndk的编译方式(ndk的下载配置详见Google官方说明:http://developer.android.com/tools/sdk/ndk/index.html)
在移植的过程中,有时我们需要单独使用交叉编译工具(比如程序的依赖库的Makefile是利用configure生成,那么我们需要使用./configure CC=arm-linux-androideabi- 来生成我们所需要的Makefile)
因此,可以利用ndk生成我们需要的交叉编译工具:
在ndk的目录下运行:
./build/tools/make-standalone-toolchain.sh –platform=android-15
Auto-config: –toolchain=arm-linux-androideabi-4.6
Copying prebuilt binaries…
Copying sysroot headers and libraries…
Copying libstdc++ headers and libraries…
Creating package file: /tmp/ndk-wwtao/arm-linux-androideabi-4.6.tar.bz2
Cleaning up…
Done.
–platform=android-15 是用来设定Android的API版本,其余的选项可以通过–help来查看。
这样可以得到ndk生成的交叉编译工具链。
在我们利用交叉编译工具移植了一些所需要的库之后就可以移植到Android平台上。通常来说移植过程都是差不多的,修改makefile交叉编译器,添加搜索头文件的位置和链接库的位置。如果遇到了头文件找不到的错误,常见可能性是交叉编译器的include中的头文件相对路径不一样,一般来说Google一下即可解决。
对于编译一个基于某些依赖库的程序,而这些依赖库在Android系统中已经有时,最简便的方法是找到它的头文件(有的头文件交叉便器的include中没有),然后再从Android系统中拷贝出相应的.so文件,用交叉编译器或者ndk-build编译即可。
arm-linux-androideabi-gcc -I[头文件目录] -L[动态库位置] filename.c -o filename
或者编写Android.mk文件,利用ndk-build.
LOCAL_PATH := (callmy−dir)include ( c a l l m y − d i r ) i n c l u d e (CLEAR_VARS)
LOCAL_MODULE := client_android
LOCAL_SRC_FILES := client.c
LOCAL_CFLAGS += -I/home/wwtao/Desktop/bluetooth/include/include
LOCAL_LDLIBS += -L/home/wwtao/Desktop/bluetooth/libfrompanda -lbluetooth
include $(BUILD_EXECUTABLE)
其中,LOCAL_PATH := $(call my-dir) 设置LOCAL_PATH为当前了路径
include $(CLEAR_VARS)是清空当前的变量
LOCAL_MODULE 是编译后生成的文件名
LOCAL_SRC_FILES 是编译的源文件
LOCAL_CFLAGS 是设置编译时的头文件搜索路径
LOCAL_LDLIBS 是设置编译时搜索动态链接库的路径
include $(BUILD_EXECUTABLE) 是生成可执行文件,如果是BUILD_STATIC_LIBRARY是生成静态库,如果是BUILD_SHARED_LIBRARY。
如果出现
Unable to auto-config arch from toolchain
这是说无法自动配置 toolchain,需要手动配置.先看看你的ndk支持编译哪些cpu.
oldfeel@oldfeel:~/android-ndk$ ls toolchains/
aarch64-linux-android-4.9 mipsel-linux-android-4.8
aarch64-linux-android-clang3.4 mipsel-linux-android-4.9
aarch64-linux-android-clang3.5 mipsel-linux-android-clang3.4
arm-linux-androideabi-4.6 mipsel-linux-android-clang3.5
arm-linux-androideabi-4.8 renderscript
arm-linux-androideabi-4.9 x86-4.6
arm-linux-androideabi-clang3.4 x86-4.8
arm-linux-androideabi-clang3.5 x86-4.9
llvm-3.4 x86_64-4.9
llvm-3.5 x86_64-clang3.4
mips64el-linux-android-4.9 x86_64-clang3.5
mips64el-linux-android-clang3.4 x86-clang3.4
mips64el-linux-android-clang3.5 x86-clang3.5
mipsel-linux-android-4.6
编辑 make-standalone-toolchain.sh,找到并修改 TOOLCHAIN_NAME= 为
vim build/tools/make-standalone-toolchain.sh
TOOLCHAIN_NAME=arm-linux-androideabi-4.9
或者直接
./build/tools/make-standalone-toolchain.sh --toolchain=arm-linux-androideabi-4.9
重新执行