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:这里会在终端输出你要打印的变量,只是输出一个警告信息,但是编译仍然可以继续

如下,这是我在源码中自己加的打印语句:

android makejar 配置 android makefile_Makefile调试方法

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. 前置条件和命令是可选的,但两者必须至少存在一个。

用图来解释更形象一点:

android makejar 配置 android makefile_android makejar 配置_02

 如下为源码中的例子:
 

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.