一、Introduction 今天我们就来谈谈如何在Ubuntu平台上面编译android源码,我的是ubuntu10.04版本,在进行编译流程讲解之前我想讲一下 make 、make snod 、make kernel的作用,m、mm、mmm它们的作用以及区别。 - make: 编译源码,生成相应的系统镜像文件。 - make snod: 重新生成一个system.img系统镜像文件 - make kernel: 编译内核(可选)一般根据envsetup.sh文件内容而论 - 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(编译指定目录下的所有模块)。 二、 编译Android source以及SDK 2.1、完全编译 使用make编译并生成镜像 ~$: cd ~/android/src ~$: make 映像编译成功后会在目录 ~/android/src/out/target/product/generic 下产生一些image文件 ramdisk.img system.img userdata.img android -info.txt 我们可以通过启动模拟器来验证我们是否编译正确 ,注意,我们最好在system.img所在的目录下进行如下动作 ~$ emulator -kernel ~/android2.2/prebuilt/android-arm/kernel/kernel-qemu -ramdisk ramdisk.img -debug all -data userdata-qemu.img -system system.img -sysdir . -show-kernel -skin 800x480 如果能正确启动则说明完全编译成功啦。 完全编译完后我们就可以使用make sdk命令做一次SDK的编译拉,步骤如下: ~$ cd ~/android/src ~$ make sdk 注意:如果需要build SDK,随着版本的不同,我们所需的环境也不同,编译android2.2之前的版本需要安装sun-java5-jdk, 而不是sun-java6-jdk,否则会出现如下错误: build/core/product_config.mk:207: WARNING: adding test OTA key ============================================ TARGET_PRODUCT=generic TARGET_BUILD_VARIANT=eng TARGET_SIMULATOR= TARGET_BUILD_TYPE=release TARGET_ARCH=arm HOST_ARCH=x86 HOST_OS=linux HOST_BUILD_TYPE=release BUILD_ID= ============================================ Combining NOTICE files: out/target/product/generic/obj/NOTICE.txt Finding NOTICE files: out/host/linux-x86/obj/NOTICE_FILES/hash-timestamp Combining NOTICE files: out/host/linux-x86/obj/NOTICE.txt Package: out/target/product/generic/generic-img-eng.anjoy.zip SDK buildinfo: out/target/product/generic/sdk/sdk-build.prop Docs droiddoc: out/target/common/docs/dx javadoc: 错误 - 在 doclet 类 DroidDoc 中,方法 start 已抛出异常 java.lang.reflect.InvocationTargetException com.sun.tools.javac.code.Symbol$CompletionFailure: 未找到 sun.util.resources.OpenListResourceBundle 的类文件 所以,如果jdk版本不同的话就去官网下载一个或者在线安装一个吧 ,这里我就不多说拉 sdk编译成功后会在~/android /src/out/host/linux-x86/sdk/ 生成sdk的文件目录和压缩包: android-sdk_eng.anjoy_linux-x86 android-sdk_eng.anjoy_linux-x86.zip 并在~/android /src/out/target/product/generic(generic是默认的产品名)下打包所有的映像文件: generic-img-eng.anjoy.zip 生成的SDK目录结构为: /home/anjoy/android/src/out/host/linux-x86/sdk/android-sdk_eng.anjoy_linux-x86: 总计 32 drwxrwx--- 6 anjoy anjoy 4096 2011-06-27 17:48 . drwxr-x--- 3 anjoy anjoy 4096 2011-06-27 17:48 .. drwxrwx--- 2 anjoy anjoy 4096 2011-06-27 17:48 add-ons drwxrwx--- 14 anjoy anjoy 4096 2011-06-27 17:48 docs -rw-rw---- 1 anjoy anjoy 172 2011-06-27 17:50 documentation.html drwxrwx--- 3 anjoy anjoy 4096 2011-06-27 17:48 platforms -rw-rw---- 1 anjoy anjoy 225 2011-06-27 17:50 RELEASE_NOTES.txt drwxrwx--- 3 anjoy anjoy 4096 2011-06-27 17:50 tools 想很方便的使用生成的SDK只需要在.bashrc中增加: export PATH=$PATH:/home/anjoy/android/src/out/host/linux-x86/sdk/android-sdk_eng.anjoy_linux-x86/tools 2.2、模块化编译 注意:在模块化编译之前我们一定要把envsetup.sh 脚本source 一下,或者你直接把envsetup.sh文件所在的路径配置到你个人的bashrc文件里面,这样你就不要每次都作source动作拉。 envsetup.sh 提供了一些的bash函数定义,当运行了envsetup.sh后就可以使用help 命令来查看: ~$ help Invoke ". build/envsetup.sh" from your shell to add the following functions to your environment: - 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. ... .. 其中对模块的编译有帮助的是tapas、m、mm、mmm这几个命令。 其中mmm 后面要跟模块的根目录,不是所有的目录下都有子模块,那些含有Android.mk 文件目录才是模块的根目录,模块名可以从Android.mk 的LOCAL_MODULE 或者LOCAL_PACKAGE_NAME 变量中得到。 单独编译某模块,需要在mmm后面指定模块路径,例如编译application中的Launcher2: mmm packages/apps/Launcher2/ 或者在src目录下直接运行make module name: cd ~/android/src make Launcher2 2.3、增量编译的步骤 a、假如我们修改了某个模块下的代码,那么我们只需要从新编译这个模块就可以拉,而不需要整个工程的编译。 b、编译所修改的代码所在模块,例如: cd ~/android/src mmm packages/apps/Launcher2 c、在~/android/src中运行: cd ~/android/src make snod d、该命令生成一个新的系统映像system.img,将这个系统映像拷贝至sdk下: cd ~/android/src cp out/target/product/generic/system.img / out/host/linux-x86/sdk/android-sdk_eng.anjoy_linux-x86/tools/lib/images/ OK,这样就完成了Android源码的编译以及SDK的生成拉 提醒:如果你是Ubuntu10.04系统 32位机上安装编译Android2.3源码,其步骤和注意事项如下: 1.安装JDK6 对于Android2.3 系统,不要安装JDK5 ,应该安装最新的JDK6 。 如果安装了JDK6,Android会自动按64位编译,如果系统是32位的,会有编译错误,后面会说如何修改这个错误。 sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner" sudo add-apt-repository "deb-src http://archive.canonical.com/ubuntu lucid partner" sudo apt-get update sudo apt-get install sun-java6-jdk sudo update-java-alternatives -s java-6-sun 安装完后,需要手动设置JAVA_HOME, JRE_HOME , CLASS_PATH为JDK6 的安装路径。 2.进行编译android2.3 ~$ cd ~/android2.3 ~$ source build/envsetup.sh ~$ make 在make的时候会提示出错: ************************************************************ You are attempting to build on a 32-bit system. Only 64-bit build environments are supported beyond froyo/2.2. ************************************************************ 因为Android2.3默认是64位的系统上编译,需要手动修改build/core/main.mk,把这个判断部分注释掉: #ifneq (64,$(findstring 64,$(build_arch))) #$(warning ************************************************************) #$(warning You are attempting to build on a 32-bit system.) #$(warning Only 64-bit build environments are supported beyond froyo/2.2.) #$(warning ************************************************************) #$(error stop) #endif 重新make,如果是安装了JDK6版本,会又报错: Docs droiddoc: out/target/common/docs/api-stubs Could not load ‘clearsilver-jni’ java.library.path = out/host/linux-x86/lib make: *** [out/target/common/docs/api-stubs-timestamp] Error 45 make: *** Waiting for unfinished jobs…. Could not load ‘clearsilver-jni’ java.library.path = out/host/linux-x86/lib make: *** [out/target/common/docs/doc-comment-check-timestamp] Error 45 我们只需要修改这几个文件,该回到32位编译环境即可: # external/clearsilver/cgi/Android.mk # external/clearsilver/java-jni/Android.mk # external/clearsilver/util/Android.mk # external/clearsilver/cs/Android.mk 把上面这些文件内容的编译选项-m64 改成-m32 即可 重新make,大概不到一个小时就make完了。 OK,大工告成