16

I have a situation where our software needs to work with several different Linux kernel distributions / kernel trees. (including Android forks)

In trying to automate our build process, I am finding that some of the defconfig files for particular builds we need to support do not include the kernel modules we depend on.

For example, let's imagine I need an option called XXX in my .config. For some dependencies, I can do something like this:

sed -i 's/# CONFIG_XXX is not set/CONFIG_XXX=m/' .config

For others, it's not so easy since the dependency may span multiple lines of .config statements.

Is there a more supported way to do this non-interactively, or am I stuck writing a more complex search-and-replace script?

mpontillo
  • 13,559
  • 7
  • 62
  • 90
  • Can you just create a set of .config files with the correct contents for each build? – ed. Sep 21 '11 at 19:03
  • @ed., not a bad idea. I'd rather not, though, as I need to support a large variety of kernels and it would be quite a bit more work to have a separate default `.config` for each one, given that I just need to include a couple of extra configuration options. (It's just that they often explode into a huge number of sub-options which also must be modified, and I don't know if the option names in the `.config` will change between kernel releases.) I guess that's a good argument for creating a `.config` by hand for each supported kernel build, though. ;-) – mpontillo Sep 21 '11 at 19:06
  • 2
    You could create some by hand and use diff/patch to modify similar ones. Maybe... – ed. Sep 21 '11 at 19:18
  • @ed., good idea. If the patch doesn't apply cleanly, I can call it out as a build failure. – mpontillo Sep 21 '11 at 19:50

4 Answers4

17

The kernel has a tool (./scripts/config) to change specific options on .config. Here is an example:

./scripts/config --set-val CONFIG_OPTION y

Although, it doesn't check the validity of the .config file.

Gustavo Bittencourt
  • 790
  • 1
  • 6
  • 15
7

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: How do I configure the Linux kernel within Buildroot?

Related: https://unix.stackexchange.com/questions/19905/how-to-non-interactively-configure-the-linux-kernel-build Migrated 20 days earlier :-)

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
  • To create config snippets from changes made using menuconfig (remember to save the changes as `.config.new`): `make x86_x64_defconfig; make menuconfig; diff -u .config{,.new} | sed -ne '4,$s/^+//p' > config-snippet` – ack Nov 26 '16 at 16:34
6

Yes, some config options change names between releases, sometimes as an indication of subtle semantic changes.

I have written python classes to merge together a set of configuration fragments into base kernel configuration files. That's overkill for you, though; you can do the same thing as a sed script; you aren't limited to one-liners.

sed -ir 's/^(CONFIG_XXX=.*|# CONFIG_XXX is not set)/CONFIG_XXX=m/;
         s/^(CONFIG_FOO=.*|# CONFIG_FOO is not set)/CONFIG_FOO=m/;
         s/^(CONFIG_BAR=.*|# CONFIG_BAR is not set)/CONFIG_BAR=m/' .config

Or even create a separate script. Say, config.sed that contains the lines:

s/^(CONFIG_XXX=.*|# CONFIG_XXX is not set)/CONFIG_XXX=m/;
s/^(CONFIG_FOO=.*|# CONFIG_FOO is not set)/CONFIG_FOO=m/;
s/^(CONFIG_BAR=.*|# CONFIG_BAR is not set)/CONFIG_BAR=m/;

Then you can run

sed -ire config.sed .config

Hope that helps!

mkj
  • 1,274
  • 11
  • 8
  • +1 Thanks for the reply and the additional ideas. I was just mulling parsing the Kconfig files to get the *actual* dependencies, but as you say, that might be overkill. – mpontillo Sep 21 '11 at 20:23
  • Ah, for that you might want to use the non-interactive configuration patches. I think that Arjan van de Ven orginally wrote them for the Red Hat kernel many years ago, and we used a variant of them for the rPath kernels. Probably easiest to pick them up out of the current Fedora kernel SRPMs; I think they are still there. That will take defaults after applying your changes, which will probably do what you want. – mkj Sep 22 '11 at 21:19
  • 1
    `-ire config.sed` does not work under GNU sed, it prefers the expressions in-line. `sed -i -re "``cat ../../config.sed``" .config` is the one that works for me. Note that the double backtick is a single one is real life, I only use it here to escape. – Gábor DANI Aug 14 '16 at 10:46
  • `scripts/kconfig/merge_config.sh` is a built-in script that also uses `sed`: http://stackoverflow.com/a/39440863/895245 – Ciro Santilli OurBigBook.com Sep 11 '16 at 21:33
  • I was struggling with this for quite a while. I needed to put `-r` as a separate argument instead of in the short argument cluster. My GNU `sed` as of Ubuntu 16.x+ was thinking `r` was the backup file extension argument to `-i` and not "use extended regex"! – nelsonjchen Jun 26 '17 at 02:15
3

To do a series of simple flipping of a single config while updating any and all config dependencies:

Single Option approach

./scripts/config --set-val CONFIG_OPTION y
./scripts/config --enable CONFIG_BRIDGE
./scripts/config --enable CONFIG_MODULES
./scripts/config --disable CONFIG_X25
./scripts/config --module CONFIG_NFT
make oldconfig
(updates dependencies; may prompt with new dependencies, but old deps silently goes away)

Multiple-File Merge approach

If you have several small snippets of .config-* files that you want to selectively merge into the main .config file, execute:

# Merge IP fragment CONFIG_ settings into the main .config file
./scripts/kconfig/merge_config.sh .config .config-fragment
# Merge  Notebook HW-specific CONFIG_ settings into main .config file
./scripts/kconfig/merge_config.sh .config .config-notebook-toshiba

# Auto-add/auto-remove CONFIG_ dependencies
make oldconfig

References

John Greene
  • 2,239
  • 3
  • 26
  • 37