How to script make menuconfig to automate Linux kernel build configuration?

I want to automate a Linux build but eventually get to a point where I need to run what seems to be a very manual step: make menuconfig. This seems to synchronize configs between the OS and kernel configs?

cp git-tracked-config .config
make defconfig 
make menuconfig # <- how to automate/script this?
make V=s

Basically, how can I remove the call to make menuconfig for a build script?

As an aside, this is in reaction to a build error that seems to happen when I run without ever calling make menuconfig:

make[1]: *** No rule to make target `include/config/auto.conf', needed by `include/config/kernel.release'.  Stop.

Which seems to be there is a missing rule in a makefile perhaps because the makefile itself does NOT exist or the makefile has not been generated/morphed to contain that rule but that is a separate question.

There could be a smarter way to approach this alltogether. Are there other configs that I’m not tracking but should (e.g. oldconfig)?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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.

Method 2

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=ynCONFIG_GDB_SCRIPTS=yn' )

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

Method 3

I had this same issue since I wanted to upgrade my CentOS kernel and needed to do it on several machines. Assume here my new CentOS kernel tree is in /linux-5.1 (I’m logged into the root account)

  1. cd /linux-5.1
  2. run make menuconfig and make your changes and save them to .config
  3. copy the /linux-5.1/.config file to your development server
  4. Now for your next machine to upgrade you’ll copy .config file from
    your development server to /linux-5.1/.config on the new machine.

Hope this helps someone in the same predicament.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x