Android.mk脚本结构

下面是main.mk文件包含关系,本文档主要说明的就是这些文件里到底做了什么。(这个文件被根目录下的makefile文件包含)

一.     main.mk

1.检查版本号,设置环境变量(BUILD_SYSTEM)和缺省的目标。$(MAKE_VERSION) >= 3.81,BUILD_SYSTEM= build/core

2.包含文件BUILD_SYSTEM/config.mk。根据配置信息和主机目标机信息,设置一些变量。

3.包含文件BUILD_SYSTEM/cleanbuild.mk。如果当前配置改变,强制删除上次的编译结果

4.包含文件OUT_DIR/version_check.mk。就设置了VERSIONS_CHECKED。如果版本序号改变,即 VERSION_CHECK_SEQUENCE_NUMBER!=VERSIONS_CHECKED,检查文件系统是否大小写不敏感。文件路径上是否没有 空格。JAVA,JAVAC的版本是否是1.6。

5.包含文件BUILD_SYSTEM/definitions.mk。定义了很多函数供makefile文件系统使用。

主要的是transform-xxx-to-xxx的形式,比如transform-cpp-to-o。并定义了一个make目标dist,额外的拷贝一些重要的文件到目标文件夹。

6.检查MAKECMDGOALS和TARGE_BUILD_VARIANT.根据MAKECMDGOALS设置标量is_sdk_build,是否编译SDK。

7.根据TARGE_BUILD_VARIANT,设置tags_to_install,ADDITIONAL_DEFAULT_PROPERTIES

 TARGE_BUILD_VARIANT tags_to_install   ADDITIONAL_DEFAULT_PROPERTIES
user user ro.secure=1 ro.allow.mock.location=0
eng user debug eng ro.setupwizard.mode=OPTIONAL
tests user debug eng  
sdk user debug eng xmpp.auto-presence=true ro.config.nocheckin=yes
user debug user debug ro.sercure=1 dalvik.vm.lockprof.threshold=500 
ro.allow.mock.location=0
ro.debuggable=1 persist.service.adb=1

8.检查PARDUCT_TAG是否包含dalvik.gc.type-precise,如果包含设置ADDITIONAL_DEFAULT_PROPERTIES+=dalvik.vm.dexopt-flags=m=y

9.判断PRODUCT_COPY_FILES。为空就安装apns-conf.xml文件

PRODUCT_COPY_FILE=development/data/etc/apns-conf_sdk.xml:system/etc/apns-conf.xml

如果TARGE_BUILD_VARIANT包含eng,tests但不包含sdk,且vendor/google/etc/apns-
conf.xml文件存在,则PRODUCT_COPY_FILE=vendor/google/etc/apns-conf.xml:system
/etc/apns-conf.xml

10.设置ADDITIONAL_BUILD_PROPERTIES+= net.bt.name=Android

dalvik.vm.stack-trace-file=/data/anr/traces.txt

11.如果MAKECMDGOALS仅包含showcommands或checkbuild,设置make目标为DEFAULT_GOALS

12.如果MAKECMDGOALS不包含clean,clobber,dataclean,installclean,根据不同的主机平台和处理器品平台,包含进要编译的模块,设置subdirs。

13.通过build/tools/findleaves.py,把subdirs目录下的Android.mk存在subdirs_makefiles。并包含这些文件。如果使用mm命令,只包含当前目录下的Android.mk。

14.若是全部编译,包含frameworks/policies/base/PolicyConfig.mk。生成android.policy模块,并定义了自己的make删除操作policy_installclean。

15.根据tags_to_install和is_sdk_build,设置哪些模块需要安装,并存入modules_to_install.

这里主要有两个函数要说明一下:

get-tagged-modules $1 $2  这两个参数一般都是ALL_MODULE_TAGS=debug eng
gnuoptional samples testsuser里面的值,取得$1中不包括$2的列表,比如tests
user,返回$(ALL_MODULE_TAGS.user)$(ALL_MODULE_TAGS.tests)即带有user或tests标记模块的
目标文件路径列表。

Module-installed-files $1  $1一般的是一个短的模块名,比如framework,Browers,返回这个模块的目标文件路径

16.包含:$(BUILD_SYSTEM)/Makefile。主要是定义了一些伪目标。

17.定义modules_to_check,文件路径列表,若模块没有定义LOCAL_DONT_CHECK_MODULE,会把生成目标的规则加入到这个变量,以便在modules_to_install后检查目标是否生成成功,目标不存在的话再次生成目标。

18.定义一些make target

target

说明

.PHONY:checkbuilt

checkbuilt: $(modules-to-check)

生成没有定义LOCAL_DONT_CHECK_MODULE的模块并拷贝到系统目录

.PHONY:prebuilt

prebuit: $(ALL_PREBUILT)

拷贝预遍野的文件(比如用include prebuild.mk编译的)到系统目录

.PHONY: files

