编译环境搭建
http://wangsheng2008love.blog.163.com/blog/static/782016892011103105310555/
http://blog.csdn.net/yujunf/article/details/7069492
编译Android前需要安装的软件包
以下内容摘自:http://source.android.com/source/download.html
Ubuntu Linux (64-bit x86)
This has not been as well tested. Please send success or failure reports to android-porting@googlegroups.com .
The Android build requires a 32-bit build environment as well as some other tools:
- Required Packages:
- Git, JDK, flex, and the other packages as listed above in the i386 instructions:
- JDK 5.0, update 12 or higher.Java 6 is not supported, because of incompatibilities with @Override.
- Pieces from the 32-bit cross-building environment
-
X11 development
$ sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl sun-java5-jdk zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev ia32-libs x11proto-core-dev libx11-dev lib32readline5-dev lib32z-dev
-
Set the system to use the right version of java by default:
$ sudo update-java-alternatives -s java-1.5.0-sun
-
X11: Ubuntu doesn't have packages for the X11 libraries, but that can be worked around with the following command:
$ sudo ln -s /usr/lib32/libX11.so.6 /usr/lib32/libX11.so
×××背景的比较重要。X11的问题没有碰到。至于JDK,从 Android 的编译脚本来看,Android 2.1 以前(包括2.1)使用 1.5,2.2使用的 1.6。问题是 JDK 1.5现在不维护了,而且在Ubuntu 10.04里的源里只有JDK 1.6的包。
至于,Android交叉编译时所用的工具链是Android工程自带的,一般放在目录prebuilt/linux-x86/toolchain下,包括X86,ARM,以及SH (SuperH)等架构,具体以build/core/combo/目录下以”TARGET_linux”开头的mk文件中指定的变量“TARGET_TOOLS_PREFIX”为准。
可能出现的问题
-
libstdc++.so 链接问题
现象: host SharedLib: libneo_util (out/host/linux-x86/obj/lib/libneo_util.so)
/usr/bin/ld: skipping incompatible /usr/lib/gcc/i486-linux-gnu/4.3.4/libstdc++.so when searching for -lstdc++
/usr/bin/ld: skipping incompatible /usr/lib/gcc/i486-linux-gnu/4.3.4/libstdc++.a when searching for -lstdc++
/usr/bin/ld: skipping incompatible /usr/lib/gcc/i486-linux-gnu/4.3.4/libstdc++.so when searching for -lstdc++
/usr/bin/ld: skipping incompatible /usr/lib/gcc/i486-linux-gnu/4.3.4/libstdc++.a when searching for -lstdc++
/usr/bin/ld: cannot find -lstdc++
collect2: ld returned 1 exit status
make: *** [out/host/linux-x86/obj/lib/libneo_util.so] 错误 1
解决方法: 缺少g++-multilib库,安装即可: sudo apt-get install g++-multilib 如果把 /usr/lib/gcc/x86_64-linux-gnu/4.4.3/libstdc++.so 链接到 ../../../../lib32/libstdc++.so.6,也可以解决问题,不推荐。
-
libz.so链接问题
host Executable: aapt (out/host/linux-x86/obj/EXECUTABLES/aapt_intermediates/aapt)
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../libz.so when searching for -lz
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../libz.a when searching for -lz
/usr/bin/ld: skipping incompatible /usr/lib/libz.so when searching for -lz
/usr/bin/ld: skipping incompatible /usr/lib/libz.a when searching for -lz
/usr/bin/ld: cannot find -lz
collect2: ld returned 1 exit status
解决方法:
缺少lib32z1-dev库,安装: sudo apt-get install lib32z1-dev
以上问题比较常见。只要按照官方的指导进行编译,就不会出现这些问题了。
以下如果没有特别说明,默认的当前工作目录是工程的顶级目录。只需输入:
$make
就会编译整个Android工程的代码。这相当于:
$make PRODUCT-generic-eng
如果要编译 Android SDK,输入:
$make sdk
其他的一些编译命令:
$make modules #打印工程的所有模块。
$make ${LOCAL_MODULE} #编译模块${LOCAL_MODULE} ,如 make libc 编译libc(bionic/libc模)
$make clean-${LOCAL_MODULE} #清理模块${LOCAL_MODULE} 编译的目标文件和中间文件。
$make eng #也可以 user,userdebug。发布版本编译的一些变体,区别在安装模块、软件 #包和是否可以调试。在不同变体间切换前,请用 make installclean 清理安装。
$make clean #清除当前编译配置生成输出和中间文件。相当rm -f out/<configuration>。
$make clobber #清除所有配置的输出和中间文件。 相当于 rm -f out
$make dataclean #
$make installclean # 清理安装的文件
$make snod #重新生成system.img
$make bootp_w_picpath #
$make dist #
在以上的命令中,加上 “showcommands”,会打印编译时使用的命令, -j 指定多核同步编译。如:
$make sdk showcommands -j 4
多核编译,有时以为同步会出现依赖问题,这时去掉 -j 或直接重新编译即可解决。更多详细内容,请参考:
build/core/build-system.html
http://source.android.com/porting/build_system.html
$make -j8 PRODUCT-sdk-sdk showcommands dist
在build/core/main.mk 及build/core/Makefile两个文件中有许多伪目标:
otapackage , recoveryp_w_picpath
模块编译开发 Android应用时,借助 Eclipse ,编码、编译、运行、调试,一气呵成。但是如果修改Android 自带的程序,或者如 Frameworks 等代码的,就难以使用 Eclipse 开发,现在一般是在命令行操作。这时有什么方法可以减少编译、启动的时间呢?可以按下面步骤实施:
1. 加载脚本
$source build/envsetup.sh
或者
$ . build/envsetup.sh
这样mmm等命令就可以使用了。由于mmm是函数,只在当前的shell中有效,这也是用source加载脚本的原因。其他还有的命令
printconfig : 打印工程当前编译配置
lunch :选择编译配置
choosecombo :逐项选择编译配置
2. 编译模块
$mmm packages/app/Launcher2
mmm只需要指定目录即可,当然这个目录下必须有Android.mk的Makefile。编译,目标文件放在
/out/target/product/generic/system/app。
-
重新挂载 /system
$adb remount
注意:把adb所在的目录放在环境变量PATH,或者指定路径,如out/host/linux-x86/bin/adb,并具有指向权限。如果是USB连接到开发板,请以超级用户的权限运行 adb server,再remount。
$adb kill-server #如果server没运行可以略过
$sudo adb start-server
默认情况,/system挂载的文件系统只读,需要重新挂载为可读写。
-
安装
$adb push out/target/product/generic/system/app/Launcher2.apk /system/app
或者
$adb install -r out/target/product/generic/system/app/Launcher2.apk
Android在发现程序文件被更新后,会重新启动应用程序,我们就可以调试了。以后,我们只需重复步骤2和4,快速编译,热更新模块,开发效率也很高,而不需要重新编译这个工程、重新烧录镜像文件、重启系统等费时的工作。
如果更新了framewok.apk 或者 共享库时,需要同步一下。
$adb shell sync
mmm frameworks/policies/base/phone/ showcommands
不能编译出 out/target/product/generic/system/framework/android.policy.jar
make android.policy -j 4
才可以。原因是, frameworks/policies/base/PolicyConfig.mk 配合 frameworks/policies/base/phone/Android.mk
共享库也可以热更新
$mmm frameworks/base/libs/binder
$adb push out/target/product/generic/system/lib/libbinder.so /system/lib
命令行定义变量:
$ DISABLE_AUTO_INSTALLCLEAN=true mmm frameworks/base/camera/tests/CameraServiceTest/
这个在编译SDK 和 eng之间切换时不会清理。
内核编译主要是模拟器的内核编译。
prebuilt/android-x86/kernel/kernel
-
获取代码
~/Android$git clone git://android.git.kernel.org/kernel/common.git
~/Android$git checkout origin/android-goldfish-2.6.27 -b goldfish
模拟器有自己的内核goldfish分支,默认分支编译后不能在qemu中启动。
更多的分支可以使用 git branch -a 查看。Goldfish 内核的源码导出到了目录~/Android/common
-
编译配置
从 SDK 中获取编译配置:
$emulator -avd myavd #启动虚拟机, 或者在 Ecplise 把虚拟机启动
$adb pull /proc/config.gz #从虚拟机的文件系统中拉出内核的编译配置
$gunzip config.gz;mv config ~/Android/common/.config
如果从源码里直接配置:
$make ARCH=arm goldfish_defconfig #生成默认配置
$make xconfig #作修改 (需要QT,安装libqt3-mt-dev 包即可) 或者
$make gconfig # (需安装libglade2-dev)
更详细的可以参照 README 或使用下面命令获取帮助:
$make help
$make ARCH=arm help
修改 Makefile 打开kernel目录下的Makefile文件,把 LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%, $(call ld-option, -Wl$(comma)?build-id,)) 这一行注释掉,并且添加一个空的LDFLAGS_BUILD_ID定义,如下: LDFLAGS_BUILD_ID = 编译内核 $make mrproper $make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- 编译开始,会有一些提示需要确认,一路回车键。 小帖士:“[Y/n]”这样字样的含义是,可以按“y”(yes)或者“n”(no), 大写的”Y”表示用户默认的选择,即直接回车就是表示选了”y”。 这里使用的交叉编译器是CodeSourcery (http://www.codesourcery.com/sgpp/lite/arm/portal/subscription?@template=lite),也可以使用 Android 自带的交叉编译器 (在prebuilt/linux-x86/toolchain/arm-eabi-4.4.0 ,相应的交叉编译器前缀要修改成 CROSS_COMPILE=arm-eabi-),当然把工具所在路径都要加入环境变量 PATH,在~/.bashrc 加入:
export PATH=${PATH}:~/CodeSourcery/Sourcery_G++_Lite/bin
模拟器的内核编译的源码很少,很快就能编译完成,生成的kernel 镜像路径是 arch/arm/boo/zImage, 拷贝到 prebuilt/android-arm/kernel/kernel-qemu