编译环境搭建

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”为准。


 

可能出现的问题

  1. 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,也可以解决问题,不推荐。


 

  1. 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。

  1. 重新挂载 /system

    $adb remount

    注意:把adb所在的目录放在环境变量PATH,或者指定路径,如out/host/linux-x86/bin/adb,并具有指向权限。如果是USB连接到开发板,请以超级用户的权限运行 adb server,再remount。

    $adb kill-server #如果server没运行可以略过

    $sudo adb start-server

    默认情况,/system挂载的文件系统只读,需要重新挂载为可读写。

  2. 安装

    $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

  1. 获取代码

    ~/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

  2. 编译配置

    从 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