files: prebuilt checkbuilt moduls-to-install  $(INSTALLED_ANDROID_INFO_TXT_TARGET)

生成所有目标文件(包括:prebuile,modules-to-install,modules-to-
check,INSTALLED_ANDROID_INFO_TXT_TARGET)并拷贝到系统目录。
INSTALLED_ANDROID_INFO_TXT_TARGET在build/target/board/Android.mk定义=out
/target/product/**/android-info.txt

.PHONY: ramdisk

ramdisk: $(INSTALL_RAMDISK_TARGET)

生成ramdisk.img

$(HOST_OUT_EXECUTABLES)/mkbootfs $(PRODUCT_OUT)/root|$(HOST_OUT_EXECUTABLES)/minizip >  $(PRODUCT_OUT)/ramdisk.img

.PHONY: systemimage

systemimage: $(INSTALL_SYSTEMIMAGE)

生成system.img

$(INSTALLED_SYSTEMIMAGE): $(BUILT_SYSTEMIMAGE)

$(HOST_OUT_EXECUTABLES)/mkyaffs2image$(PRODUCT_OUT)/system$(PRODUCT_OUT)/obj/PACKING/systemimage_unopt_intermediates/system.img

cp **/system.img (PRODUCT_OUT)/system.img

.PHONY: userdataimage

userdataimage:$(INSTALL_USERDATAIMAGE_TARGET)

生成data.img

$(HOST_OUT_EXECUTABLES)/mkyaffs2image $(PRODUCT_OUT)/data $(PRODUCT_OUT)/data.img

.PHONY: bootimage

bootimage: $(INSTALL_BOOTIMAGE_TARGET)

生成boot.img

if(TARGET_NO_KERNEL=true), INSTALL_BOOTIMAGE_TARGET=$(PRODUCT_OUT)/boot.img else $(PRODUCT_OUT)/boot.img=.

参数:

INTERNAL_BOOTIMAGE_ARGS := \

$(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET)) \

--kernel $(INSTALLED_KERNEL_TARGET) \

--ramdisk $(INSTALLED_RAMDISK_TARGET)

$(HOST_OUT_EXECUTABLES)/mkbootimg --kernel $(PRODUCT_OUT)/kernel –ramdisk $(PRODUCT_OUT)/ramdisk.img >$(PRODUCT_OUT)/boot.img

.PHONY: recoveryimage

recoveryimage:$(INSTALL_RECOVERYIMAGE_TARGET)

生成ramdisk-recovery.img recovery.img

目录$(PRODUCT_OUT)

rm -rf  recovery

mkdir -p recovery

mkdir -p recovery/root

mkdir -p recovery/root/etc

mkdir -p recovery/root/tmp

cp -R root  recovery/root

cp -f  /bootable/recovery/init.rc recovery/root/

cp -f  obj/EXECUTABLES/recovery_intermediates/recovery  recovery/root/sbin/

cp -rf  /bootable/recovery/res recovery/root/

$(foreach item,/build/target/product/**/recovery/res

cp -rf $(item) recovery/root/)

cp /obj/PACKAGING/ota_keys_ intermediates/keys recovery/res/keys

cat root/default.prop system/build.prop > recovery/root/default.prop

$(HOST_OUT_EXECUTABLES)/mkbootfs$(PRODUCT_OUT)/recovery/root|$(HOST_OUT_EXECUTABLES)/minizip
> $(PRODUCT_OUT)/ramdisk-recovery.img

$(HOST_OUT_EXECUTABLES)/mkbootimg --kernel
$(PRODUCT_OUT)/kernel –ramdisk$(PRODUCT_OUT)/ramdisk-recovery.img >
$(PRODUCT_OUT)/recovery.img

.PHONY: droidcore

droidcore: files \

systemimage \

$(INSTALLED_BOOTIMAGE_TARGET) \

$(INSTALLED_RECOVERYIMAGE_TARGET) \

$(INSTALLED_USERDATAIMAGE_TARGET) \

$(INSTALLED_FILES_FILE)

生成整个系统

system.img ramdisk.img/boot.img ramdisk-recovery.img recovery.img userdata.img  installed-files.txt

.PHONY: apps_only

生成TARGET_BUILD_APPS指定的APPS模块.

若TARGET_BUILD_APPS包含all就编译全部APPS模块

droid

默认target。

ifneq ($(TARGET_BUILD_APPS),)

droid: apps_only

else

droid:droidcore

.PHONY: sdk

生成sdk

.PHONY: clean

.PHONY: clobber

删除生成文件

.PHONY: modules

显示所有模块名

.PHONY: showcommands

显示命令

二.    config.mk

1.设置一些原文件路径,以SRC_开头

2.包含文件$(BUILD_SYSTEM)/pathmap.mk,定义了一些短名到长路径名的影射,

