我们大家都知道android的ndk开发可以编译c,c++代码,不过需要自己写Android.mk文件。但是对于大多数开源项目来说,代码量很大,而且在编译前需要通过configure来配置编译选项,这种情况下,自己写Android.mk文件是很不现实的。
不过Google给我们提供了一种按照标准linux系统编译项目的方式来移植开源代码的工具。就是standalone toolchain。
如果使用linux系统或者mac os来做安卓开发,这种方式非常方便,windows用户则需要安装minGW。
通过执行
sudo /opt/android-ndk-r9d/build/tools/make-standalone-toolchain.sh --platform=android-9 -toolchain=arm-linux-androideabi-4.8 --arch=arm --install-dir=/opt/ndk-standalone-9-arm
可以生成独立工具链,进而配合libtool工具,可以方便的移植大多数开源项目。
其中/opt/android-ndk-r9d/build/tools/make-standalone-toolchain.sh
就是Google提供的创建独立工具链的脚本。
一般来说可能需要设置这些参数 --platform 安卓版本,--arch平台。默认是arm.还可以设置为x86。--install-dir 独立工具链的安装目录。
执行后,可以在/opt/ndk-standalone-9-arm看到以下目录
-rw-r--r-- 1 shalseven staff 18002 12 18 2013 COPYING
-rw-r--r-- 1 shalseven staff 26527 12 18 2013 COPYING.LIB
-rw-r--r-- 1 shalseven staff 2176 12 18 2013 SOURCES
drwxr-xr-x 4 shalseven staff 136 3 1 2014 arm-linux-androideabi
drwxr-xr-x 30 shalseven staff 1020 5 18 2014 bin
drwxr-xr-x 9 shalseven staff 306 5 18 2014 include
drwxr-xr-x 6 shalseven staff 204 5 18 2014 lib
drwxr-xr-x 5 shalseven staff 170 3 1 2014 lib32
drwxr-xr-x 3 shalseven staff 102 3 1 2014 libexec
drwxr-xr-x 3 shalseven staff 102 3 1 2014 share
drwxr-xr-x 3 root wheel 102 5 18 2014 sysroot
其中bin目录下可以看到生成了arm-linux-androideabi的交叉编译工具链
-rwxr-xr-x 1 shalseven staff 676120 12 18 2013 arm-linux-androideabi-addr2line
-rwxr-xr-x 1 shalseven staff 702576 12 18 2013 arm-linux-androideabi-ar
-rwxr-xr-x 1 shalseven staff 1255004 12 18 2013 arm-linux-androideabi-as
lrwxr-xr-x 1 shalseven staff 25 12 18 2013 arm-linux-androideabi-c++ -> arm-linux-androideabi-g++
-rwxr-xr-x 1 shalseven staff 671948 12 18 2013 arm-linux-androideabi-c++filt
-rwxr-xr-x 1 shalseven staff 345452 12 18 2013 arm-linux-androideabi-cpp
-rwxr-xr-x 1 shalseven staff 31504 12 18 2013 arm-linux-androideabi-elfedit
-rwxr-xr-x 1 shalseven staff 349548 12 18 2013 arm-linux-androideabi-g++
-rwxr-xr-x 1 shalseven staff 345452 12 18 2013 arm-linux-androideabi-gcc
lrwxr-xr-x 1 shalseven staff 25 12 18 2013 arm-linux-androideabi-gcc-4.6 -> arm-linux-androideabi-gcc
-rwxr-xr-x 1 shalseven staff 123424 12 18 2013 arm-linux-androideabi-gcov
-rwxr-xr-x 1 shalseven staff 5842980 12 18 2013 arm-linux-androideabi-gdb
-rwxr-xr-x 1 shalseven staff 743752 12 18 2013 arm-linux-androideabi-gprof
lrwxr-xr-x 1 shalseven staff 29 12 18 2013 arm-linux-androideabi-ld -> arm-linux-androideabi-ld.gold
-rwxr-xr-x 1 shalseven staff 1150724 12 18 2013 arm-linux-androideabi-ld.bfd
-rwxr-xr-x 1 shalseven staff 4774124 12 18 2013 arm-linux-androideabi-ld.gold
-rwxr-xr-x 1 shalseven staff 2171960 2 18 2014 arm-linux-androideabi-ld.mcld
-rwxr-xr-x 1 shalseven staff 684324 12 18 2013 arm-linux-androideabi-nm
-rwxr-xr-x 1 shalseven staff 854920 12 18 2013 arm-linux-androideabi-objcopy
-rwxr-xr-x 1 shalseven staff 1028720 12 18 2013 arm-linux-androideabi-objdump
-rwxr-xr-x 1 shalseven staff 702576 12 18 2013 arm-linux-androideabi-ranlib
-rwxr-xr-x 1 shalseven staff 320148 12 18 2013 arm-linux-androideabi-readelf
-rwxr-xr-x 1 shalseven staff 676172 12 18 2013 arm-linux-androideabi-size
-rwxr-xr-x 1 shalseven staff 676168 12 18 2013 arm-linux-androideabi-strings
-rwxr-xr-x 1 shalseven staff 854920 12 18 2013 arm-linux-androideabi-strip
lrwxr-xr-x 1 shalseven staff 7 2 5 2014 python -> python2
lrwxr-xr-x 1 shalseven staff 9 2 5 2014 python2 -> python2.7
-rwxr-xr-x 1 shalseven staff 1849104 2 5 2014 python2.7
将/opt/ndk-standalone-9-arm/bin加到PATH中,确保在任意目录都可以执行arm-linux-androideabi-gcc等命令。
export PATH=$PATH:/opt/ndk-standalone-9-arm/bin
然后就可以简单地通过
cd /path/to/project/src
./configure --host=arm-linux-androideabi --prefix=`pwd`/android/arm
make
来配置编译开源项目了。因为大多数开源项目的configure都是调用libtool根据我们配置的--host决定使用哪个工具链进行编译,而libtool实际上是通过工程目录下的config.guess和config.sub这几个文件来猜测工具链。所以为了能够让libtool正确
识别--host=arm-linux-androideabi参数,需要确保你的config.guess足够新,新到它是支持android工具链的。所以对于一些老的项目,你可能需要先更新系统的libtool,然后将系统的config.guess文件拷贝覆盖工程目录的config.guess文件。再执行configure命令。
cp /opt/local/share/libtool/config/config.guess ./
cp /opt/local/share/libtool/config/config.sub ./
config.guess和config.sub文件可能是在上面写的路径,也可能在/usr/share/local/libtool/config/ 目录下。你需要看一下你的libtool是安装在哪里了。
通过这种方式,可以很快的编译libcurl,libuv,libev,libevent等等开源项目。
另外系统中需要提前安装automake,libtool,autoconf工具。比如我的mac系统需要执行以下命令安装:
sudo port install automake
sudo port install autoconf
sudo port install libtool
ubuntu系统:
sudo apt-get install automake
sudo apt-get install autoconf
sudo apt-get install libtool
如果除了需要编译arm平台的还需要编译x86平台的代码,则需要再生成
i686-linux-android工具链。
/opt/android-ndk-r9d/build/tools/make-standalone-toolchain.sh --platform=android-9 --toolchain=x86-4.8 --arch=x86 --install-dir=/opt/ndk-standalone-9-x86
export PATH=$PATH:/opt/ndk-standalone-9-x86/bin
./configure --host=i686-linux-android --prefix=`pwd`/android/x86
make
以libcurl为例:
sudo port install automake
sudo port install autoconf
sudo port install libtool
sudo /opt/android-ndk-r9d/build/tools/make-standalone-toolchain.sh --platform=android-9 -toolchain=arm-linux-androideabi-4.8 --arch=arm --install-dir=/opt/ndk-standalone-9-arm
export PATH=$PATH:/opt/ndk-standalone-9-arm/bin
git clone https://github.com/bagder/curl.gicd curl
./buildconf
./configure --host=arm-linux-androideabi --prefix=`pwd`/android/arm
make
make install
既可以在android/arm目录下得到静态库和动态库。
可以看出,这种方式,比网上一般说的放到安卓源码树下编译的方式要简单很多。