ulfalizer / Kconfiglib

A flexible Python 2/3 Kconfig implementation and library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question: Is it possible to have no warnings for defconfig but show warnings for config fragments used on top?

simonvanderveldt opened this issue · comments

I'm trying to use Kconfiglib to general kernel configs based on a defconfig (generally the one provided by the kernel, like https://github.com/torvalds/linux/blob/f5ae2ea6347a308cfe91f53b53682ce635497d0d/arch/x86/configs/x86_64_defconfig) in combination with multiple config fragments.

For this I'd like to have warnings when fragments override config symbols from other fragments but no warnings when a fragment overrides a config symbol from the defconfig (or alternatively show them as separate messages).
I was wondering if there's some built-in way to make this possible?
From my exploration so far I couldn't really find a way, since the whole config including the warnings ends up in the Kconfig object` and there's no distinction where certain config symbols came from (ie there's no real concept of a "defconfig" vs a ".config" vs a config fragment, they are all just config files).

I guess I can do the slightly clunky workaround of merging all the fragments into a single config with warning enabled and then somehow (not sure if that's possible without writing to a file first?) merge the resulting config into the defconfig with warnings disabled?

I guess I can do the slightly clunky workaround of merging all the fragments into a single config with warning enabled and then somehow (not sure if that's possible without writing to a file first?) merge the resulting config into the defconfig with warnings disabled?

I think this should work:

  1. Load all the fragments with kconf.load_config(<fragment>, replace=False). replace=False merges configurations.

    You'll get warnings for any duplicate assignments if kconf.warn_assign_override and kconf.warn_assign_redun are True. They're True by default.

  2. Load the defconfig file with kconf.load_config(<defconfig>, replace=True). This replaces the configuration and wipes out the values from the fragments.

    replace=True is the default, so can just make it kconf.load_config(<defconfig>) too.

  3. Disable warnings for duplicate assignments with kconf.warn_assign_override = kconf.warn_assign_redun = False.

  4. Repeat step 1. to add the fragments.

  5. Write the configuration with kconf.write_config()

It requires loading the fragments twice, but configuration file loading is speedy, so it shouldn't be a big deal. The defconfig file needs to be loaded first so that fragments can override assignments in it.

The assigned value from the configuration file is in Symbol.user_value after a configuration has been loaded by the way (None if no value was assigned). Don't think it'll be needed here though.

(or alternatively show them as separate messages)

This could be implemented e.g. by turning off warn_to_stderr (see Kconfig.__init__()) and working manually with kconf.warnings, which is a list with all the warnings generated so far in it.

Thanks for the pointers! Just to check, what you're saying is effectively:

  • Load all fragments for error reporting for duplicates
  • Then start over with loading the defconfig and the fragments with errors for duplicates disabled

I was hoping to avoid the second read of the fragments (even thought like you mentioned it doesn't really matter time/performance wise), but this would obviously work :)

Would it be somehow possible to merge two Kconfig objects? That would allow me to read all the fragments once with warnings, read the defconfig without warnings, and then merge the two either with or without warnings.

Would it be somehow possible to merge two Kconfig objects? That would allow me to read all the fragments once with warnings, read the defconfig without warnings, and then merge the two either with or without warnings.

Could iterate through all the symbols in one of the Kconfig objects and assign the same user values to the symbols in the other object. Something like this:

for sym in fragment_kconf.unique_defined_syms:
    if sym.user_value is not None:
        defconfig_kconf.syms[sym.name].set_value(sym.user_value)

Might be messier in the end though. It'll be slower too, because you'll need to parse the Kconfig files twice (there's no way to clone a Kconfig object, and it might be messy to implement, because there's lots of recursion and stuff in the data structures).

Won't get any warnings for the merging step there.

Closing for now. Could still comment.