存放在pathmap_INCL,通过include-path-for $1 根据短名获取到长路径名FRAMEWORKS_BASE_JAVA_SRC_DIRS 保存了所有要编进Android.jar的framework/base下的文件路径。

3.设置编译目标,.jar,.bin,.so,.a,.apk,...。以BUILD_开头,指向具体的mk文件。比如BUILD_STATIC_LIBRARY:= $(BUILD_SYSTEM)/static_library.mk

4.设置一般编译选项和不同类型的文件后缀名。以COMMON_开头。COMMON_GLOBAL_CFLAGS,COMMON_RELEASE_CFLAGS。COMMON_PACKAGE_SUFFIX:=.zip

5.包含include$(TOPDIR)buildspec.mk。设置一些主要的变量,比如目标产品名称。这些都要我们在make之前设置。这个文件有个模版是build/buildspec.mk.default。

6.包含include$(BUILD_SYSTEM)/envsetup.mk。设置一些跟product相关的变量。

7.在build/target/board/$(TARGET_DEVICE)/BroadConfig.mk,device/*
/$(TARGET_DEVICE)/BroadConfig.mk veror/*/$(TARGET_DEVICE)
/BroadConfig.mk 这三个路径下,查找product的目标设备的BroadConfig.mk文件。并包含进来。
BroadConfig.mk设置了每个设备的自己的一些变量值,来区别编译时的行为。TARGET_CPU_ABI
必须要设置。这些设备是被product.mk中 TARGET_DEVICE指定,一个设备信息可以被很多个product使用。

8.设置combo_target := HOST_,包含include $(BUILD_SYSTEM)/combo/select.mk。

根据操作系统和CPU类型设置以HOST_开头的变量,并包含include$(BUILD_SYSTEM)/combo
/HOST_$(HOST_OS)_$(HOST_ARCH).mk,其中HOST_OS是主机操作系统,HOST_ARCH是主机CPU类型,比如
HOST_linux_x86.mk.在这个文件里修改以HOST_开头的变量,主要是向HOST_GLOBAL_CFLAGS添加标志。

9.设置combo_target := TARGET_,包含include $(BUILD_SYSTEM)/combo/select.mk。

根据操作系统和CPU类型设置以TARGET_开头的变量,并包含include$(BUILD_SYSTEM)/combo
/TARGET_$(TARGET_OS)_$(TARGET_ARCH).mk,其中TARGET_OS是目标操作系统,TARGET_ARCH是目标
CPU类型,比如TARGET_linux_arm.mk.在这个文件里修改以TARGET_开头的变量,主要是设置交叉编译工具和参数和基本的系统头文
件。定义了transform-o-to-shared-lib-inner,transform-o-to-executable-
inner,transform-o-to-static-executable-inner三个函数,把.o文件分别转化成共享库文件,可执行文件,静
态库文件。

10.包含 include$(BUILD_SYSTEM)/combo/javac.mk。得到一个JAVAC编译器

CUSTOM_JAVA_COMPILER

COMMON_JAVAC

eclipse

=java -Xmx256m -jar prebuilt/common/ecj/ecj.jar -5 \  -maxProblems 9999999 -nowarn

openjdk

= prebuilt/common/openjdk/bin/javac -target 1.5 \ -Xmaxerrs 9999999

others

Windows: = development/host/windows/prebuilt/javawrap.exe -J-Xmx256m \ -target 1.5 -Xmaxerrs 9999999

Other:=javac -J-Xmx512M -target 1.5 -Xmaxerrs 9999999

11.检查BUILD_ENV_SEQUENCE_NUMBER,这个是在前面的buildspec.mk设置或者通过envsetup.sh脚本设置。

12.设置主机通用工具变量。其中一些是主机自带的LEX:= flex

YACC:=bison -d   DOXYGEN:=
doxygen,还有一些是在/out/target/$($(HOST_OS)-$(HOST_ARCH))/bin下的程
序,MKBOOTIMG:=$(HOST_OUT_EXECUTABLES)/mkbootimg。

13.设置最终的编译连接参数。有如下参数变量:

HOST_GLOBAL_CFLAGS,   HOST_RELEASE_CFLAGS,     HOST_GLOBAL_CPPFLAGS,

HOST_RELEASE_CPPFLAGS, TARGET_GLOBAL_CFLAGS,   TARGET_RELEASE_CFLAGS,

TARGET_GLOBAL_CPPFLAGS,TARGET_RELEASE_CPPFLAGS, HOST_GLOBAL_LD_DIRS,

TARGET_GLOBAL_LD_DIRS, HOST_PROJECT_INCLUDES,   TARGET_PROJECT_INCLUDES,

13.获得sdk和ndk的版本号列表。TARGET_AVAILABLE_SDK_VERSIONS和TARGET_AVAILABLE_NDK_VERSIONS

三.  envsetup.mk

1.包含:include$(BUILD_SYSTEM)/version_defaults.mk 设置那些我们需要设置的变量的缺省值。这个文件我们不因该改动,改动应该在build_id.mk里。

