menuconfig++

源自 Linux 内核 kconfig / mconf 的独立配置工具。 用熟悉的图形菜单配置项目宏,生成 sdkconfig,可直接被 CMake 读取为编译宏。

menuconfig 的主菜单界面:顶部标题栏显示 .config - Main Menu,中间是可导航的配置项列表,底部是 Select / Exit / Help 按钮
mconf .config - Main Menu

# 特性

# 安装

方式一:下载预编译二进制

从 Releases 下载 menuconfig-plusplus-<版本>-linux-x86_64.tar.gz,解包后包含 mconf(图形界面)和 conf(命令行):

$ tar -xzf menuconfig-plusplus-*-linux-x86_64.tar.gz
$ cd menuconfig-plusplus-*
$ ./mconf test/rootconf

方式二:从源码构建

依赖只有 C 编译器和 ncurses 开发库:

# Debian / Ubuntu
$ sudo apt install -y libncurses-dev cmake ninja-build

$ git clone https://github.com/luskyle/menuconfig-plusplus.git
$ cd menuconfig-plusplus
$ cmake -S . -B build -G Ninja
$ cmake --build build
构建类型由 -DDEBUG 与 -DCMAKE_BUILD_TYPE 控制: 默认 DEBUG=ON 生成带调试信息的 Debug 构建,-DDEBUG=OFF 则为 Release; 显式传入 -DCMAKE_BUILD_TYPE=Release 时以你的指定为准。

# 使用

图形界面

$ ./mconf test/rootconf

把 test/rootconf 换成你自己的 kconfig 入口文件即可。退出时选择保存,配置写入 sdkconfig。

简化后的主菜单界面:顶部显示 sdkconfig - Main Menu,列出 HEX parameter、Three states、Subconfmenu、Subconfmenu2 与 Save as
mconf sdkconfig - Main Menu

命令行(非交互)

conf 与图形界面共用同一套解析逻辑,适合放进脚本或 CI:

选项说明
--oldaskconfig以行式问答方式新建配置
--oldconfig以已有 .config 为基线更新配置
--silentoldconfig <file>同 --oldconfig 但静默,并把头写入 <file>
--olddefconfig静默更新,新符号取默认值
--defconfig <file>用 <file> 中定义的默认值生成新配置
--savedefconfig <file>把当前配置的最小集保存到 <file>
--allnoconfig全部选项取 n
--allyesconfig全部选项取 y
--allmodconfig全部选项取 m
--alldefconfig全部符号取默认值
--randconfig随机应答所有选项
--listnewconfig列出新增选项
$ ./conf --alldefconfig test/rootconf
configuration written to sdkconfig

生成的 sdkconfig

#
# Automatically generated file; DO NOT EDIT.
# Main Menu
#
CONFIG_GEN_CHOICE1=y
# CONFIG_GEN_CHOICE2 is not set
CONFIG_STRING_PARAM=""
CONFIG_NUM_PARAM=0

# 接入 CMake

读取 sdkconfig 并把 CONFIG_* 转成编译宏(节选,完整版见 README):

file(STRINGS sdkconfig lines NEWLINE_CONSUME)
string(REGEX MATCHALL "(CONFIG[a-zA-Z_0-9]+)=([a-zA-Z0-9\"]+)" result ${lines})

foreach(line ${result})
    string(REPLACE "=" ";" pv ${line})
    list(GET pv 0 p)
    list(GET pv 1 v)

    if(v STREQUAL "y")
        add_compile_definitions(${p})
    else()
        add_compile_definitions(${line})
    endif()
endforeach()

# 已知问题