KConfig 语言学习
- 菜单项
- 菜单属性
- 类型定义
- prompt: 输入提示
- default: 默认值
- depends on/requires: 依赖关系
- select: 反向依赖关系
- imply: 弱反向依赖关系
- visible if: 选项可见
- range: 数据范围
- help: 帮助信息
- 菜单依赖关系
- 菜单结构关系
- KConfig语法
- config: 配置项
- menuconfig: 配置菜单块
- choice/endchoice: 选择组
- comment: 注释项
- menu/endmenu: 菜单块
- if/endif: 条件块
- source: 读取项
- mainmenu: 标题栏
- #: 注释
- 参考文献
菜单项
总体原则:每一个 config 就表示一个配置选项的开始,后面紧跟着的 ARCH_AIROHA
是配置选项的名称,config 下面几行定义了该配置选项的属性:如选项名是什么,依赖什么,选中这个后同时会选择什么等等。
1. config ARCH_AIROHA
2. bool "选项名"
3. depends on ARCH_MULTI_V7
4. select ARM_AMBA
5. default n
6. help
7. Support for Airoha EN7523 SoCs
config —> 选项。
ARCH_AIROHA —> 句柄,可用于控制Makefile,选择编译方式。
bool —> 选择可能:TRUE选中、FALSE不选;选中则编译,不选中则不编译。如果后面选项名字串为空,则表示其不会出现在选择软件列表中。
depends on —> 依赖,后面的选择被选择后,这个选项才能被选。
select —> 当前选项选中后,则select后指定的选项自动被选择。
default—> 缺省配置项。
help—> 帮助信息。
菜单属性
类型定义
“bool”/“tristate”/“string”/“hex”/“int”
菜单选项可以有多个属性。并不要求这些属性可以用在任何地方。每个配置选项都必须指定类型。
在5种类型中 tristate 和 string 为基本类型,其他类型都是基于这两个基本类型。
- bool 布尔类型:取值范围为Y/N。
config BSP_USING_WDT bool "Enable Watchdog Timer" select RT_USING_WDT default n
tristate 三态类型:取值范围为Y/N/M,相较bool类型,tristate类型的菜单项多了编译成内核模块的选项。
string 字符串:默认菜单选项显示对应字符串。
config RT_CONSOLE_DEVICE_NAME string "the device name for console" default "uart1"
- int 整型
config BSP_I2C1_SCL_PIN int "I2C1 scl pin number" range 1 176 default 116
- hex 十六进制
类型定义可以用输入提示,所以下面的两个例子是等价的:
bool "Networking support"
和
bool
prompt "Networking support"
prompt: 输入提示
"prompt " [“if” ]
每个菜单选项最多只能有一个显示给用户的输入提示。可以用 “if” 来表示该提示的依赖关系,当然这是可选的。
default: 默认值
“default” [“if” ]
一个配置选项可以有任意多个默认值。如果有多个默认值,那么只有第一个被定义的值是可用的。
默认值并不是只限于应用在定义他们的菜单选项,这就意味着默认值可以定义在任何地方或被更早的定义覆盖。
如果用户没有设置(通过上面的输入提示),配置选项的值就是默认值。如果可以显示输入提示的话,就会把默认值显示给用户,并可以让用户进行修改。默认值的依赖关系可以用 “if” 添加。(可选项)
depends on/requires: 依赖关系
“depends on”/“requires”
意思是本配置项依赖于另一个配置项。如果那个依赖的配置项为Y或者M,则本配置项才有意义;如果依赖的那个配置项本身被设置为N,则本配置项根本没有意义。
depends on 依赖的配置项可以是多个,还可以有逻辑运算。这种时候只要依赖项目运算式子的结果为真则依赖就成立。
依赖关系也可以应用到该菜单中所有的其它选项(同样接受一if表达式),所以下面的两个例子是等价的:
bool "foo" if BAR
default y if BAR
和
depends on BAR
bool "foo"
default y
select: 反向依赖关系
“select” [“if” ]
表示depends on的值有效时,且当前配置选项被选中,则下面的select也会成立,将相应的内容选上。例如下面的例子表示选中BOOTLOADER_BOSSA时,也会选中USE_DT_CODE_PARTITION。
config BOOTLOADER_BOSSA
bool "BOSSA bootloader support"
select USE_DT_CODE_PARTITION
尽管普通的依赖关系可以降低选项的上限,反向依赖能将这一限制降的更低。当前菜单选项的值是symbol的最小值。如果symbol被选择了多次,上限就是其中的最大值。反向依赖只能用在 boolean 或 tristate 选项上。
imply: 弱反向依赖关系
“imply” [“if” ]
此属性和 select 相似,用于选定一个符号,但是被选定的符号仍有可能被直接依赖或用户输入设置为 n。
其选择规则为让目标选项的默认值不高于该选项的最大选项。可以看该例子:
config FOO
tristate "foo"
imply BAZ
config BAZ
tristate "baz"
depends on BAR
FOO | BAR | BAZ’s default | choice for BAZ |
---|---|---|---|
y | y | y | y/m/n |
y | m | n | m/n |
y | n | ● | n |
m | y | m | y/m/n |
m | m | m | m/n |
n | y | n | y/m/n |
n | m | n | m/n |
该机制很有用,例如,有多个驱动程序想表明它们有能力连接到一个次要的子系统,同时允许用户将该子系统配置出来,而不必同时取消这些驱动程序。
visible if: 选项可见
“visible if”
这个属性只适用于菜单块,如果条件是N,菜单块就不会显示给用户(不过其中包含的symbol仍然可以被其他symbol选中)。它类似于单个菜单项的条件性 "提示 "属性。"可见 "的默认值是Y。
range: 数据范围
“range” [“if” ]
为int和hex类型的选项设置可以接受输入值范围。用户只能输入大于等于第一个symbol,小于等于第二个symbol的值。
help: 帮助信息
“help” or “—help—”
定义一段帮助信息,解释这个配置项的含义,以及如何去配置它。帮助信息的结束就由缩进的水平决定的,这也就意味着信息是在第一个比帮助信息开始缩进小的行结束。
“—help—” 和 “help” 在实现的作用上没有区别,“—help—” 有助于将文件中的配置逻辑与给开发人员的提示分开。
菜单依赖关系
<expr> ::= <symbol> (1) // 在表达式计算的时候, bool和tristate可以对应的转化为对应的值, 其他的类型转化为 ‘n’
<symbol> '=' <symbol> (2) // 如果两者相同, 那么就返回 y,否则返回 n
<symbol> '!=' <symbol> (3) // 如果两者相同, 那么就返回 n,否则返回 y
<symbol1> '<' <symbol2> (4) // 如果symbol1比symbol2小、大、小于等于、大于等于,那么就返回 y,否则返回 n
<symbol1> '>' <symbol2> (4)
<symbol1> '<=' <symbol2> (4)
<symbol1> '>=' <symbol2> (4)
'(' <expr> ')' (5) // 返回表达式的值。用于覆盖优先级
'!' <expr> (6) // 返回 (2-/expr/) 的结果
<expr> '&&' <expr> (7) // 返回 min(/expr/, /expr/) 的结果
<expr> '||' <expr> (8) // 返回 max(/expr/, /expr/) 的结果
表达式的值可以是“n”、“m”、“y”(或计算时分别用 0、1、2 表示)。菜单项在其 表达式的计算结果为“m”或“y”。
共有两种类型的symbol:常量symbol和非常量symbol。
非常量符号是最常见的符号,用 "config "语句定义。非常量符号完全由字母数字字符或下划线组成。
常量符号只是表达式的一部分。常量符号总是被单引号或双引号所包围。在引号内,任何其他字符都是允许的,引号可以用’'转义。
菜单结构关系
一个菜单项在菜单树中的位置是通过两种方式确定的。首先,它可以被明确指定:
menu "Network device support"
depends on NET
config NETDEVICES
...
endmenu
上面例子,在 “menu” ~ “endmenu” 块内的所有条目都成为 “Network device support” 的子菜单。所有子项都继承了菜单项的依赖关系,例如,例子里的 “NET” 依赖项被加入了 “NETDEVICES” 配置项的依赖关系中。
另一种生成菜单结构的方法是通过分析依赖关系完成的。**如果一个菜单条目在某种程度上依赖于前一个条目,它就可以成为它的子菜单。**首先,前一个(父)符号必须是依赖关系列表的一部分,然后这两个条件中的一个必须为真。
- 如果父项设置为n,子项一定会变成不可见
- 如果父项可见,子项一定只能为可见
config MODULES
bool "Enable loadable module support"
config MODVERSIONS
bool "Set version information on all module symbols"
depends on MODULES
comment "module support disabled"
depends on !MODULES
例子中,MODVERSIONS 直接依赖于 MODULES,这意味着只有当MODULES不为n它才是可见的。另一方面,注释只有在MODULES被设置为’n’时才是可见的。
KConfig语法
配置文件描述了一系列菜单项,其中每行以关键字开头(帮助文本除外)。下列关键字则作为菜单项结束:
- config
- menuconfig
- choice/endchoice
- comment
- menu/endmenu
- if/endif
- source
上述前五项也作为菜单项定义的开始。
config: 配置项
"config" <symbol>
<config options>
这段话将定义一个配置符号,并接受上述任何一种菜单属性作为选项。
例如,可以使用config语句进行赋值:
choice
prompt "Flash PageSize"
default FLASH_PAGESIZE_2K
config FLASH_PAGESIZE_512
bool "512 Bytes"
config FLASH_PAGESIZE_2K
bool "2K Bytes"
config FLASH_PAGESIZE_4K
bool "4K Bytes"
config FLASH_PAGESIZE_8K
bool "8K Bytes"
config FLASH_PAGESIZE_16K
bool "16K Bytes"
endchoice
config SSC_FLASH_PAGE_SIZE
int
default 512 if FLASH_PAGESIZE_512
default 2048 if FLASH_PAGESIZE_2K
default 4096 if FLASH_PAGESIZE_4K
default 8192 if FLASH_PAGESIZE_8K
default 16384 if FLASH_PAGESIZE_16K
menuconfig: 配置菜单块
menuconfig <symbol>
<config options>
此入口和简单 config 入口相似,定义一个符号 symbol,但是也暗示一个菜单块,后接子入口。需保证所有子入口应该在此入口下方,且依赖于此入口符号。举例:
menuconfig BR2_TARGET_GENERIC_GETTY
bool "Run a getty (login prompt) after boot"
default y
if BR2_TARGET_GENERIC_GETTY
config BR2_TARGET_GENERIC_GETTY_PORT
string "TTY port"
default "console"
help
Specify a port to run a getty on.
choice
prompt "Baudrate"
default BR2_TARGET_GENERIC_GETTY_BAUDRATE_KEEP
help
Select a baudrate to use.
config BR2_TARGET_GENERIC_GETTY_BAUDRATE_KEEP
bool "keep kernel default"
config BR2_TARGET_GENERIC_GETTY_BAUDRATE_9600
bool "9600"
config BR2_TARGET_GENERIC_GETTY_BAUDRATE_19200
bool "19200"
config BR2_TARGET_GENERIC_GETTY_BAUDRATE_38400
bool "38400"
config BR2_TARGET_GENERIC_GETTY_BAUDRATE_57600
bool "57600"
config BR2_TARGET_GENERIC_GETTY_BAUDRATE_115200
bool "115200"
endchoice
config BR2_TARGET_GENERIC_GETTY_BAUDRATE
string
default "0" if BR2_TARGET_GENERIC_GETTY_BAUDRATE_KEEP
default "9600" if BR2_TARGET_GENERIC_GETTY_BAUDRATE_9600
default "19200" if BR2_TARGET_GENERIC_GETTY_BAUDRATE_19200
default "38400" if BR2_TARGET_GENERIC_GETTY_BAUDRATE_38400
default "57600" if BR2_TARGET_GENERIC_GETTY_BAUDRATE_57600
default "115200" if BR2_TARGET_GENERIC_GETTY_BAUDRATE_115200
config BR2_TARGET_GENERIC_GETTY_TERM
string "TERM environment variable"
default "vt100"
# currently observed by all but systemd
depends on !BR2_INIT_SYSTEMD
help
Specify a TERM type.
config BR2_TARGET_GENERIC_GETTY_OPTIONS
string "other options to pass to getty"
default ""
# currently observed by all but systemd
depends on !BR2_INIT_SYSTEMD
help
Any other flags you want to pass to getty,
Refer to getty --help for details.
endif
choice/endchoice: 选择组
choice [<symbol>]
<choice options>
<choice block>
endchoice
定义一个选择组。选择组类型仅仅可以设置为 bool 或 tristate,如果未指定类型,则取决于第一个选择项的类型。bool 类型只允许单个 config 入口被选择,tristate 类型允许多个 config 入口被设置为 m。
如上述例子的 baudrate 选择,其菜单展现结果如下:
comment: 注释项
"comment" <prompt>
<comment options>
定义注释语句。将多个类似的配置选项组合在一起,供用户单选或多选,并且打印到输出文件中,仅支持依赖属性。例如:
choice
bool "/bin/sh"
default BR2_SYSTEM_BIN_SH_DASH if !BR2_PACKAGE_BUSYBOX
help
Select which shell will provide /bin/sh.
# busybox has shells that work on noMMU
config BR2_SYSTEM_BIN_SH_BUSYBOX
bool "busybox' default shell"
depends on BR2_PACKAGE_BUSYBOX
config BR2_SYSTEM_BIN_SH_BASH
bool "bash"
depends on BR2_USE_MMU # bash
depends on BR2_PACKAGE_BUSYBOX_SHOW_OTHERS
select BR2_PACKAGE_BASH
config BR2_SYSTEM_BIN_SH_DASH
bool "dash"
depends on BR2_USE_MMU # dash
depends on BR2_PACKAGE_BUSYBOX_SHOW_OTHERS
select BR2_PACKAGE_DASH
config BR2_SYSTEM_BIN_SH_MKSH
bool "mksh"
depends on BR2_USE_MMU # mksh
depends on BR2_PACKAGE_BUSYBOX_SHOW_OTHERS
select BR2_PACKAGE_MKSH
config BR2_SYSTEM_BIN_SH_ZSH
bool "zsh"
depends on BR2_USE_MMU # zsh
depends on BR2_PACKAGE_BUSYBOX_SHOW_OTHERS
select BR2_PACKAGE_ZSH
comment "bash, dash, mksh, zsh need BR2_PACKAGE_BUSYBOX_SHOW_OTHERS"
depends on !BR2_PACKAGE_BUSYBOX_SHOW_OTHERS && BR2_PACKAGE_BUSYBOX
config BR2_SYSTEM_BIN_SH_NONE
bool "none"
endchoice # /bin/sh
menu/endmenu: 菜单块
"menu" <prompt>
<menu options>
<menu block>
"endmenu"
定义一个菜单块。菜单块内的其他子入口继承此项的依赖。仅支持依赖和可视属性。
if/endif: 条件块
"if" <expr>
<if block>
"endif"
定义一个条件块。条件块内的其他菜单入口追加此项的依赖表达式 expr。参考前面 menuconfig 部分的例子。
source: 读取项
"source" <prompt>
source条目用于读取另一个Kconfig文件。例如:
// /Config.in文件:
menu "Target options"
……………………
endmenu
menu "Build options"
……………………
endmenu
source "toolchain/Config.in"
// /toolchain/Config.in文件:
menu "Toolchain"
……………………
endmenu
最终显示在菜单树里的为展开后的选项列表:
mainmenu: 标题栏
"mainmenu" <prompt>
如果配置程序启用,将被显示在配置程序的标题栏。该语句应该被放在配置文件的开头,所有语句之前。例如在buildroot根目录下config.in文件开头定义了该句:
mainmenu "Buildroot $BR2_VERSION Configuration"
其最终被显示在了 menuconfig 菜单列表的标题栏。
#: 注释
除了上述语法,在源文件行任何地方出现一个未加引号的’#'字符,表示该行的其余部分是一段注释。
参考文献
[1]: Kconfig Language官网
[2]: Kconfig内容(详细)总结附示例快速掌握
[3]: Kconfig基本语法
[4]: Kconfig [@rt-thread]
[5]: kconfig语法整理