PLATFORM_VERSION

2.2.1

PLATFORM_SDK_VERSION

8

PLATFORM_VERSION_CODENAME

REL

DEFAULT_APP_TARGET_SDK

PLATFORM_SDK_VERSION

BUILD_ID

MASTER

BUILD_NUMBER

eng.$(USER).$(date)

2.设置在文件buildspec.mk里或通过envsetup.sh设置的变量的缺省值。

TARGET_PRODUCT

generic(TARGET_SIMULATOR := false)

sim(TARGET_SIMULATOR:=false)

TARGET_BUILD_VARIANT

eng

HOST_OS

windows/linux/darwin

HOST_ARCH

x86/ppc

HOST_BUILD_TYPE

release

TARGET_OS

linux

TARGET_ARCH

arm

TARGET_BUILD_TYPE

release

3.包含:include$(BUILD_SYSTEM)/product_config.mk。定义了两种MAKECMDGOALS参数形式,根据product和device目录下的mk文件生成相应的PRODUCTS_xxx_xxx和DEVICES_xxx_xxx变量。中间的是文件的路径,后面的是文件里定义的变量。

4.设置一些列路径变量。主机路径以HOST_OUT_* 或HOST_*_OUT_*形式,目标机路径以TARGET_OUT_* 或TARGET_*_OUT_*形式。

5.根据MAKECMDGOALS,若其中包含dumpvar-%或dumpvar-abs-%,就生成一个以dumpvar-%或
dumpvar-abs-%命名的make目标。实现是打印出%所表示的变量的值。这个变量必须要在这之前已经定义了,后一种在前面还打印出当前的路径。
这两种情况必须要先设置CALLED_FROM_SETUP=true。envsetup.sh的get_build_var和
get_abs_build_var()函数就是运用的这个原理打印变量的值。

  1. # Get the exact value of a buildvariable.
  2. function get_build_var()
  3. {
  4. T=$(gettop)
  5. if [ ! "$T" ]; then
  6. echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
  7. return
  8. fi
  9. CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
  10. make--no-print-directory -C "$T" -f build/core/config.mk dumpvar-$1
  11. }
  12. # Get the value of a build variable asan absolute path.
  13. function get_abs_build_var()
  14. {
  15. T=$(gettop)
  16. if [ ! "$T" ]; then
  17. echo "Couldn't locate the top of the tree.  Try setting TOP." >&2
  18. return
  19. fi
  20. CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
  21. make --no-print-directory -C "$T"-f build/core/config.mk dumpvar-abs-$1
  22. }

四. product_config.mk

1.定义两种命令形式:

makePRODUCT-<prodname>-<goal>

TARGET_PRODUCT := prodname  TARGET_BUILD_VARIANT := goal

make APP-<appnames>

TARGET_BUILD_APPS := appnames

2.包含:include$(BUILD_SYSTEM)/node_fns.mk

include $(BUILD_SYSTEM)/product.mk

include $(BUILD_SYSTEM)/device.mk

这三个文件主要是定义了一些函数来相互调用或供product_config.mk文件调用

函数名

说明

node_fns.mk   Import- nodes $(1) $(2) $(3)

import-nodes需要3个入口参数:
$(1)是一个字串,是输出变量的主干名。例如”PRODUCTS"和”DEVICES“。
$(2)是一个makefile文件列表,这些文件中应该含有对$(3)中变量的定义。
$(3)是一个变量列表。

import-
nodes会创建这样形式的变量,以$(1)="PRODUCTS",$(2)中含有"build/target/product/core.mk",
$(3)中含有"PRODUCT_NAME",而且core.mk中定义了PRODUCT_NAME:=core为例,
PRODUCT.build/target/product/core.mk.PRODUCT_NAME:=core

import-
nodes中还考虑了inherit的问题,如果某个PRODUCT.xxx.xxx变量的值中有‘@inherit:<mk文件>’标识后
面跟的是mk文件名,则会把那个mk文件中相应的变量的属性添加到PRODUCT.xxx.xxx中。'@inherit:<mk文件>'是
inherit-product命令添加的。这个函数在product.mk。

product.mk   
 _find-android-products-files

得到device/和vendor/, 包括子目录,以及build/target/product/下的AndroidProducts.mk文件列表

product.mk   
 get-all-product-makefiles

得到所有AndroidProducts.mk文件中 PRODUCT_MAKEFILES变量定义的mk文件列表

product.mk    
 import-products

调用import-nodes(node_fns.mk),设置$1=PRODUCTS,设置$3=$(_product_var_list),_product_var_list是以PRODUCT_开头的变量名。

product.mk   
inherit-product

将在所有的PRODUCT_xxx变量值后缀加上'@inherit:<mk文件>'

product.mk    
check-all-products

检查PRODUCT_NAME,PRODUCT_BRAND,PRODUCT_COPY_FILES定义的是否正确

product.mk    
resolve-short-product-name

根据product的名字,得到定义它的mk文件路径

(resolve-short-product-name generic → /build/target/product/generic.mk)

device.mk      
import-devices

调用import-nodes(node_fns.mk),设置$1=DEVICES,设置$3=$(_device_var_list),_device_var_list是以DEVICE_开头的变量名。

device.mk     
 inherit-device

将在所有的DEVICE_变量值后缀加上'@inherit:<mk文件>'

device.mk      
resolve-short-device-name

根据device的名字,得到定义它的mk文件路径

3.调用import-products函数,判断TARGET_BUILD_APPS是否为空,若为空,只导入

$(SRC_TARGET_DIR)/product/AndroidProducts.mk里的mk文件。否则调用get-all-product-makefiles,导入全部mk文件。再调用check-all-products检查变量设置的正确性。

4.根据要编译的目标TARGET_PRODUCT,通过调用resolve-short-product-name得到mk文件,结果存
放在INTERNAL_PRODUCT变量里。再将PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_xxx的值赋值给
PRODUCT_xxx。ADDITIONAL_BUILD_PROPERTIES追加PRODUCT_PROPERTY_OVERRIDES。这些
PRODUCT_变量都在product下的mk文件里定义。如下:

TARGET_DEVICE,PRODUCT_LOCALES
,PRODUCT_BRAND, PRODUCT_MODEL, PRODUCT_MANUFACTURER, PRODUCT_DEFAULT_WIFI_CHANNELS, PRODUCT_POLICY,PRODUCT_COPY_FILES,
PRODUCT_PROPERTY_OVERRIDES, PRODUCT_PACKAGE_OVERLAYS, 
DEVICE_PACKAGE_OVERLAYS,  PRODUCT_TAGS,PRODUCT_OTA_PUBLIC_KEYS

五.  cleanbuild.mk

1. 定义了add-clean-step函数。有一个入口参数$(1),执行删除操作的具体shell命令。
一般add-
clean-step应当在%/cleanspec.mk脚本中使用,命令会为$(1)定义一个变量保存,变量的名字是
INTERNAL_STEP.$(_acs_id),所有的$(_acs_id)保存在INTERNAL_STEPS中。$(_acs_id)的值分成3
个部分构造:
第一部分是有cleanspec.mk的路径转化而来,用'_'替代'/','-'替代'.',后缀_acs。

第二部分是$(INTERNAL_CLEAN_BUILD_VERSION),默认是4。

第三部分是有'@'组成,cleanspec.mk中的第几个add- clean-step就用几个@。

例如,packages/apps/Camera/cleanspec.mk中定义了两个删除动作

$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/APPS/Camera*)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/Camera*)
那么,对应的生成变量有:

INTERNAL_STEP.packages_apps_Camera_CleanSpec-mk_acs4@:= rm -rf $(PRODUCT_OUT)/obj/APPS/Camera*
INTERNAL_STEP.packages_apps_Camera_CleanSpec-mk_acs4@@ := rm -rf$(OUT_DIR)/target/common/obj/APPS/Camera*

INTERNAL_CLEAN_STEPS+=packages_apps_Camera_CleanSpec-mk_acs4@:

INTERNAL_CLEAN_STEPS+packages_apps_Camera_CleanSpec-mk_acs4@@:

2.包含:$(BUILD_SYSTEM)/cleanspec.mk。设置INTERNAL_CLEAN_BUILD_VERSION
:=3,并通过add-clean-step函数,加进一些默认的删除操作,在通过build/tools/findleaves.py枚举所有的
CleanSpec.mk文件,并把它们包含进来。在这些文件里根据具体的模块加删除操作。

3.包含:$(PRODUCT_OUT)/clean_steps.mk。这个文件是自动生成的,设置CURRENT_CLEAN_BUILD_VERSION :=INTERNAL_CLEAN_BUILD_VERSION

4.比较CURRENT_CLEAN_BUILD_VERSION和INTERNAL_CLEAN_BUILD_VERSION若相等执行
INTERNAL_CLEAN_STEPS里的命令,否则表示我们修改过cleanspec.mk, 删除整个$(OUT_DIR)。

5.包含:$(PRODUCT_OUT)/previous_build_config.mk。这个文件也是自动生成的,查看
PREVIOUS_BUILD_CONFIG是否于当前的编译选项一致。不相同就强制删除中间文件,并将当前的编译选项写入文件。删除的文件是由
installclean_files,dataclean_files定义。PREVIOUS_BUILD_CONFIG的格式
是$(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)$(building_sdk)-{$(locale_list)}。

6.定义两个make目标installclean和dataclean。分别用来删除安装文件和数据文件。

六.   Makefile

1.生成一些记录文件

(1).生成$(OUT_DOCS)/index.html文件,将frameworks/base/docs/docs-redirect-index.html文件内容拷贝进去。

