本文的目的是介绍Android-Makefile的详细情况,我们将通过专业的研究、有关数据的分析等多种方式,同时也不会遗漏关于AndroidFileTransfer–在Mac上也能读取Android设
本文的目的是介绍Android-Makefile的详细情况,我们将通过专业的研究、有关数据的分析等多种方式,同时也不会遗漏关于Android File Transfer – 在 Mac 上也能读取 Android 设备文件、Android makefile、Android makefile 组织结构、android makefile 编译分析及 android.mk分析的知识。
本文目录一览:- Android-Makefile
- Android File Transfer – 在 Mac 上也能读取 Android 设备文件
- Android makefile
- Android makefile 组织结构
- android makefile 编译分析及 android.mk分析
Android-Makefile
1.LOCAL_MODULE_PATH
LOCAL_MODULE_PATH: 文件的安装目录
2
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
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.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()函数就是运用的这个原理打印变量的值。
- # Get the exact value of a buildvariable.
- function get_build_var()
- {
- T=$(gettop)
- if [ ! "$T" ]; then
- echo "Couldn''t locate the top of the tree. Try setting TOP." >&2
- return
- fi
- CALLED_FROM_SETUP=trueBUILD_SYSTEM=build/core \
- make--no-print-directory -C "$T" -f build/core/config.mk dumpvar-$1
- }
- # Get the value of a build variable asan absolute path.
- function get_abs_build_var()
- {
- T=$(gettop)
- if [ ! "$T" ]; then
- echo "Couldn''t locate the top of the tree. Try setting TOP.">&2
- return
- fi
- CALLED_FROM_SETUP=trueBUILD_SYSTEM=build/core \
- make --no-print-directory -C "$T"-f build/core/config.mk dumpvar-abs-$1
- }
四. 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个入口参数: |
product.mk |
得到device/和vendor/, 包括子目录,以及build/target/product/下的AndroidProducts.mk文件列表 |
product.mk |
得到所有AndroidProducts.mk文件中 PRODUCT_MAKEFILES变量定义的mk文件列表 |
product.mk |
调用import-nodes(node_fns.mk),设置$1=PRODUCTS,设置$3=$(_product_var_list),_product_var_list是以PRODUCT_开头的变量名。 |
product.mk |
将在所有的PRODUCT_xxx变量值后缀加上''@inherit:<mk文件>'' |
product.mk |
检查PRODUCT_NAME,PRODUCT_BRAND,PRODUCT_COPY_FILES定义的是否正确 |
product.mk |
根据product的名字,得到定义它的mk文件路径 (resolve-short-product-name generic → /build/target/product/generic.mk) |
device.mk |
调用import-nodes(node_fns.mk),设置$1=DEVICES,设置$3=$(_device_var_list),_device_var_list是以DEVICE_开头的变量名。 |
device.mk |
将在所有的DEVICE_变量值后缀加上''@inherit:<mk文件>'' |
device.mk |
根据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为例:
- LOCAL_PATH:= $(call my-dir)
- ifeq ($(USE_CAMERA_STUB),)
- USE_CAMERA_STUB:=false
- ifneq ($(filter sooner genericsim,$(TARGET_DEVICE)),)
- USE_CAMERA_STUB:=true
- endif #libcamerastub
- endif
- ifeq ($(USE_CAMERA_STUB),true)
- #
- # libcamerastub
- #
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES:= \
- CameraHardwareStub.cpp \
- FakeCamera.cpp
- LOCAL_MODULE:= libcamerastub
- ifeq ($(TARGET_SIMULATOR),true)
- LOCAL_CFLAGS += -DSINGLE_PROCESS
- endif
- LOCAL_SHARED_LIBRARIES:= libui
- include $(BUILD_STATIC_LIBRARY)
- endif # USE_CAMERA_STUB
- #
- # libcameraservice
- #
- include $(CLEAR_VARS)
- LOCAL_SRC_FILES:= \
- CameraService.cpp
- LOCAL_SHARED_LIBRARIES:= \
- libui \
- libutils \
- libbinder \
- libcutils \
- libmedia \
- libcamera_client \
- libsurfaceflinger_client
- LOCAL_MODULE:= libcameraservice
- LOCAL_CFLAGS +=-DLOG_TAG=\"CameraService\"
- ifeq ($(TARGET_SIMULATOR),true)
- LOCAL_CFLAGS += -DSINGLE_PROCESS
- endif
- ifeq ($(USE_CAMERA_STUB), true)
- LOCAL_STATIC_LIBRARIES += libcamerastub
- LOCAL_CFLAGS += -includeCameraHardwareStub.h
- else
- LOCAL_SHARED_LIBRARIES += libcamera
- endif
- 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分析的相关信息,请在本站查询。
本文标签: