android源码编译与调试

Android源码编译与调试

 

整理:joeyyin@outlook.com

2012.09

 

系统环境

ubuntu-11.10-desktop-i386

on

VMware Workstation 8.0.0 build-471780

on

WindowsXP

 

 

[64bit]

ubuntu-10.10-beta-desktop-amd64   [:为了编译mtk提供的代码]

http://mirrors.163.com/ubuntu-releases/

 

on

V VMware Workstation 9.0

http://bbs.pcbeta.com/viewthread-1119365-1-1.html

 

on

window 7 64bit

 

默认安装后执行 sudo apt-get install xxxx  会出错,解决办法见以下链接:

http://hi.baidu.com/lozard/item/03b854f5a8630015e2e3bd0a

 

源码编译

软件环境

基本按照http://source.android.com/source/initializing.html,未设置ccache

 

下载源码

http://source.android.com/source/downloading.html,版本:android-4.0.3_r1

下载34天的时间才最终完成。

 

编译

make –j4

出现错误,发现ubuntu-11.10默认安装的是gcc4.6,但编译android需要gcc4.4。重新安装gcc4.4后执行 make –j4,顺利完成编译。

 

2012-9-19 注:今天在同样环境下编译 android-4.1.1_r6.1,发现已经无法在32bit系统上编译

 

执行

emulator

出现错误,发现是由于之前安装了android sdk的缘故。

 ~/.bashrc中将android sdk的路径从PATH中移除,同时增加:

export ANDROID_PRODUCT_OUT=/home/joeyyin/android_4.0.3_r1/out/target/product/generic

export ANDROID_PRODUCT_OUT_BIN=/home/joeyyin/android_4.0.3_r1/out/host/linux-x86/bin

export PATH=$ANDROID_PRODUCT_OUT:$ANDROID_PRODUCT_OUT_BIN:$PATH

 

编译生成的emulator等其他bin工具在/home/joeyyin/android_4.0.3_r1/out/host/linux-x86/bin目录。

 

System.img, userdata.img, ramdis.img/home/joeyyin/android_4.0.3_r1/out/target/product/generic

其中

Ramdisk.imgemulator的文件系统。

System.img包括主要的包、库等文件。

Userdata.img包括了一些用户数据,emulator负责加载3个映像文件后,会把system.img,userdata.img分别加载到ramdisk文件系统的systemuserdata目录下。

 

 

再执行emulator,模拟器顺利启动。

cd ~/android_4.0.3_r1/out/target/product/generic

emulator -system system.img -data userdata.img -ramdisk ramdisk.img

 

 

编译模块

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/Browsers/
编完之后生成两个文件:
out/target/product/generic/data/app/Browser.apk
out/target/product/generic/system/app/Browser.apk
可以使用
$ make snod
重新生成system.img,再运行模拟器

 

 

编译SDK

$make sdk

悲剧的出现以下错误:

 

解决:

查找alarmprovider模块,没有发现

搜索build目录下含alarmprovider的项目

去掉这两个文件中的PRODUCT_PACKAGESalarmprovider

 

网上也有关于这个问题的解答:

“Indeed there is no a module with name AlarmProvider in the source tree now. 
To fix it, remove AlarmProvider from the product definition in the 
following files: 
./build/target/product/large_emu_hw.mk:25:    AlarmProvider 
./build/target/product/generic_no_telephony.mk:24:    AlarmProvider “

 

$ make sdk

又先后出现和以上类似的针对’Sync’, ‘Updater’, ‘SyncProvider’,…

 

看了网上的信息,也可以使用 make PRODUCT-sdk-sdk进行编译

generic_no_telephony.mk, large_emu_hw.mk恢复

$ make PRODUCT-sdk-sdk

半小时候顺利完成编译。

make SDKmake PRODUCT -sdk-sdk有何异同???

 