(2).生成$(TARGET_ROOT_OUT)/default.prop文件,将ADDITIONAL_DEFAULT_PROPERTIES的值写入文件。生成$(TARGET_OUT)/build.prop文

件,主要存放的是build.properties,主要来自于三个方面(1,通过执行build/tools/buildinfo.sh根据
PRODUCT_NAME变量值...获得2.文
件$(TARGET_DEVICE_DIR)/system.prop3.ADDITIONAL_BUILD_PROPERTIES变量值)。

(3).生成文件$(PRODUCT_OUT)/sdk/sdk-build.prop,拷贝$(TARGET_OUT)/build.prop内容,并修改sdk_build_prop_remove定义的属性列表值都为generic。

(4).生成文件$(PRODUCT_OUT)/module-info.txt,列出全部模块的信息,需声明CREATE_MODULE_INFO_FILE。

2.定义一些make target

3.包含$(BUILD_SYSTEM)/tasks目录下的所有.mk文件。

七.         模块下的Android.mk的说明

以camera为例:

  1. LOCAL_PATH:= $(call my-dir)
  2. ifeq ($(USE_CAMERA_STUB),)
  3. USE_CAMERA_STUB:=false
  4. ifneq ($(filter sooner genericsim,$(TARGET_DEVICE)),)
  5. USE_CAMERA_STUB:=true
  6. endif #libcamerastub
  7. endif
  8. ifeq ($(USE_CAMERA_STUB),true)
  9. #
  10. # libcamerastub
  11. #
  12. include $(CLEAR_VARS)
  13. LOCAL_SRC_FILES:=               \
  14. CameraHardwareStub.cpp      \
  15. FakeCamera.cpp
  16. LOCAL_MODULE:= libcamerastub
  17. ifeq ($(TARGET_SIMULATOR),true)
  18. LOCAL_CFLAGS += -DSINGLE_PROCESS
  19. endif
  20. LOCAL_SHARED_LIBRARIES:= libui
  21. include $(BUILD_STATIC_LIBRARY)
  22. endif # USE_CAMERA_STUB
  23. #
  24. # libcameraservice
  25. #
  26. include $(CLEAR_VARS)
  27. LOCAL_SRC_FILES:=               \
  28. CameraService.cpp
  29. LOCAL_SHARED_LIBRARIES:= \
  30. libui \
  31. libutils \
  32. libbinder \
  33. libcutils \
  34. libmedia \
  35. libcamera_client \
  36. libsurfaceflinger_client
  37. LOCAL_MODULE:= libcameraservice
  38. LOCAL_CFLAGS +=-DLOG_TAG=\"CameraService\"
  39. ifeq ($(TARGET_SIMULATOR),true)
  40. LOCAL_CFLAGS += -DSINGLE_PROCESS
  41. endif
  42. ifeq ($(USE_CAMERA_STUB), true)
  43. LOCAL_STATIC_LIBRARIES += libcamerastub
  44. LOCAL_CFLAGS += -includeCameraHardwareStub.h
  45. else
  46. LOCAL_SHARED_LIBRARIES += libcamera
  47. endif
  48. include $(BUILD_SHARED_LIBRARY)

1.   include $(CLEAR_VARS)

这一步一般都要在文件头部包含。CLEAR_VARS=build/core/clear_vars.mk,在这个文件里将所有以LOCAL_开头的变量置为空,除了LOCAL_PATH.因为每个模快都公用同一个LOCAL_变量,防止干扰。

2.    LOCAL_PATH:=$(call my-dir)

通过调用my-dir函数获得当前目录。

3.    设置以LOCAL_开头的变量

LOCAL_SRC_FILES   需要的源文件,不需要包含它的依赖文件,因为编译时会自动的添加

LOCAL_C_INCLUDES  一些额外的头文件路径

LOCAL_SHARED_LIBRARIES  需要的共享库

LOCAL_MODULE      C,C++ 本模块的名字,必须是唯一的

LOCAL_PACKAGE_NAME  JAVA的LOCAL_MODULE

LOCAL_MODULE_TAGS   模块标记,一般的取值范围:debug eng tests optionalsamples shell_ash shell_mksh,默认optional

LOCAL_MODULE_CLASS 这个不用我们自己定义,系统会根据生成模块类型的不同赋值。取值:APPS,JAVA_LIBRARIES,SHARED_LIBRARIES,STATIC_LIBRARIES,EXECUTABLES

LOCAL_MODULE_PATH 模块的生成后存放的路径,不用定义,有默认值

LOCAL_MODULE_SUFFIX 后缀名,不用定义,有默认值(.apk,.jar,.so,.a)

