- 浏览: 15275 次
文章分类
最新评论
android源码makefile简解(二)
下面是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.mkveror/*/$(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()函数就是运用的这个原理打印变量的值。
- #Gettheexactvalueofabuildvariable.
- functionget_build_var()
- {
- T=$(gettop)
- if[!"$T"];then
- echo"Couldn'tlocatethetopofthetree.TrysettingTOP.">&2
- return
- fi
- CALLED_FROM_SETUP=trueBUILD_SYSTEM=build/core\
- make--no-print-directory-C"$T"-fbuild/core/config.mkdumpvar-$1
- }
- #Getthevalueofabuildvariableasanabsolutepath.
- functionget_abs_build_var()
- {
- T=$(gettop)
- if[!"$T"];then
- echo"Couldn'tlocatethetopofthetree.TrysettingTOP.">&2
- return
- fi
- CALLED_FROM_SETUP=trueBUILD_SYSTEM=build/core\
- make--no-print-directory-C"$T"-fbuild/core/config.mkdumpvar-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:=$(callmy-dir)
- ifeq($(USE_CAMERA_STUB),)
- USE_CAMERA_STUB:=false
- ifneq($(filtersoonergenericsim,$(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文件
相关推荐
Android 源码目录结构的顶级目录包括 Makefile、bionic、bootable、build、cts、dalvik、development、external、frameworks、hardware、out、packages、prebuilt、sdk、system 和 vendor 等。 * Makefile:...
其中,`Android.mk`文件是Android构建系统的核心部分,它是一个Makefile,用于指导NDK(Native Development Kit)如何处理C/C++代码。本文将深入探讨`Android.mk`文件的写法和关键知识点。 1. **LOCAL_PATH变量的...
首先,要下载Android源码,你需要一个Linux环境,因为官方的构建工具链和文档主要针对这个平台。Ubuntu是最常见的选择,但其他基于Debian的发行版也可以。确保你的系统安装了必要的依赖项,如Git、Repo、Java JDK...
### 最全的Android源码目录结构详解 在深入解析Android源码目录结构之前,我们先了解下Android系统作为全球最大的移动操作系统之一,其内部结构复杂且庞大,涉及到硬件抽象层(HAL)、应用框架、核心库等多个层次。...
首先,Android源码的获取通常依赖于Git,这是一个分布式版本控制系统。通过访问Android开源项目(AOSP)的官方仓库,开发者可以克隆完整的源码树。命令行中输入`git clone ...
在Android源码上编译APK是一个复杂但必要的过程,特别是当你需要开发具有系统权限的应用,例如修改系统时间或实现关机功能。以下是对整个流程的详细解释: 首先,你需要编译Android源码。这通常涉及到获取源码、...
在Android开发领域,深入理解Android源码是提升技术能力的关键步骤。"android源码大全"这个资源包无疑为开发者提供了一个宝贵的自学平台,涵盖了几乎所有的主流Android资源文件和源码。接下来,我们将深入探讨这个...
Android源码的编译过程涉及复杂的构建系统,主要依赖于`build.gradle`和`makefile`。使用`mm`或`mmm`命令可以编译特定模块,而`mm`用于编译当前目录下的模块,`mmm`则可以编译指定目录下的所有模块。 五、调试与...
本文将深入探讨“Android源码编译参考文档”中的关键知识点,包括高通编译参考和Android Build System。 首先,我们关注的是“高通编译参考文档”。高通是Android设备中广泛使用的芯片制造商,其编译过程涉及到特定...
在Android源码开发实战11.10这个主题中,我们深入探讨了Android系统的底层机制以及如何通过源码级别的理解来提升应用开发的效率和质量。Android作为一个开源的操作系统,其源码为我们提供了丰富的学习资源,使开发者...
在Android源码开发实战中,理解并掌握源码是提升开发者技能的关键步骤。"android源码开发实战10.10.zip"很可能是一个教程或资料集合,包含了第十章第十节的相关学习材料,聚焦于深入解析Android系统的内部运作。在这...
在Android源码开发实战中,11.11章节可能涉及了Android系统深层次的理解和定制。这个压缩包可能包含了一系列的教程、代码示例或项目文件,帮助开发者深入理解Android系统的内部工作原理,并掌握源码级别的开发技能。...
编译Android源码的过程则更为复杂,需要用到Build System,如Jenkins、Bazel或传统的Makefile。AOSP主要使用了名为“mm”(make modules)的构建脚本,它会调用Android的构建系统mmake或mmm。在源码根目录下执行以下...
5. **编译环境搭建**:使用Android源码进行开发前,需要设置合适的开发环境,包括安装SDK、NDK、Git、JDK等工具,以及配置build system,如repo和makefile。 6. **编译流程**:理解mm、mmx、mmm等命令的作用,掌握...
6. **编译与构建系统**:Android源码还包括构建工具和脚本,如`build.gradle`和`makefile`,它们控制着如何将源码编译成可执行的APK和系统镜像。了解这些工具的使用,可以帮助开发者更有效地定制和构建自己的Android...
在Android开发领域,深入理解Android源码的编译过程对于开发者来说至关重要。本文将详尽地探讨Android源码的下载、编译以及如何通过shell脚本制作镜像,旨在为开发者提供一个清晰的指南。 首先,Android源码的下载...
在Android源码开发实战4.22的压缩包中,我们很显然会深入探讨与Android系统相关的编程技术,特别是从源码级别的理解。这通常包括Android操作系统的基本架构、组件系统、UI框架、运行时环境、服务框架以及应用程序的...
在Android源码开发实战3.03的课程中,我们深入探讨了Android系统的内部机制以及如何利用源码进行应用开发。这个压缩包包含了丰富的学习资料,让我们一起剖析其中的关键知识点。 1. **Android源码结构**:Android...
在Android源码开发实战19.20的内容中,我们可以深入探索Android系统的内部运作机制以及如何利用源码进行应用开发。这一部分的学习通常涉及到以下几个关键知识点: 1. **Android源码结构**:Android源码是一个庞大的...
3. **编译与调试**:Android源码的构建过程涉及Makefile规则,使用`mm`或`mmm`命令进行模块编译。了解AOSP的编译流程和使用adb进行设备调试是源码开发的基础技能。 4. **Kernel层面**:在15.03版本中,可能涉及到对...