编译后生成的SDK存放在out/host/linux-x86/sdk/,此目录下有android-sdk_eng.joeyyin_linux- x86.zipandroid-sdk_eng.joeyyin_linux-x86目录。android-sdk_eng.joeyyin_linux-x86就是 SDK目录
实际上,当用mmm命令编译模块时,一样会把SDK的输出文件清除,因此,最好把android-sdk_eng.joeyyin_linux-x86移出来
此后的应用开发,就在该SDK上进行,所以把在~/.bashrc中增加sdk tools/platform_toolsPATH中:
export ANDROID_SDK_HOME=/home/joeyyin/android_4.0.3_r1/out/host/linux-x86/sdk/android-sdk_eng.joeyyin_linux-x86

export PATH=$ANDROID_SDK_HOME/tools:$ANDROID_SDK_HOME/platform_tools: $PATH

创建Android Virtual Device
编译出来的SDK是没有AVDAndroid Virtual Device)的,我们可以通过android工具查看:
$ android list
创建AVD
$ android create avd -t 1 -n myavd –s 320x480
可以android –help来查看上面命令选项的用法。创建中有一些选项,默认就行了
再执行android list,可以看到AVD存放的位置
以后每次运行emulator都要加-avd myavd@myavd选项:
$ emulator -avd myavd

源码编译分析

首先需要理解makefile的编写规则

推荐一篇介绍文章http://www.cnblogs.com/dskit/archive/2010/02/09/1666771.html

 

Makefile -> build/core/main.mk

 

 

Eclipse+adt

Eclipse 安装

下载eclipse from http://www.eclipse.org/downloads/?osType=linux

这个版本在后面编译安装adt时会有错误,建议下载下面的版本:

$ tar zxvf eclipse-jee-indigo-SR2-linux-gtk.tar.gz

$ tar zxvf eclipse-SDK-3.7.2-linux-gtk.tar.gz

$ sudo mv eclipse /opt

$ cd /opt

$ sudo chown -R root:root eclipse

$ sudo chmod -R +r eclipse

$ sudo touch /usr/bin/eclipse

$ sudo chmod 755 /usr/bin/eclipse

$ sudo vim /usr/bin/eclipse

文件内容如下:

#!/bin/sh

#export MOZILLA_FIVE_HOME="/usr/lib/mozilla/"

export ECLIPSE_HOME="/opt/eclipse"

 

$ECLIPSE_HOME/eclipse $*

$ sudo vim /usr/share/applications/eclipse.desktop

文件内容如下:

[Desktop Entry]

Encoding=UTF-8

Name=Eclipse

Comment=Eclipse IDE

Exec=eclipse

Icon=/opt/eclipse/icon.xpm

Terminal=false

Type=Application

Categories=GNOME;Application;Development;

StartupNotify=true

 

Start eclipse firsttime:

$ /opt/eclipse/eclipse -clean &

 

编译安装adt

$ cd ~/android_4.0.3_r1/out/host/linux-x86

$ mkdir adt

$ cd ~/android_4.0.3_r1/sdk/eclipse/scripts

$ export ECLIPSE_HOME=/opt/eclipse

$ ./build_server.sh ~/android_4.0.3_r1/out/host/linux-x86/adt

处理失败,出现很多类似以下依赖错误,据说要下载安装JavaEEeclipse

Missing required plug-in com.android.ide.eclipse.adt_0.0.0.

 

直接启动eclipse -> help ->install new software ->add -> https://dl-ssl.google.com/android/eclipse/

天煞的,这个地址居然无法连接【难道又被天朝封了?】

 

下载javaee版本eclipse安装后,重新编译adt成功。

 

运行eclipse

$ eclipse

help ->install new software ->add ->   选择archive,刚刚编译生成adt zip

安装完成后重启eclipse, 配置sdk信息

 

 

悲剧的是这个编译会删除之前编译的sdk,所以这一步最好在make sdk之前做。

 

创建应用

Helloandroid:

http://developer.android.com/resources/tutorials/hello-world.html

 

导入android源码到eclipse

1、将 源码目录\development\ide\eclipse 中的.classpath复制到源码根目录下。
$ cd ~/android_4.0.3_r1

$ cp /home/joeyyin/android_4.0.3_r1/development/ide/eclipse/.classpath .

