How to script make menuconfig to automate Linux kernel build configuration?
The Linux kernel build-system provide many build targets, the best way to know about it is probably to do a make help
:
Configuration targets:
config - Update current config utilising a line-oriented program
nconfig - Update current config utilising a ncurses menu based program
menuconfig - Update current config utilising a menu based program
xconfig - Update current config utilising a QT based front-end
gconfig - Update current config utilising a GTK based front-end
oldconfig - Update current config utilising a provided .config as base
localmodconfig - Update current config disabling modules not loaded
localyesconfig - Update current config converting local mods to core
silentoldconfig - Same as oldconfig, but quietly, additionally update deps
defconfig - New config with default from ARCH supplied defconfig
savedefconfig - Save current config as ./defconfig (minimal config)
allnoconfig - New config where all options are answered with no
allyesconfig - New config where all options are accepted with yes
allmodconfig - New config selecting modules when possible
alldefconfig - New config with all symbols set to default
randconfig - New config with random answer to all options
listnewconfig - List new options
olddefconfig - Same as silentoldconfig but sets new symbols to their default value
kvmconfig - Enable additional options for guest kernel support
tinyconfig - Configure the tiniest possible kernel
As jimmij says in the comments, the interesting parts are in the oldconfig
related targets.
Personally, I would recommend you to go for silentoldconfig
(if nothing changed in the .config
file or olddefconfig
if you updated your .config
file with a new kernel.
merge_config.sh
config fragments
$ cd linux
$ git checkout v4.9
$ make x86_64_defconfig
$ grep -E 'CONFIG_(DEBUG_INFO|GDB_SCRIPTS)[= ]' .config
# CONFIG_DEBUG_INFO is not set
$ # GDB_SCRIPTS depends on CONFIG_DEBUG_INFO in lib/Kconfig.debug.
$ cat <<EOF >.config-fragment
> CONFIG_DEBUG_INFO=y
> CONFIG_GDB_SCRIPTS=y
> EOF
$ # Order is important here. Must be first base config, then fragment.
$ ./scripts/kconfig/merge_config.sh .config .config-fragment
$ grep -E 'CONFIG_(DEBUG_INFO|GDB_SCRIPTS)[= ]' .config
CONFIG_DEBUG_INFO=y
CONFIG_GDB_SCRIPTS=y
Process substitution does not work unfortunately:
./scripts/kconfig/merge_config.sh arch/x86/configs/x86_64_defconfig \
<( printf 'CONFIG_DEBUG_INFO=y\nCONFIG_GDB_SCRIPTS=y\n' )
because of: https://unix.stackexchange.com/a/164109/32558
merge_config.sh
is a simple front-end for the make alldefconfig
target.
When cross compiling, ARCH
must be exported when you run merge_config.sh
, e.g.:
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
make defconfig
./scripts/kconfig/merge_config.sh .config .config-fragment
The merged output file can be specified explicitly with the KCONFIG_CONFIG
environment variable; otherwise it just overwrites .config
:
KCONFIG_CONFIG=some/path/.config ./scripts/kconfig/merge_config.sh .config .config-fragment
Buildroot automates it with BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES
: https://stackoverflow.com/questions/1414968/how-do-i-configure-the-linux-kernel-within-buildroot
Related: https://stackoverflow.com/questions/7505164/how-do-you-non-interactively-turn-on-features-in-a-linux-kernel-config-file