02-3:default、符号可见性与menuconfig
验证方式:Zephyr 本地文档、.config、autoconf.h、native_sim/native/64
验证结论:模拟确认
1. 本节目标
理解四个问题:
- 为什么
default只是候选值,而不是强制值; - 多个
default同时存在时如何选择; - prompt 为什么决定 symbol 是否能由用户配置;
- 如何用
menuconfig查一个 symbol 的当前值、依赖和来源。
2.default只是没有更强配置时的候选值
实验定义:
config LEARN_TIMEOUT_MS int "Timeout selected by ordered defaults" range 100 5000 default 2000 if LEARN_VERBOSE default 500可以这样理解:
如果配置文件或用户已经给出合法值 -> 使用用户值 否则 -> 从上到下寻找第一个条件满足的 default因此:
| 条件 | 最终值 |
|---|---|
LEARN_VERBOSE=y,没有显式设置 timeout | 2000 |
LEARN_VERBOSE=n,没有显式设置 timeout | 500 |
| 配置文件显式设置 timeout=123 | 123 |
default不是赋值锁,也不会阻止用户覆盖。
3. 多个default的顺序
Kconfig 从上到下处理默认项,使用第一个当前可用的 default。
default 2000 if LEARN_VERBOSE default 500当LEARN_VERBOSE=y时:
- 第一条条件成立,选择 2000;
- 后面的 500 不再覆盖它。
如果顺序写反:
default 500 default 2000 if LEARN_VERBOSE无条件的 500 总是先匹配,后面的条件默认值就没有机会生效。
所以通常把更具体、带条件的 default 放前面,把通用 fallback 放最后。
4. 实验一:使用条件默认值
defaults.conf:
CONFIG_LEARN_FEATURE=y CONFIG_LEARN_VERBOSE=y CONFIG_LEARN_VISIBLE_VALUE=42它没有设置:
CONFIG_LEARN_TIMEOUT_MS=...因为LEARN_VERBOSE=y,预期 timeout 使用条件默认值 2000。
构建命令:
cd~/project/exportZEPHYR_SDK_INSTALL_DIR=/home/yff/zephyr-sdk/zephyr-sdk-0.17.1sourcezephyr/zephyr-env.sh west build\-bnative_sim/native/64\/mnt/c/study/1-zephyr/labs/ch02_kconfig\--build-dir /mnt/c/study/1-zephyr/work/ch02_defaults\-palways\---DCONF_FILE=defaults.conf west build\--build-dir /mnt/c/study/1-zephyr/work/ch02_defaults\-trun实际输出中的对应行:
defaults: timeout_ms=2000 visible=42 hidden_mirror=42最终.config:
CONFIG_LEARN_TIMEOUT_MS=2000 CONFIG_LEARN_VISIBLE_VALUE=42 CONFIG_LEARN_HIDDEN_MIRROR=425. 实验二:显式值覆盖 default
defaults_override.conf:
CONFIG_LEARN_FEATURE=y CONFIG_LEARN_VERBOSE=y CONFIG_LEARN_TIMEOUT_MS=123 CONFIG_LEARN_VISIBLE_VALUE=42虽然条件默认值 2000 仍满足,但显式合法值 123 优先。
west build\-bnative_sim/native/64\/mnt/c/study/1-zephyr/labs/ch02_kconfig\--build-dir /mnt/c/study/1-zephyr/work/ch02_defaults_override\-palways\---DCONF_FILE=defaults_override.conf实际输出中的对应行:
defaults: timeout_ms=123 visible=42 hidden_mirror=42两个 build 的最终配置对比:
ch02_defaults: TIMEOUT_MS=2000 ch02_defaults_override: TIMEOUT_MS=123结论:显式合法值 123 的优先级高于满足条件的 default 2000。
6. 可见 symbol:有 prompt
config LEARN_VISIBLE_VALUE int "Visible source value" range 1 99 default 7引号中的:
"Visible source value"就是 prompt。
有 prompt 的 symbol:
- 能在
menuconfig中显示; - 在依赖满足时可以由用户修改;
- 可以在
.conffragment 中赋值; - 仍然受到类型、range 和 dependencies 约束。
注意:有 prompt 不代表任何时候都可见。如果depends on不满足,它会暂时隐藏或不可编辑。
7. 不可见 symbol:没有 prompt
config LEARN_HIDDEN_MIRROR int default LEARN_VISIBLE_VALUE它只有类型,没有 prompt,所以是 invisible symbol。
不可见 symbol:
- 不在普通
menuconfig菜单中供用户直接修改; - 不应该在 application
.conf中直接赋值; - 通常由
default、select、imply或其他表达式计算; - 适合表达内部能力、派生状态和 helper。
本实验中:
LEARN_VISIBLE_VALUE=42 ↓ default LEARN_VISIBLE_VALUE LEARN_HIDDEN_MIRROR=42隐藏 symbol 仍会出现在最终.config和autoconf.h,只是用户没有直接控制权。
8. 错误示范:给 invisible symbol 赋值
hidden_invalid.conf:
CONFIG_LEARN_VISIBLE_VALUE=42 CONFIG_LEARN_HIDDEN_MIRROR=99LEARN_HIDDEN_MIRROR没有 prompt,配置文件中的 99 不会成为正常用户选择。最终值仍应由:
default LEARN_VISIBLE_VALUE得到 42,并伴随赋值无效相关 warning。
原则:
.conf主要配置有 prompt 的 visible symbols;invisible symbols 应由 Kconfig 逻辑计算。
该 warning 将在02-5集中分析。
9. 运行menuconfig
必须先有一个已经配置过的 build directory。本节使用:
west build\--build-dir /mnt/c/study/1-zephyr/work/ch02_defaults\-tmenuconfig常用操作:
| 按键 | 作用 |
|---|---|
| 方向键/Enter | 浏览和进入菜单 |
| Space | 切换 bool/tristate |
/ | 按 symbol 名称搜索 |
? | 查看当前项目帮助 |
A | 显示/隐藏当前不可见 symbol |
S | 保存 |
D | 保存最小配置,只保留偏离默认值的 symbol |
Q或 Esc | 退出 |
建议依次搜索:
LEARN_TIMEOUT_MS LEARN_VISIBLE_VALUE LEARN_HIDDEN_MIRROR LEARN_DEPENDS_CLIENT观察:
- timeout 显示当前值 2000,并能看到两个 defaults;
- visible value 可以编辑;
- hidden mirror 没有 prompt,普通模式下不可直接编辑;
- depends client 在 required backend 关闭时不可见或不可选。
10.menuconfig修改的是谁
交互界面保存时修改:
build/zephyr/.config它不会自动修改:
prj.conf defaults.conf Kconfig所以 menuconfig 非常适合:
- 探索配置;
- 查看 symbol 的定义位置、依赖和反向依赖;
- 临时试验某个值;
- 导出 minimal config 后再人工整理到
.conf。
但直接 pristine rebuild 会重新生成.config,临时修改可能丢失。要永久保存,应把需要的配置写回合适的.conf文件。
11. 两个容易混淆的menuconfig
11.1 构建 target:menuconfig
west build-tmenuconfig这是终端交互配置界面。
11.2 Kconfig 关键字:menuconfig
USS 主开关写成:
menuconfig USS_TDK_ICU30201 bool "TDK ICU30201 ..."这里的menuconfig是 Kconfig 定义关键字。它表示这个 symbol 可以作为其后相关配置的菜单入口。
二者名字相同,但作用不同:
west build -t menuconfig -> 启动配置界面 menuconfig FOO -> 在 Kconfig 中定义可展开的菜单型 symbol12. 本节结论
default 仅在没有更强用户值时提供候选值 多个 default 使用第一个条件满足的项 有 prompt symbol 对用户可见、可配置 但仍受 dependencies 控制 无 prompt invisible symbol 由 default/select/imply/表达式计算 不应在普通 .conf 中直接赋值 menuconfig 界面 编辑 build/zephyr/.config 用于探索,不会自动改回源码配置 fragment13. 自测题
default 2000 if VERBOSE和配置文件显式设置 123,哪个优先?- 两个 default 的条件都满足时,选择哪一个?
- Kconfig symbol 没有 prompt 意味着什么?
- invisible symbol 是否一定不会出现在
.config和autoconf.h? - 为什么
depends on不满足时,有 prompt 的 symbol 仍可能不可见? - menuconfig 保存后修改的是
prj.conf还是 build 中的.config? west build -t menuconfig与menuconfig USS_TDK_ICU30201有什么区别?
下一节:02-4-Kconfig如何控制CMake和源码编译。