LOCAL_BUILT_MODULE_STEM
编译目标要生成的文件名,如果我们定义了    LOCAL_BUILT_STEM值就
是$(LOCAL_BUILT_STEM)$(LOCAL_MODULE_SUFFIX),否则就
是$(LOCAL_MODULE)$(LOCAL_MODULE_SUFFIX)。若要编译JAVA的库文件和执行文件会被置为jablib.jar和
package.apk。

LOCAL_INSTALLED_MODULE_STEM  定义规则跟LOCAL_BUILT_MODULE_STEM相同,但是不会有设置为单一值的情况。

LOCAL_BUILT_MODULE 编译目标完整的路径和文件名

LOCAL_PRELINK_MODULE只有在编译.so的时候才会有的选项,主要是通过预链接的方式来加快程序启动和执行的速度,如果设置
是真的话,那你要在build/core/prelink-linux-arm.map中定义你的库需要使用的空间,空间不够的话会报错

4.    include$(BUILD_SHARED_LIBRARY)

BUILD_SHARED_LIBRARY在config.mk里有定义,指向相应的.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

主要分为两种类型:prebuilt和bin/lib文件。这些.mk文件都包含build/core/base_rule.mk。这个文件的作用如下:

(1).  根据LOCAL_IS_HOST_MODULE,LOCAL_MODULE_CLASS,LOCAL_MODULE这三个变量的值来判断这个模块是否是全局唯一的,我们应该使LOCAL_MODULE全局唯一的。

(2). 设置LOCAL_MODULE_PATH的默认值。
LOCAL_MODULE_PATH:=$($(my_prefix)OUT$(use_data)_$(LOCAL_MODULE_CLASS))若
my_prefix=TARGET_ use_data=””  LOCAL_MODULE_CLASS=APPS
则LOCAL_MODULE_PATH=$(TARGET_OUT_APPS)。TARGET_OUT_APPS在envsetup.mk定义
TARGET_OUT_APPS=out/target/product/generic/system/app

(3). 设置LOCAL_BUILT_MODULE的默认值。
LOCAL_BUILT_MODULE:=$(built_module_path)/$(LOCAL_BUILT_MODULE_STEM),built_module_path
就是编译目标存放的路径。有两种路经built_module_path=target/common/obj
/$(LOCAL_MODULE_CLASS)/$(LOCAL_MODULE)__intermediates
/,built_module_path=/target/product/generic/obj/$(LOCAL_MODULE_CLASS)
/$(LOCAL_MODULE)__intermediates/。以Camera为例:LOCAL_BUILT_MODULE=out/target
/product/generic/obj/APPS/Camera_intermediates/Camera.apk。

(4).  设置LOCAL_INSTALLED_MODULE的默认值。
LOCAL_INSTALLED_MODULE=$(LOCAL_MODULE_PATH)/$(LOCAL_MODULE_SUBDIR)$(LOCAL_INSTALLED_MODULE_STEM),
这里LOCAL_MODULE_SUBDIR留给我们自己定义一般为空。但是要记得的是当我们设置了它之后,要在每个模块的最后要将这个值清空,因为默认
CLEAR_VARS是不会清空这个值的。以Camera为例:LOCAL_INSTALLED_MODULE=out/target/product
/generic/system/app/Camera.apk

(5).  将.aidl和.logtags文件转化为.java文件,存放在out/target/common/obj /src/,out/target/common/obj/目录是JAVA的中间文件的存放目录

(6). 定义.PHONY:$(LOCAL_MODULE)目标规则.拷贝$(LOCAL_BUILT_MODULE)
到$(LOCAL_INSTALLED_MODULE),这两个变量的值前面都有说明。若不想把这个模块编译进系统的话,声明
LOCAL_UNINSTALLABLE_MODULE即可(只适用于静态库)。在这里只是拷贝文件,真正的编译工作是在它的外层.mk文件做的,并把生
成的目标文件放在$(LOCAL_BUILT_MODULE)。若是prebuild就不需要编译了,只是将已经存在的文件做简单的拷贝工作。当我们要安
装指定的模块到系统的时候,只要make $(LOCAL_MODULE)就行了。定义cleantarget目标规则,删
除$(LOCAL_BUILT_MODULE),$(LOCAL_INSTALLED_MODULE), $(intermediates)文件或目录

(7).  定义或添加以ALL_MODULES.开头的值,将本模块变量保存起来。

ALL_MODULES.$(LOCAL_MODULE).CLASS
ALL_MODULES.$(LOCAL_MODULE).PATH
ALL_MODULES.$(LOCAL_MODULE).TAGS
ALL_MODULES.$(LOCAL_MODULE).CHECKED
ALL_MODULES.$(LOCAL_MODULE).BUILT
ALL_MODULES.$(LOCAL_MODULE).INSTALLED
ALL_MODULES.$(LOCAL_MODULE).REQUIRED
ALL_MODULES.$(LOCAL_MODULE).EVENT_LOG_TAGS

ALL_MODULE_TAGS

ALL_MODULE_TAGS.$(LOCAL_MODULE_TAGS)

