文章目录
- 一、 条件判断的本质:预处理
- 二、四大判断金刚
- 三、 语法细节(最容易报错的地方)
- 四、 💡 安卓工程师的实战案例:多架构适配
- 五、 💡 安卓工程师的记忆卡片
一、 条件判断的本质:预处理
一定要记住:Makefile 的条件判断是在make解析(读取)文件阶段执行的,而不是在命令执行阶段。
- 这意味着你不能在命令(Tab 开头的行)里直接写
ifeq。 - 它的作用是决定“哪些代码块”会被
make纳入执行计划。
二、四大判断金刚
| 指令 | 逻辑 | 实战场景 |
|---|---|---|
ifeq (a, b) | 如果 a 等于 b | 判断TARGET_PRODUCT是否为某个特定机型 |
ifneq (a, b) | 如果 a 不等于 b | 排除掉某些不支持的硬件模块 |
ifdef var | 如果变量var值非空 | 检查用户是否在命令行传了DEBUG=1 |
ifndef var | 如果变量var值为空 | 设置默认路径或默认开关 |
三、 语法细节(最容易报错的地方)
参数的括号:
ifeq后面可以加括号(a, b),也可以用引号"a" "b"。Android 源码中为了清晰,通常使用括号。空格的尊严:
ifeq与左括号之间必须有一个空格。- ❌
ifeq(A,B)-> 报错 - ✅
ifeq (A, B)-> 正确
- ❌
注意缩进:
if的内容体可以缩进也可以不缩进。如果选择缩进美观代码,千万不要用Tab键开头缩进,否则会被Makefile误解为命令。可以选择使用两个空格或四个空格缩进。结束标志: 每一个判断块必须以
endif结尾。
四、 💡 安卓工程师的实战案例:多架构适配
在Android.mk中,你经常会看到这种根据架构分配不同 CFLAGS 的逻辑:
# 根据 Android 目标架构选择编译优化ifeq($(TARGET_ARCH), arm64)LOCAL_CFLAGS+=-DARM64_OPTIMIZATIONelseifeq($(TARGET_ARCH), x86_64)LOCAL_CFLAGS+=-DX86_64_STABILITYelseLOCAL_CFLAGS+=-DGENERIC_ARCHendif进阶技巧:嵌套判断
你可以像写 C 语言一样嵌套判断,比如先判断是不是arm64,再判断是不是userdebug版本,从而开启更深层的日志。
五、 💡 安卓工程师的记忆卡片
ifdef的陷阱:ifdef只是测试变量是否有值。如果你定义了DEBUG =(后面是空的),那么ifdef DEBUG会被判定为假。- 不要在命令块里写判断:
如果你想在 Shell 命令里做判断,请使用 Shell 的if [ ... ]; then ... fi语法。- Makefile 判断: 控制 Makefile 规则的生成。
- Shell 判断: 控制命令在运行时如何跳过。
- 与
strip函数配合:
在 Android 源码中,为了防止变量里有看不见的空格,大牛们喜欢写:ifeq ($(strip $(LOCAL_MODULE_CLASS)), SHARED_LIBRARIES)
这能保证逻辑的绝对健壮。
【本篇自测】
请看这段代码:
DEBUG :=ifeq($(DEBUG),)FLAG :=-O2elseFLAG :=-gendif最终
FLAG的值是多少?如果把第一行改为
DEBUG := 1,执行结果会变吗?