$ chmod u+w .classpath

 

2、更改eclipse缓存设置
    eclipse安装根目录下修改eclipse.ini   
    -Xms128m

    -Xmx512m
    -XX:MaxPermSize=256m
3、将 源码目录\development\ide\eclipse 中的android-formatting.xmlandroid.importorder导入eclipse
    android-formatting.xml用来配置eclipse编辑器的代码风格;android.importorder用来配置eclipseimport的顺序和结构。

window->preferences->java->Code style->Formatter中导入android-formatting.xml
    window->preferences->java->Code style->Organize Imports中导入android.importorder
4、导入源码
   新建
Java Project [android project],指定一个name[android_4.0.3_r1],接着将use default location勾掉,指定到你源码的目录下[/home/joeyyin/android_4.0.3_r1]finish

出现两个miss required library的错误。反正不在eclipse中编译,不管这个错误了。

 

Workspace中的其他project可设置android.jar attach到之前导入的android源码工程(android_4.0.3_r1)

Properties -> java build path ->libraries ->  设置android.jarsource attachmentworkspace -> android_4.0.3._r1

[windows下类似操作]

 

eclipse中调试android系统应用/服务:

按以下说明,使用browser测试过,可以断点跟踪调试。

http://wenku.baidu.com/view/cbc4773410661ed9ad51f3e8.html

 

 

windows_eclipse下调试

  1. 导入android源码到windows环境下eclipse
  2. Linux下编译好的/home/joeyyin/android_4.0.3_r1/out/target/product/generic 目录下system.imguserdata.imgramdisk.img复制到window->androidsdk对应版本的images
  3. Debug http://wenku.baidu.com/view/cbc4773410661ed9ad51f3e8.html

 

 

使用GDB调试native code

调试webkit

 

1. 进入android系统源码根目录,然后执行

                source build/envsetup.sh

 

      2. 启动模拟器,并打开浏览器

                Emulator –avd myavd

 

      3. 在终端中执行                 

                adb forward tcp:5039 tcp:5039

 

       4. 打开另一个终端,执行

                adb shell ps

                找到 com.android.browser 进程号

 

       5. 执行

                adb shell gdbserver :5039 --attach pid

                pid com.android.browser 进行号

                正常反馈:

                 Attached; pid = **** 

                 Listening on port 5039

 

        6.  回到第一个终端,导出环境变量,adb, arm-eabi-gdb等的路径,在执行gdbclient报错时,可将相应的命令 的路径导出

                export PATH=/home/joeyyin/android_4.0.3_r1/out/host/linux-x86/sdk/android-sdk_eng.joeyyin_linux-x86/platform-tools:$PATH
               export PATH=/home/joeyyin/android_4.0.3_r1/prebuilt/linux-x86/toolchain/arm-linux-androideabi-4.4.x/bin:$PATH

 

                现在执行命令

                gdb client

                成功的话就会加载一系列的符号表。试了一下设置断点,成功地在代码中中断了下来。下面要做的就                   是熟悉GDB调试命令了。

 

         7. gdb中设置断点                                                               

                  b  FrameLoaderClientAndroid.cpp:888

                                                c             ---- continue

 

         8.  在模拟中用浏览器打开任一网页,就会进入断点了。

 

另有一简化方法:http://mogoweb.net/archives/309

 

 

 

源码结构

http://wenku.baidu.com/view/0816dc232f60ddccda38a04d.html


 

附录

Linux环境变量设置

http://www.360doc.com/content/11/1206/14/6828497_170097352.shtml

 

shell

/etc/passwd

查看当前系统中可用的shell

cat /etc/shells

查看当前使用的shell

echo $SHELL

检查用户(joeyyin)的默认shell

cat /etc/passwd | grep joeyyin

切换shell(到/bin/sh

/bin/sh

退出

Exit

 

共享文件夹设置

http://www.net130.com/CMS/Pub/special/special_virtual/special_virtual_js/2010_04_12_92762.htm

 

 

预制APKAndroid系统

http://blog.csdn.net/sergeycao/article/details/8198205

 

一、如何将带源码的APK预置进系统?
1)     
 packages/apps 下面以需要预置的 APK 名字创建一个新文件夹,以预制一个名为TestAPK 为例