ALL_MODULE_NAME_TAGS

(8).  包含$(BUILD_SYSTEM)/notice_files.mk,这个我没细看估计是生成本模块的NOTICE文件

zz android 系统 makefile文件(Android.mk)组织结构的更多相关文章

  1. 在Android系统中修改Android.mk使其同时编译rgb2565和rgb2888(向out/host/linux-x86/bin/下新增加一个工具命令)【转】

    本文转载自:http://blog.csdn.net/mu0206mu/article/details/7514559 在Android系统中修改android.mk使其同时编译rgb2565和rgb ...

  2. linux和Android的Makefile和android.mk

    1. makefile 1.1 gcc的参数 -Wall: 是打开警告开关, -O:    代表默认优化,可选:-O0不优化,-O1低级优化,-O2中级优化,-O3高级优化,-Os代码空间优化. -g ...

  3. Android系统定制——Download Android System 及加载system镜像文件

    定制android系统(配置及相关系统的镜像文件),具体可参考:Driver_All_in_One_V1.0——MT6735_6753.pdf文档,特别需要理解的是Download部分. 与之对应的软 ...

  4. 【Android 系统开发】Android框架 与 源码结构

    一. Android 框架 Android框架层级 : Android 自下 而 上 分为 4层; -- Linux内核层; -- 各种库 和 Android运行环境层; -- 应用框架层; -- 应 ...

  5. 【Android 系统开发】 Android 系统启动流程简介

    作者 : 万境绝尘 (octopus_truth@163.com) 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/3889548 ...

  6. android编译系统的makefile文件Android.mk写法如下

    (1)Android.mk文件首先需要指定LOCAL_PATH变量,用于查找源文件.由于一般情况下Android.mk和需要编译的源文件在同一目录下,所以定义成如下形式:LOCAL_PATH:=$(c ...

  7. android编译系统的makefile文件Android.mk写法

    Android.mk文件首先需要指定LOCAL_PATH变量,用于查找源文件.由于一般情况下Android.mk和需要编译的源文件在同一目录下,宏函数“my-dir”右编译系统提供的,用于返回当前路径 ...

  8. android系统的文件夹选择器

    aFileChooser: https://github.com/iPaulPro/aFileChooser/issues, 这个是最适合android的文件选择器,看看有无可能改成文件夹选择器. f ...

  9. 【410】Linux 系统 makefile 文件

    makefile 主要是用来合并编译文件 CC = gcc puzzle: puzzle.c boardADT.o $(CC) puzzle.c boardADT.o -o puzzle -lm bo ...

随机推荐

  1. 点击listview 的列头对其item进行自动排序

    若要自定义排序顺序,必须编写一个实现 IComparer 接口的类,并将 ListViewItemSorter 属性设置为该类的一个对象.当设置 ListViewItemSorter 属性值时,将自动 ...

  2. Log4j 密码屏蔽

    Log4j filter to mask Payment Card numbers (PCI DSS) According to PCI DSS (Payment Card Industry Data ...

  3. yii2源码学习笔记(十二)

    继续了解controller基类. /** * Runs a request specified in terms of a route.在路径中指定的请求. * The route can be e ...

  4. 前端工程的构建工具对比 Gulp vs Grunt

    1. Grunt -> Gulp 早些年提到构建工具,难免会让人联想到历史比较悠久的Make,Ant,以及后来为了更方便的构建结构类似的Java项目而出现的Maven.Node催生了一批自动化工 ...

  5. mysqli_fetch_assoc与mysqli_result::fetch_assoc区别

    mysqli_fetch_assoc与mysqli_result::fetch_assoc区别

  6. 未能解析此远程名称:'nuget.org'

    今天用Nuget下一个程序包时,发现Nuget挂了:未能解析此远程名称:'nuget.org'.第一反应就是方校长抖威风了,挂个代理上 http://nuget.org 试了下,果然好好的. 用命令n ...

  7. Python 手册(一)

    Python 手册 Guido van Rossum Fred L. Drake,  Jr., editor PythonLabs Email: python-docs@python.org Rele ...

  8. C与OC、C++的区别

    C语言的特点:1)C语言是结构化语言,层次清晰,调试和维护比较容易2)表现能力和处理能力比较强,可直接访问内存的物理地址3)c语言实现对硬件的编辑,c语言课用语系统软件的开发,也可用语应用软件的开发, ...

  9. poj 1273

    网络流之最大流的基础题: 可以使用dinic算法和EK算法: 分别对着模板敲了一遍: dinic: #include<cstdio> #include<cstring> #in ...

  10. USB C和USB 3.1傻傻分不清?这篇文章可以帮你

    USB Type-C接口以及USB 3.1标准的到来,理应为消费者提供更多便利.然而就目前来看,似乎这些新标准非但没有为消费者提供了更好的使用体验,反而带来了诸多隐患.Google的工程师Benson ...