1. 前言
在学习Android源码编译的流程时,需要查看一些定义变量值,阅读makefile的代码时需要通过判断条件走到哪个分支,关键是mk文件没有特定的IDE工具去step-by-step调试,最简单原始的方法就是添加打印log,然后在原工程下make,根据打印信息去梳理代码流程和逻辑。
2. 调试方法
2.1 使用info
格式: $(info 这里写需要打印的log信息 ) ,下面为Android源码中的代码例子:
1.
$(info [1/1] initializing build system ...)
2.
ifneq ($(filter user userdebug eng,$(MAKECMDGOALS)),)
$(info ***************************************************************)
$(info ***************************************************************)
$(info Do not pass '$(filter user userdebug eng,$(MAKECMDGOALS))' on \
the make command line.)
$(info Set TARGET_BUILD_VARIANT in buildspec.mk, or use lunch or)
$(info choosecombo.)
$(info ***************************************************************)
$(info ***************************************************************)
$(error stopping)
endif
当然呢,也可以在括号中加入你想打印的变量,比如:
$(info Invalid variant: $(TARGET_BUILD_VARIANT))
$(info Valid values are: $(INTERNAL_VALID_VARIANTS))
2.2 使用warning
格式: $(warning 这里写需要打印的log信息 ),下面为源码中的例子:
ifneq ($(dangling_modules),)
$(warning: Modules '$(dangling_modules)' in PRODUCT_PACKAGES have nothing to install!)
endif
warning:这里会在终端输出你要打印的变量,只是输出一个警告信息,但是编译仍然可以继续
如下,这是我在源码中自己加的打印语句:
2.3 使用error
格式: $(error 这里写需要打印的log信息), 下面为源码中的例子:
ifeq ($(TARGET_CPU_ABI),)
$(error No TARGET_CPU_ABI defined by board config: $(board_config_mk))
endif
这段代码表达的意思:如果TARGET_CPU_ABI为空, 则走下面的代码, 会提示:
No TARGET_CPU_ABI defined by board config: build/make/core/board_config.mk
就是说 TARGET_CPU_ABI 必须定义在 board_config.mk 文件中
如果使用error调试的话,终端上会打印你的log信息,然后编译到此处就会停止
2.4 使用echo增加调试信息
如果你要用echo打印的话,必须遵循makefile的语法规则,就是必须在target之后,如下:
<target>: <prerequisites>
[Tab]<commands>
1. 第一行冒号前为目标,冒号后为前置条件;
2. 第二行必须由一个Tab键起首,后接命令;目标是必须的,不可省略;
3. 前置条件和命令是可选的,但两者必须至少存在一个。
用图来解释更形象一点:
如下为源码中的例子:
samplecode: $(sample_APKS_COLLECTION)
@echo "Collect sample code apks: $^"
# remove apks that are not intended to be installed.
rm -f $(sample_ADDITIONAL_INSTALLED)
也就是说,使用@echo增加打印log信息的话,必须在这样子的模板中加入,不能平白无故的想加哪里就加哪里,不然就会报错: commands commence before first target
当然了,我们再遵循上述规则的情况下,也可以变通一下,在某个makefile中,我想看下代码中某个变量的值,我就是任性,不想用info/warning/error 我就要用echo打印,怎么搞呢?
我们可以创建一个伪目标(makefile中的语法: .PHONY),如下:
.PHONY: nothing
nothing:
@echo Successfully read the makefiles.
.PHONY: tidy_only
tidy_only:
@echo Successfully make tidy_only.
.PHONY: modules
modules:
@echo "Available sub-modules:"
@echo "打印此变量值: $(ALL_MODULE_TAGS)"
代码解释: 首先.PHONY是makefile中的关键字, 定义了伪目标 nothing tidy_only modules
nothing:
@echo Successfully read the makefiles.
nothing 作为目标 冒号(:)后面没有依赖文件,满足第3条语法规则( 前置条件和命令是可选的,但两者必须至少存在一个)。
然后TAB键 打印自己需要的信息
最后在终端上输出 :Successfully read the makefiles.