编译Android源代码
请按照“获取Android源代码”一节中的内容安装所需的相关包,否则在编译源代码的时候会报很多的错。为了方便起见,现将所有需要安装的包罗列如下,其中有些包是可选的,但最好都装上,同时,在安装之前,最好先更新一下:
$ sudo aptitude update
$ sudo aptitude upgrade
Ubuntu Linux (32位 x86)
$ sudo aptitude install git-core gnupg flex bison gperf libsdl-dev libesd0-dev libwxgtk2.6-dev build-essential zip curl libncurses5-dev zlib1g-dev make gcc g++ libc6‐dev patch texinfo ncurses‐dev python2.6 valgrind lib32readline5-dev
$ sudo aptitude install sun‐java6‐jdk
Ubuntu Linux (64位 x86)
$ sudo apt-get install git-core gnupg flex bison gperf libsdl-dev libesd0-dev libwxgtk2.6-dev build-essential zip curl libncurses5-dev zlib1g-dev make gcc g++ libc6-dev patch texinfo ncurses-dev python2.6 valgrind gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev ia32-libs x11proto-core-dev libx11-dev lib32readline5-dev lib32z-dev
$ sudo ln -s /usr/lib32/libX11.so.6 /usr/lib32/libX11.so
$ sudo aptitude install sun‐java6‐jdk
基本上安装上面罗列的包,编译时就不会有太大的问题,下面列举本人(64位机子,Ubuntu10.04系统)在编译时出现的一些错误,以及在出现错误时,相关的解决包。虽然google已将这些必需包在 android文档中进行说明了,但在此声明这些问题的解决还是参考网址:http://code.google.com/p/android/issues/detail?id=1005
/usr/include/gnu/stubs.h:7:27: error: gnu/stubs-32.h: No such file or directory make: *** [out/host/linux-x86/obj/EXECUTABLES/acp_intermediates/acp.o] Error 1
解决包:$ sudo aptitude install libc6-dev-i386
/usr/bin/ld: cannot find -lstdc++
collect2: ld returned 1 exit status
make: *** [out/host/linux-x86/obj/EXECUTABLES/aidl_intermediates/aidl] Error 1
dpkg-query -l &> packages.txt (该工具可用来查询dpkg数据库)
解决包:$ sudo aptitude install g++-multilib
/usr/bin/ld: cannot find -lncurses
collect2: ld returned 1 exit status
make: *** [out/host/linux-x86/obj/EXECUTABLES/adb_intermediates/adb] Error 1
make: *** Waiting for unfinished jobs....
解决包:$ sudo aptitude search lib32ncurses5-dev
/usr/bin/ld: cannot find -lz
collect2: ld returned 1 exit status
make: *** [out/host/linux-x86/obj/EXECUTABLES/zipalign_intermediates/zipalign] Error 1
make: *** Waiting for unfinished jobs....
解决包:$ sudo aptitude install lib32z-dev
同时,网友kees.jongenburger提出了使用getlibs(该工具可自动解决32位程序在64位系统上的依赖关系)来解决这个问题。具体用法如下:
$ getlibs -l libz.so
libz.so: zlib1g-dev The following i386 packages will be installed:
zlib1g-dev
Continue [Y/n]? y
Downloading ...
Installing libraries ...
具体getlibs工具的介绍请参考网址: http://ubuntuforums.org/showthread.php?t=474790
注:在“获取Android源代码”一节中已介绍使用java 6时会有不兼容的问题,但经过测试发现,如果仅仅make(make 不包括make sdk),用sun‐java6‐jdk 是没有问题的。而make sdk,就会有问题,严格来说是在make doc 时会出问题,它需要的javadoc 版本为1.5。
因此,我们安装完sun‐java6‐jdk 后最好再安装sun‐java5‐jdk,或者只安装sun‐java5‐jdk。这里sun‐java6‐jdk 和sun‐java5‐jdk 都安装,并只修改javadoc.1.gz 和javadoc。因为只有这两个是make sdk 用到的。这样的话,除了javadoc 工具是用1.5 版本,其它均用1.6 版本,java的安装目录及结构如下:
derek@derek-desktop:/usr/lib/jvm$ ls -l
total 4
lrwxrwxrwx 1 root root 19 2010-08-20 23:19 java-6-sun -> java-6-sun-1.6.0.20
drwxr-xr-x 8 root root 4096 2010-08-21 00:06 java-6-sun-1.6.0.20
sudo aptitude install sun‐java5‐jdk (现在发现找不到java 5的包,可能是源的问题)
修改javadoc 的link
$ cd /etc/alternatives
$ sudo rm javadoc.1.gz
$ sudo ln ‐s /usr/lib/jvm/java‐1.5.0‐sun/man/man1/javadoc.1.gz javadoc.1.gz
$ sudo rm javadoc
$ sudo ln ‐s /usr/lib/jvm/java‐1.5.0‐sun/bin/javadoc javadoc
但是,本人在编译2.2系统时测试发现使用java 6并没有上述问题。估计应该是解决了。所以上述对javadoc这快的处理就可以不做了。
设置环境变量
$ vim ~/.bashrc
增加如下的环境变量,包括java以及android程序开发、运行的一些环境变量
JAVA_HOME=/usr/lib/jvm/java-6-sun
export JAVA_HOME
JRE_HOME=${JAVA_HOME}/jre
export JRE_HOME
export ANDROID_JAVA_HOME=${JAVA_HOME}
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib:$CLASSPATH
export JAVA_PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin
HOME_BIN=~/android/bin/
export PATH=${PATH}:${JAVA_PATH}:${HOME_BIN}
$ source ~/.bashrc (使环境变量的设置立即生效,即同步变化)
编译android源码
$ cd ~/android/androidplatform/ (cd 到android源码目录)
$ make (或者使用 make -jn 命令,其中,n值的确定参考原则为2m-1,m为处理器核数,本人实验机子为双核,故用 make -j3)
这个过程很久,大概花两个小时左右,编译完后将得到~/android/androidplatform/out 目录,可参加附件中的目录树文件。
编译SDK
直接执行make 是不包括make sdk 的。make sdk 用来生成SDK,这样,我们就可以用与源码同步的SDK 来开发 android 了。
1、查看~/android/androidplatform/frameworks/base/include/utils/Asset.h
$ cd ~/android/androidplatform/
$ vim frameworks/base/include/utils/Asset.h
查看 UNCOMPRESS_DATA_MAX 值:
enum {
/* data larger than this does not get uncompressed into a buffer */
#ifdef HAVE_ANDROID_OS
UNCOMPRESS_DATA_MAX = 1 * 1024 * 1024
#else
UNCOMPRESS_DATA_MAX = 2 * 1024 * 1024
#endif
};
由于Eclipse 编译工程需要大于1.3M 的buffer,如果仅为1 * 1024 * 1024
请改为2 * 1024 * 1024,由于本人实验的版本为2.2已使用enum进行了更正,故不用修改。
输入以下命令进行sdk编译:
$ make sdk
注意如果这里出现问题请按照上面所介绍的将javadoc换回1.5版本。
编译后生成的SDK 存放在~/android/android/platform/out/host/linux‐x86/sdk/ ,此目录下有android‐sdk_eng.xxx_linux‐x86.zip 和android‐sdk_eng.xxx_linux‐x86 目录。android‐sdk_eng.xxx_linux‐x86 就是SDK 目录。参加附件中的目录树文件。
模拟器使用 进入~/android/androidplatform/out/host/linux-x86/sdk/android-sdk_eng.derek_linux-x86/tools目录下,这里有很多Android的工具,其中模拟器对应的应用程序是emulator。下面是正确使用模拟器的步奏:
输入以下命令启动Android SDK 和 AVD 管理器,可以通过该图形化界面进行很多操作,比如SDK下载,虚拟设备的创建,启动模拟器等等。
derek@derek-desktop:~/android/androidplatform/out/host/linux-x86/sdk/android-sdk_eng.derek_linux-x86/tools$ ./android
Starting Android SDK and AVD Manager
No command line parameters provided, launching UI.
See 'android --help' for operations from the command line.
列出机子上的所有target版本,可以理解为android sdk 版本。
derek@derek-desktop:~/android/androidplatform/out/host/linux-x86/sdk/android-sdk_eng.derek_linux-x86/tools$ ./android list target
Available Android targets:
id: 1 or "android-AOSP"
Name: Android AOSP (Preview)
Type: Platform
API level: AOSP
Revision: 2
Skins: WQVGA400, WQVGA432, WVGA800, WVGA854, HVGA (default), QVGA
创建一个名为 My_AVD_2.2的虚拟设备
derek@derek-desktop:~/android/androidplatform/out/host/linux-x86/sdk/android-sdk_eng.derek_linux-x86/tools$ ./android create avd -n My_AVD_2.2 -t 1
Android AOSP (Preview) is a basic Android platform.
Do you wish to create a custom hardware profile [no]
Created AVD 'My_AVD_2.2' based on Android AOSP (Preview),
with the following hardware config:
hw.lcd.density=160
使用刚创建的虚拟设备启动模拟器
derek@derek-desktop:~/android/androidplatform/out/host/linux-x86/sdk/android-sdk_eng.derek_linux-x86/tools$ ./emulator -avd My_AVD_2.2
创建虚拟sdcard,用于模拟器中数据和外部数据的交互,虚拟SD卡的大小不应该小于100M,否则在后期的文件系统打包过程中,有可能会有SD卡存储空间不够的问题。
derek@derek-desktop:~/android/androidplatform/out/host/linux-x86/sdk/android-sdk_eng.derek_linux-x86/tools$ ./mksdcard -l smallone 256M ~/android/androidplatform/out/host/linux-x86/sdk/android-sdk_eng.derek_linux-x86/sdcard.img
使用刚刚创建的虚拟sdcard创建一虚拟设备
derek@derek-desktop:~/android/androidplatform/out/host/linux-x86/sdk/android-sdk_eng.derek_linux-x86/tools$ ./android create avd -n MyAOSP -t 1 -c ~/android/androidplatform/out/host/linux-x86/sdk/android-sdk_eng.derek_linux-x86/sdcard.img
列出本机上的所有虚拟设备
derek@derek-desktop:~/android/androidplatform/out/host/linux-x86/sdk/android-sdk_eng.derek_linux-x86/tools$ ./android list avd
Available Android Virtual Devices:
Name: MyAOSP
Path: /home/derek/.android/avd/MyAOSP.avd
Target: Android AOSP (Preview) (API level AOSP)
Skin: HVGA
Sdcard: /home/derek/android/androidplatform/out/host/linux-x86/sdk/android-sdk_eng.derek_linux-x86/sdcard.img
---------
Name: My_AVD_2.2
Path: /home/derek/.android/avd/My_AVD_2.2.avd
Target: Android AOSP (Preview) (API level AOSP)
Skin: HVGA
Sdcard: 256M
使用刚编译完成的SDK中的模拟器启动android系统时,默认采用的系统镜像为~/android/androidplatform/out/host/linux-x86/sdk/android-sdk_eng.derek_linux-x86/platforms/android-AOSP/images目录(刚编译完的SDK目录中的android-sdk_eng.derek_linux-x86/platforms/android-AOSP/images)下的kernel-qemu ramdisk.img system.img userdata.img 。
其中kernel-qemu为内核镜像,其他组合为文件系统。
当然也可以使用自己编译的内核镜像,关于如果编译内核的问题会在后续文章中说明。
使用名为MyAOSP 的虚拟设备启动模拟器,并规定系统,数据等的映象文件路径,模拟器内核采用prebuild/android-arm/kernel/kernel-qemu。当然也可以使用自己编译的内核镜像,关于如果编译内核的问题会在后续文章中说明。
derek@derek-desktop:~/android/androidplatform/out/host/linux-x86/sdk/android-sdk_eng.derek_linux-x86/tools$ ./emulator -avd MyAOSP -sysdir ~/android/androidplatform/out/target/product/generic/ -data ~/android/androidplatform/out/target/product/generic/userdata.img -ramdisk ~/android/androidplatform/out/target/product/generic/ramdisk.img -kernel ~/android/androidplatform/prebuilt/android-arm/kernel/kernel-qemu
也可以再加上下面的参数进行启动,
-system ~/android/androidplatform/out/target/product/generic/system.img
或
-image ~/android/androidplatform/out/target/product/generic/system.img
但后者已过时。
可以输入emulator -help 进行进一步的工作。
注意:细心的人可能会发现刚刚编译生成的SDK目录下的tools目录(~/android/androidplatform/out/host/linux-x86/sdk/android-sdk_eng.derek_linux-x86/tools)中的所有工具在刚刚源码编译完的host目录下的bin目录(~/android/androidplatform/out/host/linux-x86/bin)中都有。
http://www.linuxidc.com/Linux/2011-03/32991p6.htm
7 . 编译 Android 源代码
7 .1 编译生成镜像
切换到Android源码根目录下,执行$sudo make 即可。首次编译非常耗时,取决于机器配置,大约需要2-3 小时 。有可能会出现:“Permission denied (权限拒绝的提示)” 请命令赋予权限:$cd 无权限文件的当前目录 回车 ; $sudo chmod -R +rwx *
回车 ; 完成后镜像生成在/root/mydroid/out/target/product/generic下:Android源码编译后得到system.img ,ramdisk.img ,userdata.img 映像文件。其中, ramdisk.img是emulator的文件系统,system.img包括了主要的包、库等文件,userdata.img包括了一些用户数据,emulator加载这3个映像文件后,会把 system和 userdata分别加载到 ramdisk文件系统中的system和 userdata目录下。
7.2 编译、配置 Android SDK
make编译完成后,执行$sudo make sdk 命令,生成对应于该版本源代码的sdk,此过程用的时间偶的是10 多分钟 。注意这个sdk不能用于生产环境。
用于生产环境的最好用如下命令: $sudo make PRODUCT-sdk-sdk 命令,生成对应于该版本源代码的用于生产环境的sdk,此过程用的时间偶的是1 个多小时 。
Android官方的SDK和偶自己编译Android源码时使用make sdk编译出的SDK有区别,模拟器版本不同,加载的默认镜像也不同(一个是官方的, 一个是自己编译的)。下面将展示如何能够自由切换SDK版本。
首先是自己编译的SDK版本,实际位置是/root/mydroid/out/host/linux-x86/sdk/Android-sdk_eng.root_linux-x86。
因为它比较常用,我们给它高优先级:
update-alternatives --install /usr/bin/AndroidSDK AndroidSDK /root/mydroid/out/host/linux-x86/sdk/android-sdk_eng.root_linux-x86 255
事先下载的官方SDK位置是/root/Android-sdk-linux_86,执行:
update-alternatives --install /usr/bin/AndroidSDK AndroidSDK /root/android-sdk-linux_86 0
然后使用update-alternatives --display AndroidSDK查看当前配置情况:

如果要切换配置,使用update-alternatives --config AndroidSDK

配置AndroidSDK环境变量。终端中执行gedit ~/.bashrc
在文件最后添加下面三行:
# set Android environment
export Android_SDK_HOME=/usr/bin/ AndroidSDK
export PATH=$Android_SDK_HOME/tools:$PATH 保存文件。在终端中执行source ~/.bashrc
8)编译模块 android中的一个应用程序可以单独编译,编译后要重新生成system.img 在源码目录下执行 $ . build/envsetup.sh (.后面有空格) 就多出一些命令: - croot: Changes directory to the top of the tree. - m: Makes from the top of the tree. - mm: Builds all of the modules in the current directory. - mmm: Builds all of the modules in the supplied directories. - cgrep: Greps on all local C/C++ files. - jgrep: Greps on all local Java files. - resgrep: Greps on all local res/*.xml files. - godir: Go to the directory containing a file. 可以加—help查看用法 我们可以使用mmm来编译指定目录的模块,如编译联系人: $ mmm packages/apps/Contacts/ 编完之后生成两个文件: out/target/product/generic/data/app/ContactsTests.apk out/target/product/generic/system/app/Contacts.apk 可以使用 $ make snod 重新生成system.img,再运行模拟器
|