A standalone configuration tool derived from the Linux kernel's kconfig / mconf.
Configure your project's macros through the familiar menu UI and generate an sdkconfig
that CMake can read directly as compile definitions.
<Y>/<N>/<M> to toggle the highlighted entry, ? or < Help > for help, / to search — the same muscle memory as the Linux kernel's menuconfig.
bool / tristate / int / hex / string, choice, depends on, select, nested submenus and source includes.
sdkconfig (CONFIG_XXX=y form); parse it in CMake and feed it to add_compile_definitions.
ncursesw; titles, menus and help windows are centered and truncated by display width, so Chinese/Japanese/Korean entries neither misalign nor get sliced in half.
conf supports --olddefconfig / --defconfig / --savedefconfig / --allyesconfig and more, for scripts and pipelines.
Grab menuconfig-plusplus-<version>-linux-x86_64.tar.gz from Releases. It unpacks to mconf (menu UI) and conf (command line):
$ tar -xzf menuconfig-plusplus-*-linux-x86_64.tar.gz $ cd menuconfig-plusplus-* $ ./mconf test/rootconf
The only dependencies are a C compiler and the ncurses development library (it provides the wide-character library used below):
# 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 and -DCMAKE_BUILD_TYPE:
DEBUG=ON (the default) yields a Debug build with debug info, while
-DDEBUG=OFF yields Release; an explicit -DCMAKE_BUILD_TYPE=... always wins.
$ ./mconf test/rootconf
Point it at your own kconfig entry file instead of test/rootconf. On exit, choosing to save writes the configuration to sdkconfig.
conf shares the same parser as the menu UI, so it fits scripts and CI pipelines:
| Option | Description |
|---|---|
--listnewconfig | List new options |
--oldaskconfig | Start a new configuration using a line-oriented program |
--oldconfig | Update a configuration using a provided .config as base |
--silentoldconfig <file> | Same as oldconfig, but quietly; write header to <file> |
--olddefconfig | Same as silentoldconfig but sets new symbols to their default value |
--oldnoconfig | An alias of olddefconfig |
--defconfig <file> | New config with default defined in <file> |
--savedefconfig <file> | Save the minimal current configuration to <file> |
--allnoconfig | New config where all options are answered with no |
--allyesconfig | New config where all options are answered with yes |
--allmodconfig | New config where all options are answered with mod |
--alldefconfig | New config with all symbols set to default |
--randconfig | New config with random answer to all options |
$ ./conf --alldefconfig test/rootconf
configuration written to 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
Read sdkconfig and turn each CONFIG_* into a compile definition (excerpt; the full version is in the 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()
/ search, the Save as filename) do not accept typing or editing CJK text yet; displaying CJK is fine.