Android build system note

来源:互联网 发布:明星开淘宝店 编辑:程序博客网 时间:2024/06/05 01:28
1. Android编译系统分析 
编译脚本及系统变量 
build/envsetup.sh脚本分析 
在编译源代码之前通常需要在android源代码顶层目录执行 . ./build/envsetup.sh 目的是为了使用脚本  
choosecombo 命令分析: 
function choosecombo() 

choosesim $1 
echo 
echo 
choosetype $2 
echo 
echo 
chooseproduct $3 
echo 
echo 
choosevariant $4 
echo 
set_stuff_for_environment 
printconfig 

会依次进行如下选择: 
Build for the simulator or the device? 
1. Device 
2. Simulator 
Which would you like? [1]  
Build type choices are: 
1. release 
2. debug 
Which would you like? [1]  
Product choices are: 
1. emulator 
2. generic 
3. sim 
4. littleton 
You can also type the name of a product if you know it. 
Which would you like? [littleton]  
Variant choices are: 
1. user 
2. userdebug 
3. eng 
Which would you like? [eng] user 
默认选择以后会出现: 
TARGET_PRODUCT=littleton 
TARGET_BUILD_VARIANT=user 
TARGET_SIMULATOR=false 
TARGET_BUILD_TYPE=release 
TARGET_ARCH=arm 
HOST_ARCH=x86 
HOST_OS=linux 
HOST_BUILD_TYPE=release 
BUILD_ID= 
========== 
function chooseproduct()函数分析: 
choices=(`/bin/ls build/target/board/*/BoardConfig.mk vendor/*/*/BoardConfig.mk 2> /dev/null`) 
读取 build/target/board/* 目录下的板配置文件:BoardConfig.mk 
读取 vendor/*/*/目录下的板配置文件:BoardConfig.mk 
choices 的值为: 
build/target/board/emulator/BoardConfig.mk 
build/target/board/generic/BoardConfig.mk 
build/target/board/sim/BoardConfig.mk 
vendor/marvell/littleton/BoardConfig.mk 
经过: 
for choice in ${choices[@]} 
do 
# The product name is the name of the directory containing 
# the makefile we found, above. 
prodlist=(${prodlist[@]} `dirname ${choice} | xargs basename`) 
done 
的处理,prodlist的值为: 
emulator generic sim littleton 
所以选择菜单为: 
Product choices are: 
1. emulator 
2. generic 
3. sim 
4. littleton 
如果选择 4,那么 TARGET_PRODUCT 被赋值为: littleton。 
board_config_mk := / 
$(strip $(wildcard / 
$(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk / 
vendor/*/$(TARGET_DEVICE)/BoardConfig.mk / 
)) 
怎样添加一个模块 
LOCAL_PATH:= $(call my-dir) 
#编译静态库 
include $(CLEAR_VARS) 
LOCAL_MODULE = libhellos 
LOCAL_CFLAGS = $(L_CFLAGS) 
LOCAL_SRC_FILES = hellos.c 
LOCAL_C_INCLUDES = $(INCLUDES) 
LOCAL_SHARED_LIBRARIES := libcutils 
LOCAL_COPY_HEADERS_TO := libhellos 
LOCAL_COPY_HEADERS := hellos.h 
include $(BUILD_STATIC_LIBRARY) 
#编译动态库 
include $(CLEAR_VARS) 
LOCAL_MODULE = libhellod 
LOCAL_CFLAGS = $(L_CFLAGS) 
LOCAL_SRC_FILES = hellod.c 
LOCAL_C_INCLUDES = $(INCLUDES) 
LOCAL_SHARED_LIBRARIES := libcutils 
LOCAL_COPY_HEADERS_TO := libhellod 
LOCAL_COPY_HEADERS := hellod.h 
include $(BUILD_SHARED_LIBRARY) 
BUILD_TEST=true 
ifeq ($(BUILD_TEST),true) 
#使用静态库 
include $(CLEAR_VARS) 
LOCAL_MODULE := hellos 
LOCAL_STATIC_LIBRARIES := libhellos 
LOCAL_SHARED_LIBRARIES := 
LOCAL_LDLIBS += -ldl 
LOCAL_CFLAGS := $(L_CFLAGS) 
LOCAL_SRC_FILES := mains.c 
LOCAL_C_INCLUDES := $(INCLUDES) 
include $(BUILD_EXECUTABLE) 
#使用动态库 
include $(CLEAR_VARS) 
LOCAL_MODULE := hellod 
LOCAL_MODULE_TAGS := debug 
LOCAL_SHARED_LIBRARIES := libc libcutils libhellod 
LOCAL_LDLIBS += -ldl 
LOCAL_CFLAGS := $(L_CFLAGS) 
LOCAL_SRC_FILES := maind.c 
LOCAL_C_INCLUDES := $(INCLUDES) 
include $(BUILD_EXECUTABLE) 
endif # ifeq ($(WPA_BUILD_SUPPLICANT),true) 
######################## 
#local_target_dir := $(TARGET_OUT)/etc/wifi 
#include $(CLEAR_VARS) 
#LOCAL_MODULE := wpa_supplicant.conf 
#LOCAL_MODULE_TAGS := user 
#LOCAL_MODULE_CLASS := ETC 
#LOCAL_MODULE_PATH := $(local_target_dir) 
#LOCAL_SRC_FILES := $(LOCAL_MODULE) 
#include $(BUILD_PREBUILT) 
######################## 
系统变量解析 
LOCAL_MODULE - 编译的目标对象 
LOCAL_SRC_FILES - 编译的源文件 
LOCAL_C_INCLUDES - 需要包含的头文件目录 
LOCAL_SHARED_LIBRARIES - 链接时需要的外部库 
LOCAL_PRELINK_MODULE - 是否需要prelink处理 
BUILD_SHARED_LIBRARY - 指明要编译成动态库 
LOCAL_PATH - 编译时的目录 
$(call 目录,目录….) 目录引入操作符 
如该目录下有个文件夹名称 src,则可以这样写 $(call src),那么就会得到 src 目录的完整路径 
include $(CLEAR_VARS) -清除之前的一些系统变量 
CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk 
在 build/core/config.mk 定义 CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk 
通过include 包含自定义的.mk文件(即是自定义编译规则)或是引用系统其他的.mk文件(系统定义的编译规则)。 
LOCAL_SRC_FILES - 编译的源文件 
可以是.c, .cpp, .java, .S(汇编文件)或是.aidl等格式 
不同的文件用空格隔开。如果编译目录子目录,采用相对路径,如子目录/文件名。也可以通过$(call 目录),指明编译某目录 
下所有.c/.cpp/.java/.S/ .aidl文件.追加文件 LOCAL_SRC_FILES += 文件 
LOCAL_C_INCLUDES - 需要包含的头文件目录 
可以是系统定义路径,也可以是相对路径. 如该编译目录下有个include目录,写法是include/*.h 
LOCAL_SHARED_LIBRARIES - 链接时需要的外部共享库 
LOCAL_STATIC_LIBRA RIES - 链接时需要的外部外部静态 
LOCAL_JAVA_LIBRARIES 加入jar包 
LOCAL_MODULE - 编译的目标对象 
module 是指系统的 native code,通常针对c,c++代码 
./system/core/sh/Android.mk:32:LOCAL_MODULE:= sh 
./system/core/libcutils/Android.mk:71:LOCAL_MODULE := libcutils 
./system/core/cpio/Android.mk:9:LOCAL_MODULE := mkbootfs 
./system/core/mkbootimg/Android.mk:8:LOCAL_MODULE := mkbootimg 
./system/core/toolbox/Android.mk:61:LOCAL_MODULE:= toolbox 
./system/core/logcat/Android.mk:10:LOCAL_MODULE:= logcat 
./system/core/adb/Android.mk:65:LOCAL_MODULE := adb 
./system/core/adb/Android.mk:125:LOCAL_MODULE := adbd 
./system/core/init/Android.mk:20:LOCAL_MODULE:= init 
./system/core/vold/Android.mk:24:LOCAL_MODULE:= vold 
./system/core/mountd/Android.mk:13:LOCAL_MODULE:= mountd 
LOCAL_PACKAGE_NAME  
Java 应用程序的名字用该变量定义 
./packages/apps/Music/Android.mk:9:LOCAL_PACKAGE_NAME := Music 
./packages/apps/Browser/Android.mk:14:LOCAL_PACKAGE_NAME := Browser 
./packages/apps/Settings/Android.mk:8:LOCAL_PACKAGE_NAME := Settings 
./packages/apps/Stk/Android.mk:10:LOCAL_PACKAGE_NAME := Stk 
./packages/apps/Contacts/Android.mk:10:LOCAL_PACKAGE_NAME := Contacts 
./packages/apps/Mms/Android.mk:8:LOCAL_PACKAGE_NAME := Mms 
./packages/apps/Camera/Android.mk:8:LOCAL_PACKAGE_NAME := Camera 
./packages/apps/Phone/Android.mk:11:LOCAL_PACKAGE_NAME := Phone 
./packages/apps/VoiceDialer/Android.mk:8:LOCAL_PACKAGE_NAME := VoiceDialer 
BUILD_SHARED_LIBRARY - 指明要编译成动态库。 
编译的目标,用include 操作符 
UILD_STATIC_LIBRARY来指明要编译成静态库。 
如果是java文件的话,会用到系统的编译脚本host_java_library.mk,用BUILD_PACKAGE来指明。三个编译 
------------------- 
include $(BUILD_STATIC_LIBRARY) 
BUILD_STATIC_LIBRARY:= $(BUILD_SYSTEM)/static_library.mk 
------------------- 
include $(BUILD_SHARED_LIBRARY) 
./build/core/config.mk:50:BUILD_SHARED_LIBRARY:= $(BUILD_SYSTEM)/shared_library.mk 
------------------- 
include $(BUILD_HOST_SHARED_LIBRARY) 
BUILD_HOST_SHARED_LIBRARY:= $(BUILD_SYSTEM)/host_shared_library.mk 
------------------- 
include $(BUILD_EXECUTABLE) 
build/core/config.mk:51:BUILD_EXECUTABLE:= $(BUILD_SYSTEM)/executable.mk 
------------------- 
include $(BUILD_HOST_EXECUTABLE) 
./build/core/config.mk:53:BUILD_HOST_EXECUTABLE:= $(BUILD_SYSTEM)/host_executable.mk 
------------------- 
BUILD_HOST_JAVA_LIBRARY:= $(BUILD_SYSTEM)/host_java_library.mk 
------------------- 
BUILD_JAVA_LIBRARY 
./build/core/config.mk:58:BUILD_JAVA_LIBRARY:= $(BUILD_SYSTEM)/java_library.mk 
------------------ 
BUILD_STATIC_JAVA_LIBRARY 编译静态JAVA库 
./build/core/config.mk:59:BUILD_STATIC_JAVA_LIBRARY:= $(BUILD_SYSTEM)/static_java_library.mk 
------------------ 
BUILD_HOST_JAVA_LIBRARY 编译本机用的JAVA库 
./build/core/config.mk:60:BUILD_HOST_JAVA_LIBRARY:= $(BUILD_SYSTEM)/host_java_library.mk 
------------------ 
BUILD_HOST_STATIC_LIBRARY:= $(BUILD_SYSTEM)/host_static_library.mk 
BUILD_HOST_SHARED_LIBRARY:= $(BUILD_SYSTEM)/host_shared_library.mk 
BUILD_STATIC_LIBRARY:= $(BUILD_SYSTEM)/static_library.mk 
BUILD_RAW_STATIC_LIBRARY := $(BUILD_SYSTEM)/raw_static_library.mk 
BUILD_SHARED_LIBRARY:= $(BUILD_SYSTEM)/shared_library.mk 
BUILD_EXECUTABLE:= $(BUILD_SYSTEM)/executable.mk 
BUILD_RAW_EXECUTABLE:= $(BUILD_SYSTEM)/raw_executable.mk 
BUILD_HOST_EXECUTABLE:= $(BUILD_SYSTEM)/host_executable.mk 
BUILD_PACKAGE:= $(BUILD_SYSTEM)/package.mk 
BUILD_HOST_PREBUILT:= $(BUILD_SYSTEM)/host_prebuilt.mk 
BUILD_PREBUILT:= $(BUILD_SYSTEM)/prebuilt.mk 
BUILD_MULTI_PREBUILT:= $(BUILD_SYSTEM)/multi_prebuilt.mk 
BUILD_JAVA_LIBRARY:= $(BUILD_SYSTEM)/java_library.mk 
BUILD_STATIC_JAVA_LIBRARY:= $(BUILD_SYSTEM)/static_java_library.mk 
BUILD_HOST_JAVA_LIBRARY:= $(BUILD_SYSTEM)/host_java_library.mk 
BUILD_DROIDDOC:= $(BUILD_SYSTEM)/droiddoc.mk 
BUILD_COPY_HEADERS := $(BUILD_SYSTEM)/copy_headers.mk 
BUILD_KEY_CHAR_MAP := $(BUILD_SYSTEM)/key_char_map.mk 
============ 
LOCAL_PRELINK_MODULE 
Prelink利用事先链接代替运行时链接的方法来加速共享库的加载,它不仅可以加快起动速度,还可以减少部分内存开销, 
是各种Linux架构上用于减少程序加载时间、缩短系统启动时间和加快应用程序启动的很受欢迎的一个工具。程序运行时的 
动态链接尤其是重定位(relocation)的开销对于大型系统来说是很大的。 
动态链接和加载的过程开销很大,并且在大多数的系统上, 函数库并不会常常被更动, 每次程序被执行时所进行的链接 
动作都是完全相同的,对于嵌入式系统来说尤其如此。因此,这一过程可以改在运行时之前就可以预先处理好,即花一些时间 
利用Prelink工具对动态共享库和可执行文件进行处理,修改这些二进制文件并加入相应的重定位等信息,节约了本来在程序 
启动时的比较耗时的查询函数地址等工作,这样可以减少程序启动的时间,同时也减少了内存的耗用。  
Prelink的这种做法当然也有代价:每次更新动态共享库时,相关的可执行文件都需要重新执行一遍Prelink才能保 
证有效,因为新的共享库中的符号信息、地址等很可能与原来的已经不同了,这就是为什么 android framework代码一改动, 
这时候就会导致相关的应用程序重新被编译。 
这种代价对于嵌入式系统的开发者来说可能稍微带来一些复杂度,不过好在对用户来说几乎是可以忽略的。 
-------------------- 
变量设置为false那么将不做prelink操作 
LOCAL_PRELINK_MODULE := false 
默认是需要prlink的,同时需要在 build/core/prelink-linux-arm.map 中加入 
libhellod.so 0x96000000 
这个map文件好像是制定动态库的地址的,在前面注释上面有一些地址范围的信息,注意库与库之间的间隔数, 
如果指定不好的话编译的时候会提示说地址空间冲突的问题。另外,注意排序,这里要把数大的放到前面去,
按照大小降序排序。 
解析 LOCAL_PRELINK_MODULE 变量 
build/core/dynamic_binary.mk:94:ifeq ($(LOCAL_PRELINK_MODULE),true) 
ifeq ($(LOCAL_PRELINK_MODULE),true) 
$(prelink_output): $(prelink_input) $(TARGET_PRELINKER_MAP) $(APRIORI) 
$(transform-to-prelinked) 
transform-to-prelinked定义: 
./build/core/definitions.mk:1002:define transform-to-prelinked 
define transform-to-prelinked 
@mkdir -p $(dir $@) 
@echo "target Prelink: $(PRIVATE_MODULE) ($@)" 
$(hide) $(APRIORI) / 
--prelinkmap $(TARGET_PRELINKER_MAP) / 
--locals-only / 
--quiet / 
$< / 
--output $@ 
endef 
./build/core/config.mk:183:APRIORI := $(HOST_OUT_EXECUTABLES)/apriori$(HOST_EXECUTABLE_SUFFIX) 
prelink工具不是常用的prelink而是apriori,其源代码位于” /build/tools/apriori” 
参考文档: 
动态库优化——Prelink(预连接)技术 
http://www.eefocus.com/article/09-04/71629s.html 
=============== 
LOCAL_ARM_MODE := arm 
目前Android大部分都是基于Arm处理器的,Arm指令用两种模式Thumb(每条指令两个字节)和arm指令(每条指令四个字节) 
LOCAL_CFLAGS += -O3 -fstrict-aliasing -fprefetch-loop-arrays 
通过设定编译器操作,优化级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高 
LOCAL_CFLAGS += -W -Wall 
LOCAL_CFLAGS += -fPIC -DPIC 
LOCAL_CFLAGS += -O2 -g -DADB_HOST=1 -Wall -Wno-unused-parameter 
LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE -DSH_HISTORY 
LOCAL_CFLAGS += -DUSEOVERLAY2 
根据条件选择相应的编译参数 
ifeq ($(TARGET_ARCH),arm) 
LOCAL_CFLAGS += -DANDROID_GADGET=1 
LOCAL_CFLAGS := $(PV_CFLAGS) 
endif 
ifeq ($(TARGET_BUILD_TYPE),release) 
LOCAL_CFLAGS += -O2 
endif 
LOCAL_LDLIBS := -lpthread 
LOCAL_LDLIBS += -ldl 
ifdef USE_MARVELL_MVED 
LOCAL_WHOLE_STATIC_LIBRARIES += lib_il_mpeg4aspdecmved_wmmx2lnx lib_il_h264decmved_wmmx2lnx 
LOCAL_SHARED_LIBRARIES += libMrvlMVED 
else 
LOCAL_WHOLE_STATIC_LIBRARIES += lib_il_h264dec_wmmx2lnx lib_il_mpeg4aspdec_wmmx2lnx 

endif 


http://blog.csdn.net/qclzdh/article/details/6280737

原创粉丝点击