Kconfig相关
Kconfig相关
背景
以前准备写一下Linux内核里的Kconfig
,但一直迟迟没有动手,最近在看 Openharmony 相关的东西,发现它也可以通过Kconfig
和Kconfiglib
进行可视化配置,所以想借此机会在这一起记录一下
作用
#define
配置宏主要用来使能/关闭代码,如下面:
#define CONFIG_TEST_ENABLE
#ifdef CONFIG_TEST_ENABLE
... ... ...
#endif
或来定义配置参数,如下:
#define CONFIG_TEST_SHOW_STRING "Test 123"
#define CONFIG_TEST_SHOW_INT (123)
但是如果参数越来越多,或者配置之间的关系越来越复杂,就会让代码的可读性越来越差,管理越麻烦,且不直观。
所以Kconfig
就是用来解决这些问题的,管理这些配置参数,而且能够可视化地去配置它们
Kconfig简介
Kconfig
语言定义了一套完整的规则来表述配置项及配置项间的关系Kconfig
是配置项的描述文件,支持设置配置项及其默认值,依赖关系等等,该文件还会继续依赖各个模块的Kconfig文件。而配置(.config
)的可视化管理、生成和修改等需要其他工具(Kconfiglib
)配合来完成,且C的头文件需要单独的脚本(kconfig.py
)来生成
Kconfig
相关的语法这里就不展开了,具体可参见Linux内核中文档介绍:Kconfig Language
Kconfiglib
Kconfiglib
是读取、修改和生成 Kconfig 文件的工具,其中menuconfig
可以图形化来管理相关配置
kconfig.py
kconfig.py:c头文件生成脚本
这里使用zephyr
项目中的生成脚本https://github.com/zephyrproject-rtos/zephyr/blob/main/scripts/kconfig/kconfig.py
实践
工具包准备
需要安装以下几个东东:
安装curses库,提供配置GUI能力
sudo apt-get install libncurses5-dev
安装kconfiglib
python3 -m pip install kconfiglib
工程准备
新建目录,在目录中分别创建main.c、Makefile、Kconfig、kconfig.py
main.c
main.c,主要是根据不同的配置打印不同的信息,来测试配置项:
#include <stdio.h>
#include "autoconfig.h"
int main()
{
printf("hello, world\n");
#ifdef CONFIG_TEST_ENABLE
printf("CONFIG_TEST_ENABLE\n");
#endif
printf("CONFIG_TEST_SHOW_STRING: %s\n", CONFIG_TEST_SHOW_STRING);
printf("CONFIG_TEST_SHOW_INT: %d\n", CONFIG_TEST_SHOW_INT);
#ifdef CONFIG_TEST_TOP_ENABLE
printf("CONFIG_TEST_TOP_ENABLE\n");
#endif
#ifdef CONFIG_TEST_SUB_0_ENABLE
printf("CONFIG_TEST_SUB_0_ENABLE\n");
#endif
#ifdef CONFIG_TEST_SUB_1_ENABLE
printf("CONFIG_TEST_SUB_1_ENABLE\n");
#endif
printf("CONFIG_TEST_SHOW_SUB_INT: %d\n", CONFIG_TEST_SHOW_SUB_INT);
return 0;
}
Kconfig
Kconfig,写法跟Linux的Kernel中的Kconfig类似:
mainmenu "Kconfig Demo"
menu "Test Params setting"
config TEST_ENABLE
bool "Enable test work"
default n
help
Will print debug information if enable.
config TEST_SHOW_STRING
string "The show string info"
default "Test 123"
config TEST_SHOW_INT
int "The show int info"
range 0 255
default 123
config TEST_TOP_ENABLE
bool "Test Top Func"
default n
help
Function Test Top
config TEST_SUB_0_ENABLE
bool "Test Sub 0 Func"
default n
help
Function Test Sub 0
config TEST_SUB_1_ENABLE
bool "Test Sub 1 Func"
default n
depends on TEST_TOP_ENABLE
help
Function Test Sub 1
config TEST_SHOW_SUB_INT
int
default 456 if TEST_SUB_0_ENABLE && TEST_SUB_1_ENABLE
default 123
endmenu
Makefile
Makefile,主要是通过menuconfig
图形化配置生成.config
,然后通过kconfig.py
脚本生成c的头文件autoconfig.h
,最后通过gcc
编译main生成可执行文件:
all: main.o
gcc main.o -o main
main.o: main.c autoconfig.h
gcc main.c -c -o main.o
clean:
del main.o main
autoconfig.h:.config
python3 ./scripts/kconfig.py Kconfig .config autoconfig.h log.txt .config
.config:
menuconfig
menuconfig:
menuconfig
kconfig.py
kconfig.py,从zephyr
项目中拿来的脚本,需要屏蔽掉以下代码,不然会报错:
# if kconf.syms['WARN_DEPRECATED'].tri_value == 2:
# check_deprecated(kconf)
# if kconf.syms['WARN_EXPERIMENTAL'].tri_value == 2:
# check_experimental(kconf)
编译测试
运行make all
,首次编译因开始没有.config文件,会生成.config
和autoconfig.h
,2个文件中的配置项是对应的,只不过形式不一样而已。
后面如需修改配置参数,只需要执行make menuconfig
,再make all
重新编译。
修改不同的配置项,然后编译运行测试程序,会发现对应的打印输出会发生相应的变化