Zephyr学习 - 第二章-1:depends on`与配置文件合并
02-1depends on与配置文件合并验证方式源码、生成配置、native_sim/native/64验证结论模拟确认1. 本节目标理解四个问题depends on如何限制 Kconfig symbol为什么关闭的布尔配置通常不会生成值为0的 C 宏CONF_FILE和EXTRA_CONF_FILE有什么区别如何通过.config、autoconf.h和 ELF 证明配置结果。实验源码C:\study\1-zephyr\labs\ch02_kconfig2. 实验中的依赖关系Kconfig中定义config LEARN_FEATURE bool Enable the learning feature default y config LEARN_PERIOD_MS int Learning feature period in milliseconds default 1000 range 10 5000 depends on LEARN_FEATURE config LEARN_VERBOSE bool Print verbose configuration details default n depends on LEARN_FEATURE依赖关系LEARN_FEATURE ├── LEARN_PERIOD_MS └── LEARN_VERBOSE含义不是“打开LEARN_PERIOD_MS时自动打开LEARN_FEATURE”而是只有LEARN_FEATUREy时LEARN_PERIOD_MS和LEARN_VERBOSE才允许生效。因此depends on是正向依赖约束不是自动启用依赖。3. 功能开启时的基线prj.confCONFIG_LEARN_FEATUREy CONFIG_LEARN_PERIOD_MS250 CONFIG_LEARN_GREETINGKconfig is active CONFIG_LEARN_VERBOSEy运行结果*** Booting Zephyr OS build v4.1.0-rc1 *** greetingKconfig is active featureenabled period_ms250 verbose: period is provided by Kconfig最终.configCONFIG_LEARN_FEATUREy CONFIG_LEARN_PERIOD_MS250 CONFIG_LEARN_GREETINGKconfig is active CONFIG_LEARN_VERBOSEy最终autoconf.h#defineCONFIG_LEARN_FEATURE1#defineCONFIG_LEARN_PERIOD_MS250#defineCONFIG_LEARN_GREETINGKconfig is active#defineCONFIG_LEARN_VERBOSE14. 关闭主功能disabled.confCONFIG_LEARN_FEATUREn CONFIG_LEARN_GREETINGfeature is disabled4.1 使用CONF_FILE替换主配置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_disabled\-palways\---DCONF_FILEdisabled.conf west build\--build-dir /mnt/c/study/1-zephyr/work/ch02_disabled\-trunCONF_FILEdisabled.conf表示本次 application configuration 使用disabled.conf替代默认的prj.conf。实际输出*** Booting Zephyr OS build v4.1.0-rc1 *** greetingfeature is disabled featuredisabled period_msnot compiled5. 关闭后的生成结果5.1.config# CONFIG_LEARN_FEATURE is not set CONFIG_LEARN_GREETINGfeature is disabled这里需要注意布尔值n保存为# CONFIG_LEARN_FEATURE is not set而不是CONFIG_LEARN_FEATUREn这是 Kconfig 最终.config的常见表示方式。5.2autoconf.h#defineCONFIG_LEARN_GREETINGfeature is disabled以下宏完全没有生成CONFIG_LEARN_FEATURE CONFIG_LEARN_PERIOD_MS CONFIG_LEARN_VERBOSE所以 C 代码不能假设关闭的 bool symbol 一定存在且等于0。6.IS_ENABLED()为什么安全不安全写法if(CONFIG_LEARN_FEATURE){/* ... */}关闭功能后CONFIG_LEARN_FEATURE没有定义这段代码可能编译失败。安全写法if(IS_ENABLED(CONFIG_LEARN_FEATURE)){/* ... */}IS_ENABLED()能把“宏定义为 1”和“宏不存在”转换成可用的编译期常量1或0。适合两条分支都具备完整声明、都能通过编译的情况。7. 为什么还需要#if实验代码#ifdefined(CONFIG_LEARN_FEATURE)printf(period_ms%d\n,CONFIG_LEARN_PERIOD_MS);#elseprintf(period_msnot compiled\n);#endif当LEARN_FEATUREn时CONFIG_LEARN_PERIOD_MS也不存在。如果改成普通运行期ifif(IS_ENABLED(CONFIG_LEARN_FEATURE)){printf(%d\n,CONFIG_LEARN_PERIOD_MS);}预处理器和编译器仍然需要解析CONFIG_LEARN_PERIOD_MS可能因宏不存在而报错。因此IS_ENABLED() 适合两条代码路径自身都能编译 #if/#ifdef 适合某些类型、宏、API 或源码只在配置开启时存在8. ELF 也能证明代码被移除执行strings /mnt/c/study/1-zephyr/work/ch02_disabled/zephyr/zephyr.elf\|rgverbose:|period is provided结果没有输出。这说明字符串verbose: period is provided by Kconfig没有进入关闭版本的 ELF。相关代码不是运行后“跳过”而是在编译阶段被排除了。9.EXTRA_CONF_FILE的冲突实验如果使用west build\-bnative_sim/native/64\/mnt/c/study/1-zephyr/labs/ch02_kconfig\--build-dir /mnt/c/study/1-zephyr/work/ch02_disabled_extra\-palways\---DEXTRA_CONF_FILEdisabled.conf配置合并顺序为prj.conf FEATUREy PERIOD250 VERBOSEy disabled.conf FEATUREn ↓ 最终 FEATUREndisabled.conf关闭了 feature但prj.conf对 dependent symbols 的旧请求仍然存在。Kconfig 因此警告LEARN_PERIOD_MS was assigned the value 250 but got the value unsatisfied dependencies: LEARN_FEATURE (n) LEARN_VERBOSE was assigned the value y but got the value n unsatisfied dependencies: LEARN_FEATURE (n)本次实验仍能完成构建但配置 fragment 之间存在逻辑冲突。不要只看“编译成功”还要读 Kconfig warning。10.CONF_FILE与EXTRA_CONF_FILECONF_FILE 指定 application 主配置文件 设置后不再默认使用 prj.conf EXTRA_CONF_FILE 在主配置文件之后追加一个或多个 fragment 不会删除主配置中的旧赋值请求选择原则完整的另一套应用配置使用CONF_FILE在主配置基础上增加少量调试选项使用EXTRA_CONF_FILE多个 fragment 必须保证依赖关系一致任何assigned ... but got ...警告都应检查。11. 为什么LEARN_GREETING仍然存在LEARN_GREETING的定义没有depends on LEARN_FEATURE因此即使 feature 关闭它仍然是一个有效的独立 symbol并生成#defineCONFIG_LEARN_GREETINGfeature is disabled这说明 Kconfig 只按照明确定义的依赖关系计算不会根据 symbol 名称或开发者意图猜测依赖。12. 本节结论depends on 限制当前 symbol 何时允许生效 不会自动打开依赖项 booln .config 中通常表示为 “# CONFIG_xxx is not set” autoconf.h 中通常不生成宏 IS_ENABLED() 安全判断可能不存在的 bool CONFIG 宏 #if/#ifdef 在预处理阶段彻底排除依赖不存在的代码 CONF_FILE 替换主 application configuration EXTRA_CONF_FILE 在主配置之后继续追加 fragment14. 自测题depends on会自动把它依赖的 symbol 设置为y吗为什么CONFIG_LEARN_FEATUREn后autoconf.h中找不到该宏为什么IS_ENABLED(CONFIG_LEARN_FEATURE)可以编译而直接使用该宏可能失败什么情况下必须使用#if defined(...)为什么关闭 feature 后CONFIG_LEARN_GREETING仍然存在想完全换一套 application 配置时应使用CONF_FILE还是EXTRA_CONF_FILEKconfig 输出assigned y but got n时说明了什么下一节02-2-select、imply与depends-on的区别。