转自:http://blog.csdn.net/liwei405499/article/details/42008245
问题描述:
对于有过开发高通android系统的人来说,获取代码构建开发环境并不是难事,但对于刚刚接触这一块内容的人,如果没有详细的说明很容易走弯路,本文档就是根据本人的实践总结的一些经验教训。
1. 代码获取
高通的android代码分为两部分,一部分是开源的,可以从网站https://www.codeaurora.org/xwiki/bin/QAEP/下载,需要知道要下载的代码的分支及build id。另一部分是非开源的,需要从高通的另一个网站https://support.cdmatech.com/login/上下载,这个下载是有权限限制的,晓光的帐号可以下载代码。后面这部分代码需要放到第一部分代码的vendor指定目录下,可能是vendor/qcom-proprietary或vendor/qcom/proprietary,根据版本的不同有所区别。
高通平台相关的东西基本都在vendor/qcom/proprietary下或device/qcom下
2. 编译环境构建(ubuntu 10.04 64位)
Android2.3.x后的版本需要在64位下进行编译
更新ubuntu源,要加上deb http://archive.canonical.com/ lucid partner 这个源用来安装java。
apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev x11proto-core-dev libx11-dev libxml-simple-perl sun-java6-jdk gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev ia32-libs lib32z-dev lib32readline5-dev
研发主机不能更新java,需要让IT安装sun-java6-jdk。
在命令行执行sudo dpkg-reconfigure dash 选择no,否则编译时会报一下脚本语法错误
编译的过程中https://www.codeaurora.org/xwiki/bin/QAEP/和版本的release notes中都有介绍,首先source build/envsetup.sh,然后choosecombo选择需要的选项,最后make或make –j4。-j4用来指定参与编译的cpu个数,指定了编译会快些。编译单个模块的时候只需要在make后面跟上模块的名字
为了简化可以使用以下脚本
export TARGET_SIMULATOR=fasle
export TARGET_BUILD_TYPE=release
export TARGET_PRODUCT=msm7627a
export TARGET_BUILD_VARIANT=eng
set_stuff_for_environment
make $1
编译的中间结果在out/target/product/平台/obj目录下,有时候为了完全重新编译需要把这里对于的目录删掉。
编译的结果在out/target/product/平台/下.
Appsboot.mbn是bootloader
Boot.img是内核+ramdisk,ramdisk根据当前目录的root目录生成
System.img是板子上/system目录下的初始内容,根据当前目录的system目录生成
Userdata.img是/data目录下的内容,根据当前目录的data目录生成
3. 烧录环境构建
需要让pc识别插上的android设备,需要安装驱动,我的驱动是从BSP获得的,目前也不知道具体从哪里下载。驱动下有几个目录,弹出安装驱动的提示时挨个试就行了。
还需要android的adb和fastboot等工具,这些也是bsp提供的。
使用google的驱动应该也是可以的,在7225a上我试了是可以的,但在7625上却不行。使用google的驱动的下载需要参考http://developer.android.com/sdk/index.html
编辑google-usb_driver/ android_winusb.inf,按照已有的条目添加vid pid。
4. Flash分区烧录
Android提供了烧录flash的fastboot模式,bsp会提供进入fastboot模式的方法。进入fastboot模式后,在pc的命令行执行fastboot devices可以查看设备,执行fastboot flash boot boot.img烧录boot分区,执行fastboot flash system system.img烧录system分区,执行fastboot flash userdata userdata.img烧录data分区。有些人执行这些命令失败都是因为一些低级的错误,比如打开命令行就直接输命令,估计你自己都不知道fastboot在哪呢让命令行到哪里去找啊,或者到fastboot的目录下后执行命令,又悲剧了谁知道你把那些img文件放哪了,总不能让人家遍历整个硬盘去给你找吧。这样的问题对于开发人员来说实在不应该啊。
5. 开发调试
用前面提到的方法可以烧录各个分区,但编译烧录分区还是比较麻烦的。使用adb可以对单个文件进行操作
Adb push file /system/bin/将file上传到板子的/system/bin/目录下
Adb pull /system/bin/file file 将板子上的文件/system/bin/file下载到PC当前目录下
Adb shell进入板子的命令行
板子上根目录是只读的,如果需要写权限,需要运行mount –o remount rw /
Adb logcat可以查看日志
6. 增加软件模块
这里写的主要是如何写android.mk
(1) 增加动态库
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := a.c b.c
LOCAL_MODULE := libtest
LOCAL_C_INCLUDES := dir/include
LOCAL_CFLAGS := -g
LOCAL_LDLAGS := -lpthread
LOCAL_LDLIBS := -lpthread
LOCAL_SYSTEM_SHARED_LIBRARIES := libc libcutils
LOCAL_PRELINK_MODULE := false
include $(BUILD_SHARED_LIBRARY)
LOCAL_SRC_FILES指定源文件
LOCAL_MODULE指定模块的名字,整个andorid系统中必须唯一
LOCAL_C_INCLUDES指定需要包括的头文件路径
LOCAL_CFLAGS指定编译选项
LOCAL_LDLAGS指定链接选项
LOCAL_LDLIBS指定链接选项,和LOCAL_LDLAGS类似
LOCAL_SYSTEM_SHARED_LIBRARIES指定依赖的库,这个和LOCAL_LDLAGS不同,首先是名字是以模块名的方式指定的,其次是这里面包含的依赖关系,会导致被依赖的模块也会被编译
LOCAL_PRELINK_MODULE这个为我们编译库很重要,不加这行一般会编译失败。
最后一行开始进行编译
(2) 增加静态库
与动态库类似,把最后一句改为
Include $(BUILD_STATIC_LIBRARY)
(3) 增加应用
与动态库类似,把最后一句改为
Include $(BUILD_EXECUTABLE)
去掉LOCAL_PRELINK_MODULE
(4) 增加资源
即只需要拷贝到某个目录
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
file := $(TARGET_OUT)/etc/lctpri
$(file) : $(LOCAL_PATH)/lctpri | $(ACP)
$(transform-prebuilt-to-target)
ALL_PREBUILT += $(file)
上面这个andoird.mk的意思是将本目录下的lctpri拷贝到system/etc下, $(TARGET_OUT)是编译环境中的一个定义
(5) 特殊的例子
编译Iptables的时候需要根据模块生成一个初始化文件,android中是这样实现的
GEN_INITEXT:= $(intermediates)/extensions/gen_initext.c
$( GEN_INITEXT): PRIVATE_PATH := $(LOCAL_PATH)
$( GEN_INITEXT): PRIVATE_CUSTOM_TOOL = $(PRIVATE_PATH)/extensions/create_initext “$(EXT_FUNC)”
$( GEN_INITEXT): PRIVATE_MODULE := $(LOCAL_MODULE)
$( GEN_INITEXT):
$(transform-generated-source)
$(intermediates)/extensions/initext.o : $( GEN_INITEXT)
LOCAL_GENERATED_SOURCES := $( GEN_INITEXT)
create_initext是一个脚本文件,从svn下载下来的时候会失去可执行属性,需要改变属性。这个方式生成的gen_initext.c似乎并不会跟着选择的模块的变化而重新生成,所以需要手动将它删掉。
Android自带的代码中基本没有一个目录下既有代码又有目录的情况,而我们的代码中这种情况很常见,出现这中情况的时候需要在饱含子目录的android.mk的后面加入
include $(call all-makefiles-under,$(LOCAL_PATH))
没有找到能解决android中两个库相互依赖的方法,虽然加入$(LOCAL_ALLOW_UNDEFINED_SYMBOLS) = true后可以编译通过,但在板子中不能正常运行。
7. 编译最小系统
在编译前先定义下面的环境变量
export BUILD_TINY_ANDROID=true
编译的内容在build/core/main.mk中搜索BUILD_TINY_ANDROID即可找到,如果需要增加新的内容加在这里就行了