2)     
 Test APKSource code 拷贝到 Test 文件夹下,删除 /bin  /gen 目录
3)     
 Test 目录下创建一个名为 Android.mk的文件,内容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := Test
include $(BUILD_PACKAGE)
 
4)     
打开文件 build/target/product/${Project}.mk (其中 ${Project} 表示工程名)
 Test 添加到 PRODUCT_PACKAGES 里面。
5)     
重新 build 整个工程
 
二、如何将无源码的 APK 预置进系统?
1)     
 packages/apps 下面以需要预置的 APK 名字创建文件夹,以预制一个名为TestAPK为例
2)     
 Test.apk 放到 packages/apps/Test 下面
3)     
  packages/apps/Test 下面创建文件 Android.mk,文件内容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Module name should match apk name to be installed
LOCAL_MODULE := Test
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)

#PRESIGNED不再重新签名, platform使用系统签名
LOCAL_CERTIFICATE := PRESIGNED  
include $(BUILD_PREBUILT)
 
4)     
打开文件 build/target/product/${Project}.mk (其中 ${Project} 表示工程名)
    
 Test 添加到 PRODUCT_PACKAGES 里面。
5)     
将从Test.apk解压出来的 so库拷贝到alps/vendor/mediatek/${Project}/artifacts/out/target/product/${Project}/system/lib/目录下,若无 so 库,则去掉此步;
6)     
重新 build 整个工程
 
 
三、如何预置APK使得用户可以卸载?
有两种方法:
方法一:
7)     
 packages/apps 下面以需要预置的 APK 名字创建文件夹,以 预制一个名为TestAPK为例
8)     
 Test.apk 放到 packages/apps/Test 下面;
9)     
  packages/apps/Test 下面创建文件 Android.mk,文件内容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Module name should match apk name to be installed
LOCAL_MODULE := Test
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := PRESIGNED
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
include $(BUILD_PREBUILT)
 
10)   
打开文件 build/target/product/${Project}.mk (其中 ${Project} 表示工程名)
    
 Test 添加到 PRODUCT_PACKAGES 里面。
11)   
将从Test.apk解压出来的 so库拷贝到alps/vendor/mediatek/${Project}/artifacts/out/target/product/${Project}/system/lib/目录下,若无 so 库,则去掉此步;
12)   
重新 build 整个工程
注意:这个比不能卸载的多了一句
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
方法二:
4
 将需要预置的 apk 拷贝到:
vendor/mediatek/${Project}/artifacts/out/target/product/${Project}/data/app/
5
 重新 build 整个工程
注意:如果没有相应目录则需手动创建。
 
四、如何使得用户在将预置的 APK 卸载后,恢复出厂设置时能恢复?
为了让用户在将预置的 APK 卸载后,恢复出厂设置时能恢复,敝司做了一个 Feature,但在ALPS.GB.TDFD.MP.V1.7 ALPS.GB.FDD2.MP.V4.7版本后支持,若贵司版本低于此版本,请申请 Patch ALPS00092543
大致的做法是:
  - 
vendor/mediatek/project_name/artifacts/out/target/product/project_name/system目录下新建一个名为appbackup的文件夹,将该应用的apk文件copyappbackup文件夹下
  - 
mediatek/config/project_name/ProjectConfig.mk文件中添加定义:MTK_SPECIAL_FACTORY_RESET=yes
   -
vendor/mediatek/project_name/artifacts/out/target/product/project_name/data/app下创建一个.restore_list,并且在其中添加语句:
/system/appbackup/xxx.apk
(注意,.restore_list中的每一行都要以"/system” 开头)
当卸载了data/app下的apk后,再恢复出厂设置,系统会从 .restore_list 中读取apk的名字,然后从 appbackup 文件中把apk重新拷贝到data/app下,从而恢复data/app下已经卸载了的apk

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值