GVKun编程网logo

Android-Makefile

22

本文的目的是介绍Android-Makefile的详细情况,我们将通过专业的研究、有关数据的分析等多种方式,同时也不会遗漏关于AndroidFileTransfer–在Mac上也能读取Android设

本文的目的是介绍Android-Makefile的详细情况,我们将通过专业的研究、有关数据的分析等多种方式,同时也不会遗漏关于Android File Transfer – 在 Mac 上也能读取 Android 设备文件、Android makefile、Android makefile 组织结构、android makefile 编译分析及 android.mk分析的知识。

本文目录一览:

Android-Makefile

Android-Makefile

1.LOCAL_MODULE_PATH

LOCAL_MODULE_PATH: 文件的安装目录

2

Android File Transfer – 在 Mac 上也能读取 Android 设备文件

Android File Transfer – 在 Mac 上也能读取 Android 设备文件

Android File Transfer – 在 Mac 上也能读取 Android 设备文件[OS X]


由于 Mac OS X 本身并不支持 MTP 协议,所以通过 USB 将 Android 设备连接到 Mac 电脑上是无法识别的,更别说读取里面的文件了。针对这一个问题, Google 官方推出了 Android File Transfer 这款工具好让 Mac 也能读取 Android 设备里的文件。


只需要在连接手机前运行 Android File Transfer ,再连接手机,那么 Mac 就会识别出 Android 设备,并可以对里面的文件进行复制、粘贴、删除等管理。启动过一次 Android File Transfer 后,以后每次只要连接 Android 设备 Android File Transfer 都会自动启动。

目前 Android File Transfer 只支持 Android 3.0 及以上的机器,支持传输最大 4GB 的文件。

Ps:很多朋友说连接到电脑了但是检测不到设备,请将连接方式设置为媒体设备(MTP)即可。

Android makefile

Android makefile


LOCAL_PATH := $(call my-dir)

{

call 函数:根据不同的参数和函数得到不同的值
my-dir 函数: 获取当前含有.mk 的路径
LOCAL_PATH: 定位源文件的位置

}


#include $(CLEAR_VARS)(必须放在 LOCAL_PATH 后面)

{
CLEAR_VARS 由编译系统提供,指定让 GNU MAKEFILE 为你清除许多 LOCAL_XXX 变量(例如 LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, 等等...),
除 LOCAL_PATH 。这是必要的,因为所有的编译控制文件都在同一个 GNU MAKE 执行环境中,所有的变量都是全局的。

}

 


LOCAL_MODULE := helloworld

{

LOCAL_MODULE 模块必须定义,以表示 Android.mk 中的每一个模块。名字必须唯一且不包含空格。

Build System 会自动添加适当的前缀和后缀。例如,foo,要产生动态库,则生成 libfoo.so. 但请注意:如果模块名被定为:libfoo. 则生成 libfoo.so. 不再加前

}

LOCAL_MODULE_PATH: 最后的目标安装路径

{

 
    问: TARGET_OUT_SHARED_LIBRARIES 是什么?
    答: 在 build/core/envsetup.mk 中定义。TARGET_OUT_SHARED_LIBRARIES:= $(TARGET_OUT)/lib
    TARGET_ROOT_OUT:表示根文件系统。
    TARGET_OUT:表示 system 文件系统。
    TARGET_OUT_DATA:表示 data 文件系统。

}

 

LOCAL_SRC_FILES := $(call all-java-files-under, src)

{

获取目录下所有 Java 文件

}

 

LOCAL_MODULE_TAGS :=user eng tests optional

{

user: 指该模块只在 user 版本下才编译

eng: 指该模块只在 eng 版本下才编译

tests: 指该模块只在 tests 版本下才编译

optional: 指该模块在所有版本下都编译

}

 

 

 

LOCAL_PACKAGE_NAME

{
指定要编译的 APK 名称

}

 

LOCAL_CERTIFICATE

{
声明 APK 的权限

}

 

 

如果一个应用程序想用系统方法和 root 权限 必须签名
1. 在应用程序的 AndroidManifest.xml 中的 manifest 节点中加入 android:sharedUserId="android.uid.system" 这个属性。
2. 修改 Android.mk 文件,加入 LOCAL_CERTIFICATE := platform 这一行
3. 使用 mm 命令来编译,生成的 apk 就有修改系统时间的权限了。



Android makefile 组织结构

Android makefile 组织结构

Android makefile 组织


标题

android makefile 编译分析及 android.mk分析

android makefile 编译分析及 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()函数就是运用的这个原理打印变量的值。

view plain print ?
  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=trueBUILD_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=trueBUILD_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为例:

view plain print ?
  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文件

 

|-- Makefile        (全局的Makefile)    
|-- bionic          (Bionic含义为仿生,这里面是一些基础的库的源代码)    
|-- bootloader      (引导加载器)    
|-- build           (build目录中的内容不是目标所用的代码,而是编译和配置所需要的脚本和工具)    
|-- dalvik          (JAVA虚拟机)    
|-- development     (程序开发所需要的模板和工具)    
|-- external        (目标机器使用的一些库)    
|-- frameworks      (应用程序的框架层)    
|-- hardware        (与硬件相关的库)    
|-- kernel          (Linux2.6的源代码)    
|-- packages        (Android的各种应用程序)    
|-- prebuilt        (Android在各种平台下编译的预置脚本)    
|-- recovery        (与目标的恢复功能相关)    
`-- system          (Android的底层的一些库)

我们今天的关于Android-Makefile的分享已经告一段落,感谢您的关注,如果您想了解更多关于Android File Transfer – 在 Mac 上也能读取 Android 设备文件、Android makefile、Android makefile 组织结构、android makefile 编译分析及 android.mk分析的相关信息,请在本站查询。

本文标签: