为prj添加kconfig支持
目录
1 搭建KConfig环境
2 头文件生成脚本-kconfig.py
3 编写Kconfig文件
4 修改Makefile文件
5 关于kconfiglib中menuconfig.py的异常
1 搭建KConfig环境
安装kconfiglib时可以采用如下方式:
python -m pip install windows-curses
python -m pip install kconfiglib
linux环境:
sudo apt-get update
sudo apt install python-pip
pip install kconfiglib
安装完成后通过’menuconfig -h’ 可以验证是否安装成功,安装成功的话会输出类似以下的内容:
usage: menuconfig [-h] [KCONFIG]
Overview
========
A curses-based Python 2/3 menuconfig implementation. The interface should feel
familiar to people used to mconf ('make menuconfig').
Supports the same keys as mconf, and also supports a set of keybindings
inspired by Vi:
J/K : Down/Up
L : Enter menu/Toggle item
H : Leave menu
Ctrl-D/U: Page Down/Page Up
G/End : Jump to end of list
g/Home : Jump to beginning of list
[Space] toggles values if possible, and enters menus otherwise. [Enter] works
the other way around.
The mconf feature where pressing a key jumps to a menu entry with that
character in it in the current menu isn't supported. A jump-to feature for
jumping directly to any symbol (including invisible symbols), choice, menu or
comment (as in a Kconfig 'comment "Foo"') is available instead.
2 头文件生成脚本-kconfig.py
这里做一个相对通用的实现,可以根据传入的Kconfig、.config(保存的配置)、autoconfig.h文件的路径来读取、修改配置;生成相关C语言的位置头文件(autoconfig.h)
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import os, sys, argparse
from kconfiglib import Kconfig
from menuconfig import menuconfig
def mconf_set_env(args):
"""
Set Kconfig Env
"""
os.environ["MENUCONFIG_STYLE"] = "default selection=fg:white,bg:blue"
os.environ["KCONFIG_CONFIG"] = os.path.join(args.config_out)
os.environ["KCONFIG_CONFIG_HEADER"] = "# Generated by My Kconfig Demo"
os.environ["KCONFIG_AUTOHEADER"] = os.path.join(args.c_config_header_file_out)
os.environ["CONFIG_"] = ""
def mconfig(argv):
args = parse_args()
mconf_set_env(args)
kconf = Kconfig(args.kconfig_file)
menuconfig(kconf)
kconf.write_autoconf()
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument("--handwritten-input-configs",
action="store_true",
help="Assume the input configuration fragments are "
"handwritten fragments and do additional checks "
"on them, like no promptless symbols being "
"assigned")
parser.add_argument("kconfig_file",
help="witch Kconfig file use")
parser.add_argument("config_out",
help="Output configuration file")
parser.add_argument("c_config_header_file_out",
help="Output c config header file")
return parser.parse_args()
if __name__ == "__main__":
mconfig(sys.argv)
使用该脚本的命令格式为:
[python kconfig.py $path/kconfig_file $path/config_out $path/c_config_header_file_out]
python kconfig.py $path/Kconfig $path/.config $path/autoconfig.h
3 编写Kconfig文件
Kconfig的一些参考资料:
linux: Kconfig Language — The Linux Kernel documentation
zephyr: Configuration System (Kconfig) — Zephyr Project Documentation
博主fluidog的博文: Kconfig语法
简书上的文章: kconfig语法整理
以下是一个包含常规Kconfig使用的示例:
menu "Example Configuration Menu"
config EXAMPLE_BOOL
bool "Example boolean option"
default n
help
This is an example of a boolean option. It can be either 'y' (yes) or 'n' (no).
config EXAMPLE_TRISTATE
tristate "Example tristate option"
default m
help
This is an example of a tristate option. It can be 'y' (built-in), 'm' (module), or 'n' (disabled).
config EXAMPLE_INT
int "Example integer option"
default 10
help
This is an example of an integer option. You can enter any integer value.
config EXAMPLE_STRING
string "Example string option"
default "Hello, world!"
help
This is an example of a string option. You can enter any string value.
config EXAMPLE_HEX
hex "Example hexadecimal option"
default 0x10
help
This is an example of a hexadecimal option. You can enter any hexadecimal value.
config EXAMPLE_CHOICE
choice "Example choice option"
default EXAMPLE_CHOICE_OPTION_1
help
This is an example of a choice option. You can choose one of the following options.
config EXAMPLE_CHOICE_OPTION_1
bool "Choice Option 1"
config EXAMPLE_CHOICE_OPTION_2
bool "Choice Option 2"
endchoice
endmenu
在这个示例中,定义了一个名为 “Example Configuration Menu” 的菜单,其中包含多种类型的配置项,包括布尔值、三态值、整数、字符串、十六进制和选择项。每个配置项都有一个默认值和一个帮助文本,帮助文本用于解释该配置项的用途。
4 修改Makefile文件
.PHONY = all clean menuconfig
ROOT = $(PWD)
all: main.o autoconfig.h
gcc main.o -o main
main.o: main.c
gcc main.c -c -o main.o
clean:
rm main.o main
menuconfig:
python kconfig.py $(ROOT)/Kconfig $(ROOT)/.config $(ROOT)/autoconfig.h
5 关于kconfiglib中menuconfig.py的异常
字符串转整形莫名奇妙的抛异常,也是神奇。只能选择直接将旧的值不显示了,让用户输入新值(不再输入退格按键)。期待后续有大佬能够解惑,目前只能说能用即可了
具体为改动kconfiglib中menuconfig.py文件中的_change_node函数的实现。
def _change_node(node):
#...... 此处省略部分
while True:
s = _input_dialog(
"{} ({})".format(node.prompt[0], TYPE_TO_STR[sc.orig_type]),
s, _range_info(sc))
def _change_node(node):
#...... 此处省略部分
while True:
s = _input_dialog(
"{} ({})".format(node.prompt[0], TYPE_TO_STR[sc.orig_type]),
"", _range_info(sc))
修改_input_dialog调用的传入参数,不再传入原始的配置值。