def defconfig_merge( kconf: kconfiglib.Kconfig, sources: T.List[pathlib.Path], fail_on_unknown: bool, ) -> GenerationResult: for path in sources: kconf.load_config(str(path.absolute()), replace=False) if kconf.missing_syms and fail_on_unknown: raise ValueError("Unknown symbols: {}".format(kconf.missing_syms)) stats = Stats( nb_symbols=len([ symbol for symbol in kconf.unique_defined_syms if symbol.user_value ]), files=sources, ) with tempfile.NamedTemporaryFile(mode='r') as f: kconf.write_min_config(f.name, header='') lines = f.read() return GenerationResult( stats=stats, output=lines, )
def main(): parse_args() print("Parsing Kconfig tree in {}".format(args.kconfig_root)) kconf = Kconfig(args.kconfig_root, warn_to_stderr=False) # Enable warnings for assignments to undefined symbols kconf.enable_undef_warnings() # This script uses alldefconfig as the base. Other starting states could be set # up here as well. The approach in examples/allnoconfig_simpler.py could # provide an allnoconfig starting state for example. print("Using {} as base".format(args.conf_fragments[0])) for config in args.conf_fragments[1:]: print("Merging {}".format(config)) # Create a merged configuration by loading the fragments with replace=False for config in args.conf_fragments: kconf.load_config(config, replace=False) # Write the merged configuration and the C header. This will evaluate all # symbols, which might generate additional warnings, so do it before # checking for warnings. kconf.write_config(args.dotconfig) kconf.write_autoconf(args.autoconf) # Print warnings for symbols whose actual value doesn't match the assigned # value for sym in kconf.defined_syms: # Was the symbol assigned to? Choice symbols are checked separately. if sym.user_value is not None and not sym.choice: verify_assigned_sym_value(sym) # Print warnings for choices whose actual selection doesn't match the user # selection for choice in kconf.choices: if choice.user_selection: verify_assigned_choice_value(choice) # We could roll this into the loop below, but it's nice to always print all # warnings, even if one of them turns out to be fatal for warning in kconf.warnings: if enabled(warning): print(warning, file=sys.stderr) # Turn all warnings except for explicity whitelisted ones into errors. In # particular, this will turn assignments to undefined Kconfig variables # into errors. # # A warning is generated by this script whenever a symbol gets a different # value than the one it was assigned. Keep that one as just a warning for # now as well. for warning in kconf.warnings: if fatal(warning): sys.exit("Error: Aborting due to non-whitelisted Kconfig " "warning '{}'.\nNote: If this warning doesn't point " "to an actual problem, you can add it to the " "whitelist at the top of {}.".format( warning, sys.argv[0]))
def main(): parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description=__doc__) parser.add_argument("--show-help", "-l", action="store_true", help="Show any help texts as well") parser.add_argument("kconfig", metavar="KCONFIG", nargs="?", default="Kconfig", help="Top-level Kconfig file (default: Kconfig)") args = parser.parse_args() kconf = Kconfig(args.kconfig, suppress_traceback=True) # Make it possible to filter this message out print(kconf.load_config(), file=sys.stderr) for sym in kconf.unique_defined_syms: # Only show symbols that can be toggled. Choice symbols are a special # case in that sym.assignable will be (2,) (length 1) for visible # symbols in choices in y mode, but they can still be toggled by # selecting some other symbol. if sym.user_value is None and \ (len(sym.assignable) > 1 or (sym.visibility and (sym.orig_type in (INT, HEX, STRING) or sym.choice))): # Don't reuse the 'config_string' format for bool/tristate symbols, # to show n-valued symbols as 'CONFIG_FOO=n' instead of # '# CONFIG_FOO is not set'. This matches the C tools. if sym.orig_type in (BOOL, TRISTATE): s = "{}{}={}\n".format(kconf.config_prefix, sym.name, TRI_TO_STR[sym.tri_value]) else: s = sym.config_string print(s, end="") if args.show_help: for node in sym.nodes: if node.help is not None: # Indent by two spaces. textwrap.indent() is not # available in Python 2 (it's 3.3+). print("\n".join(" " + line for line in node.help.split("\n"))) break
def run(self, args): if not newt_available: logging.error( 'Menu plugin requires \'python3-newt\' distribution package.') sys.exit(1) ctx = create_global_context(args) self.kconf = Kconfig(args.kconfig, warn_to_stderr=False) config_filename = os.path.join(ctx.kas_work_dir, CONFIG_YAML_FILE) self.load_config(config_filename) self.dump_kconf_warnings() menu = Menuconfig(self.kconf) action = menu.show() if action == 'exit': return self.save_config(config_filename) self.dump_kconf_warnings() if action == 'build': logging.debug('Starting build') build_args = Args() build_args.config = None build_args.target = None build_args.task = None build_args.extra_bitbake_args = [] build_args.skip = None Build().run(build_args)
def hi_mconfig(): kconfig = os.path.join("tools", "menuconfig", "Kconfig") display_style = "default selection=fg:white,bg:red" target_conf = os.path.join("build", "config", "usr_config.mk") header = "# Generated by HiSilicon menuconfig tool" mconf_set_env(display_style, target_conf, header) kconf = Kconfig(filename=kconfig) menuconfig(kconf)
def main(): parser = argparse.ArgumentParser(description="Merge .config files.") parser.add_argument("--outfile", required=True) parser.add_argument("config_files", nargs="+") args = parser.parse_args() config = Kconfig("Kconfig") config.warn_assign_override = False config.warn_assign_redun = False for config_file in args.config_files: config.load_config(config_file, replace=False) config.write_config(args.outfile)
def all_arch_srcarch_kconfigs(): """ Generates Kconfig instances for all the architectures in the kernel """ for arch, srcarch in all_arch_srcarch_pairs(): print(" Processing " + arch) os.environ["ARCH"] = arch os.environ["SRCARCH"] = srcarch # um (User Mode Linux) uses a different base Kconfig file yield Kconfig("Kconfig" if arch != "um" else "arch/x86/um/Kconfig", warn=False)
def main(kconfig_file, config1, config2): kconf = Kconfig(kconfig_file, suppress_traceback=True) # Enable warnings for assignments to undefined symbols kconf.warn_assign_undef = False # (This script uses alldefconfig as the base. Other starting states could be # set up here as well. The approach in examples/allnoconfig_simpler.py could # provide an allnoconfig starting state for example.) # Disable warnings generated for multiple assignments to the same symbol within # a (set of) configuration files. Assigning a symbol multiple times might be # done intentionally when merging configuration files. kconf.warn_assign_override = False kconf.warn_assign_redun = False # Create a merged configuration by loading the fragments with replace=False. # load_config() and write_config() returns a message to print. print(kconf.load_config(config1, replace=False)) print(kconf.load_config(config2, replace=False)) # Modification for PX4 unset all symbols (INT,HEX etc) from 2nd config f = open(config2, 'r') unset_match = re.compile(r"# {}([^ ]+) is not set".format("CONFIG_"), re.ASCII).match for line in f: match = unset_match(line) #pprint.pprint(match) if match is not None: sym_name = match.group(1) kconf.syms[sym_name].unset_value() f.close() # Print warnings for symbols whose actual value doesn't match the assigned # value for sym in kconf.defined_syms: # Was the symbol assigned to? if sym.user_value is not None: # Tristate values are represented as 0, 1, 2. Having them as # "n", "m", "y" is more convenient here, so convert. if sym.type in (BOOL, TRISTATE): user_value = TRI_TO_STR[sym.user_value] else: user_value = sym.user_value if user_value != sym.str_value: print("warning: {} was assigned the value '{}' but got the " "value '{}' -- check dependencies".format( sym.name_and_loc, user_value, sym.str_value), file=sys.stderr) return kconf
def defconfig_split( kconf: kconfiglib.Kconfig, fail_on_unknown: bool, categories: T.List[T.Text], destdir: pathlib.Path, source: T.TextIO, prefix: T.Text, ) -> Stats: with tempfile.TemporaryDirectory() as d: config_path = os.path.join(d, '.config') defconfig_path = os.path.join(d, 'defconfig') with open(config_path, 'w', encoding='utf-8') as f: for line in source: f.write(line) kconf.load_config(config_path) if fail_on_unknown and kconf.missing_syms: raise ValueError("Unknown symbols: {}".format(kconf.missing_syms)) kconf.write_min_config(defconfig_path) kconf.load_config(defconfig_path) symbols_by_category: T.Dict[T.Text, T.List[kconfiglib.Symbol]] = { cat: [] for cat in categories } symbols_by_category[''] = [] for symbol in kconf.unique_defined_syms: if symbol.user_value is not None: category = max(cat for cat in symbols_by_category if symbol.nodes[0].filename.startswith(cat)) symbols_by_category[category].append(symbol) stats = Stats( nb_symbols=sum( len(symbols) for symbols in symbols_by_category.values()), files=[], ) for category, symbols in sorted(symbols_by_category.items()): if category: path = destdir / '{}.{}'.format(prefix, category.replace('/', '_')) else: path = destdir / prefix stats.files.append(path) with path.open('w', encoding='utf-8') as output: for symbol in symbols: output.write(symbol.config_string) return stats
def main(): kconf = Kconfig(KCONFIG_FILE, warn=False) kconf.load_config(DEFCONFIG) if sys.argv[1] == "GDB_INTERNAL": try: for opt in open("../config_append", "r").readlines(): enable_opt(kconf, opt) except: pass set_debug(kconf) disable_opt(kconf, 'SMP') # enable_opt(kconf, 'BLK_DEV_INITRD') # enable_opt(kconf, 'BLK_DEV_RAM') kconf.write_config(CONFIG_FILE)
def __init__(self, kconfig_file="Kconfig", config_file=".config", systemLogger=None): """[summary] Parameters ---------- kconfig_file : string (default: "Kconfig") The Kconfig configuration file config_file : string (default: ".config") The save file which will be used for loading and saving the settings systemLogger (default: None) A system logger object. If None then print statements are used for logging. """ global log if systemLogger: log = systemLogger # Load Kconfig configuration files self.kconfig = Kconfig(kconfig_file) setKConfig(self.kconfig) if os.path.isfile(config_file): log.info(self.kconfig.load_config(config_file)) elif os.path.isfile(".config"): log.info(self.kconfig.load_config(".config")) self.tree = KConfigTree(self.kconfig) self.tree.addTreeSelectionListener(self.treeSelectionChanged) jTreeSP = JScrollPane(self.tree) self.jta = JTextArea() self.jta.setEditable(False) jTextSP = JScrollPane(self.jta) toolPanel = JPanel() toolPanel.setLayout(BoxLayout(toolPanel, BoxLayout.X_AXIS)) toolPanel.setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0)) toolPanel.add(JLabel("Search: ")) jSearchPanel = JPanel() jSearchPanel.setLayout(BoxLayout(jSearchPanel, BoxLayout.X_AXIS)) self.jSearchField = JTextField() jSearchPanel.setBackground(self.jSearchField.getBackground()) jSearchPanel.setBorder(self.jSearchField.getBorder()) self.jSearchField.setBorder(None) self.jSearchField.getDocument().addDocumentListener( SearchListener(self.tree)) jSearchPanel.add(self.jSearchField) clearSearchButton = JButton(u'\u00d7', actionPerformed=self.clearSearch) d = clearSearchButton.getPreferredSize() clearSearchButton.setPreferredSize(Dimension(d.height, d.height)) clearSearchButton.setBackground(self.jSearchField.getBackground()) clearSearchButton.setBorder(None) clearSearchButton.setOpaque(False) clearSearchButton.setContentAreaFilled(False) clearSearchButton.setFocusPainted(False) jSearchPanel.add(clearSearchButton) toolPanel.add(jSearchPanel) self.showAllCheckBox = JCheckBox("Show all", actionPerformed=self.OnShowAllCheck) toolPanel.add(self.showAllCheckBox) splitPane = JSplitPane(JSplitPane.VERTICAL_SPLIT, jTreeSP, jTextSP) splitPane.setOneTouchExpandable(True) splitPane.setDividerLocation(300) treePanel = JPanel(BorderLayout()) treePanel.add(toolPanel, BorderLayout.NORTH) treePanel.add(splitPane, BorderLayout.CENTER) loadSavePanel = JPanel() loadSavePanel.setLayout(BoxLayout(loadSavePanel, BoxLayout.X_AXIS)) loadSavePanel.add( JButton("Load", actionPerformed=self.loadConfigDialog)) loadSavePanel.add( JButton("Save as", actionPerformed=self.writeConfigDialog)) self.rootPanel = JPanel() self.rootPanel.setLayout(BorderLayout()) self.rootPanel.add(loadSavePanel, BorderLayout.PAGE_START) self.rootPanel.add(treePanel, BorderLayout.CENTER)
class MPConfig(TreeSelectionListener): """The MPConfig component initializes the KConfig library with the requested configuration, and buildst the GUI, consisting of a "Load" and a "Save as" buttons, a search field, "show all" checkbox, tree view and information text view.""" def __init__(self, kconfig_file="Kconfig", config_file=".config", systemLogger=None): """[summary] Parameters ---------- kconfig_file : string (default: "Kconfig") The Kconfig configuration file config_file : string (default: ".config") The save file which will be used for loading and saving the settings systemLogger (default: None) A system logger object. If None then print statements are used for logging. """ global log if systemLogger: log = systemLogger # Load Kconfig configuration files self.kconfig = Kconfig(kconfig_file) setKConfig(self.kconfig) if os.path.isfile(config_file): log.info(self.kconfig.load_config(config_file)) elif os.path.isfile(".config"): log.info(self.kconfig.load_config(".config")) self.tree = KConfigTree(self.kconfig) self.tree.addTreeSelectionListener(self.treeSelectionChanged) jTreeSP = JScrollPane(self.tree) self.jta = JTextArea() self.jta.setEditable(False) jTextSP = JScrollPane(self.jta) toolPanel = JPanel() toolPanel.setLayout(BoxLayout(toolPanel, BoxLayout.X_AXIS)) toolPanel.setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0)) toolPanel.add(JLabel("Search: ")) jSearchPanel = JPanel() jSearchPanel.setLayout(BoxLayout(jSearchPanel, BoxLayout.X_AXIS)) self.jSearchField = JTextField() jSearchPanel.setBackground(self.jSearchField.getBackground()) jSearchPanel.setBorder(self.jSearchField.getBorder()) self.jSearchField.setBorder(None) self.jSearchField.getDocument().addDocumentListener( SearchListener(self.tree)) jSearchPanel.add(self.jSearchField) clearSearchButton = JButton(u'\u00d7', actionPerformed=self.clearSearch) d = clearSearchButton.getPreferredSize() clearSearchButton.setPreferredSize(Dimension(d.height, d.height)) clearSearchButton.setBackground(self.jSearchField.getBackground()) clearSearchButton.setBorder(None) clearSearchButton.setOpaque(False) clearSearchButton.setContentAreaFilled(False) clearSearchButton.setFocusPainted(False) jSearchPanel.add(clearSearchButton) toolPanel.add(jSearchPanel) self.showAllCheckBox = JCheckBox("Show all", actionPerformed=self.OnShowAllCheck) toolPanel.add(self.showAllCheckBox) splitPane = JSplitPane(JSplitPane.VERTICAL_SPLIT, jTreeSP, jTextSP) splitPane.setOneTouchExpandable(True) splitPane.setDividerLocation(300) treePanel = JPanel(BorderLayout()) treePanel.add(toolPanel, BorderLayout.NORTH) treePanel.add(splitPane, BorderLayout.CENTER) loadSavePanel = JPanel() loadSavePanel.setLayout(BoxLayout(loadSavePanel, BoxLayout.X_AXIS)) loadSavePanel.add( JButton("Load", actionPerformed=self.loadConfigDialog)) loadSavePanel.add( JButton("Save as", actionPerformed=self.writeConfigDialog)) self.rootPanel = JPanel() self.rootPanel.setLayout(BorderLayout()) self.rootPanel.add(loadSavePanel, BorderLayout.PAGE_START) self.rootPanel.add(treePanel, BorderLayout.CENTER) def clearSearch(self, event): self.jSearchField.setText("") def OnShowAllCheck(self, event): self.tree.setShowAll(self.showAllCheckBox.isSelected()) self.tree.doSearch(self.jSearchField.getText() ) # Must repeat the search if one is active def treeSelectionChanged(self, event): """When the user selects a new node in the tree, show info about the selected node in the info text area below the tree.""" path = event.getNewLeadSelectionPath() if path: comp = path.getLastPathComponent() if isinstance(comp, DefaultMutableTreeNode): nodeData = comp.getUserObject() if isinstance(nodeData, TreeNodeData): self.jta.setText(getNodeInfoString(nodeData.knode)) self.jta.setCaretPosition(0) def getPane(self): """Return the panel containing all the other components that is set up in __init__().""" return self.rootPanel def writeConfig(self, fileName): """Write the current configuration to the file specified.""" self.kconfig.write_config(fileName) # Save full configuration #self.kconfig.write_min_config(fileName) # Save minimal configuration def loadConfig(self, fileName): """Load configuration settings from the file specified.""" if os.path.isfile(fileName): log.info(self.kconfig.load_config(fileName)) self.tree.createKconfShadowModel(self.kconfig) self.tree.updateTree() def writeConfigDialog(self, e): """Open a file dialog to save configuration""" fileChooser = JFileChooser(os.getcwd()) retval = fileChooser.showSaveDialog(None) if retval == JFileChooser.APPROVE_OPTION: f = fileChooser.getSelectedFile() self.writeConfig(f.getPath()) def loadConfigDialog(self, e): """Open a file dialog to select configuration to load""" fileChooser = JFileChooser(os.getcwd()) retval = fileChooser.showOpenDialog(None) if retval == JFileChooser.APPROVE_OPTION: f = fileChooser.getSelectedFile() log.info("Selected file: " + f.getPath()) self.loadConfig(f.getPath())
# warning: QAZ (defined at Kconfig:10) was assigned the value "y" but got the value "n" -- check dependencies # $ cat merged # Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) # # CONFIG_FOO is not set # CONFIG_BAR=y # CONFIG_BAZ="baz string" import sys from kconfiglib import Kconfig, BOOL, TRISTATE, TRI_TO_STR if len(sys.argv) < 4: sys.exit("usage: merge_config.py Kconfig merged_config config1 [config2 ...]") kconf = Kconfig(sys.argv[1]) # Enable warnings for assignments to undefined symbols kconf.enable_undef_warnings() # (This script uses alldefconfig as the base. Other starting states could be # set up here as well. The approach in examples/allnoconfig_simpler.py could # provide an allnoconfig starting state for example.) # Disable warnings generated for multiple assignments to the same symbol within # a (set of) configuration files. Assigning a symbol multiple times might be # done intentionally when merging configuration files. kconf.disable_override_warnings() kconf.disable_redun_warnings() # Create a merged configuration by loading the fragments with replace=False
def mconfig(argv): kconfig = os.path.join("tools", "menuconfig", "extra", "Configs", "Config.in") display_style = "default selection=fg:white,bg:blue" target_conf = os.path.join(".config") header = "# Generated by Huawei LiteOS Kconfig Tool" mconf_set_env(display_style, target_conf, header) kconf = Kconfig(filename=kconfig) if len(argv) == 2 and argv[1] == 'savemenuconfig': kconf.load_config() print(kconf.write_config()) # savemenuconfig elif len(argv) == 2 and argv[1] == 'defconfig': kconf.load_allconfig("alldef.config") print(kconf.write_config()) # defconfig elif len(argv) == 2 and argv[1] == 'allyesconfig': kconf.warn = False for sym in kconf.unique_defined_syms: sym.set_value(1 if sym.choice else 2) for choice in kconf.unique_choices: choice.set_value(2) kconf.warn = True kconf.load_allconfig("allyes.config") print(kconf.write_config()) # allyesconfig elif len(argv) == 2 and argv[1] == 'allnoconfig': kconf.warn = False for sym in kconf.unique_defined_syms: sym.set_value(2 if sym.is_allnoconfig_y else 0) kconf.warn = True kconf.load_allconfig("allno.config") print(kconf.write_config()) # allnoconfig else: menuconfig(kconf) # menuconfig kconf.write_autoconf()
# # location: init/Kconfig:403 # # ... import re import sys from kconfiglib import Kconfig, Symbol, Choice, MENU, COMMENT if len(sys.argv) < 3: sys.exit("Pass the regex with SCRIPT_ARG=<regex>") search = re.compile(sys.argv[2], re.IGNORECASE).search for node in Kconfig(sys.argv[1]).node_iter(): match = False if isinstance(node.item, (Symbol, Choice)) and \ node.help is not None and search(node.help): print(node.item) match = True elif node.item == MENU and search(node.prompt[0]): print('menu "{}"'.format(node.prompt[0])) match = True elif node.item == COMMENT and search(node.prompt[0]): print('comment "{}"'.format(node.prompt[0])) match = True
# set_value() doesn't do it automatically. if sc.type == HEX and not val.startswith(("0x", "0X")): val = "0x" + val # Let Kconfiglib itself print a warning here if the value is invalid. We # could also disable warnings temporarily with # kconf.disable_warnings() / kconf.enable_warnings() and print our own # warning. return sc.set_value(val) if __name__ == "__main__": if len(sys.argv) != 2: sys.exit("usage: menuconfig.py <Kconfig file>") # Load Kconfig configuration files kconf = Kconfig(sys.argv[1]) # Print the initial configuration tree print_menuconfig(kconf) while True: try: cmd = input('Enter a symbol/choice name, "load_config", or "write_config" (or press CTRL+D to exit): ') \ .strip() except EOFError: print("") break if cmd == "load_config": config_filename = input(".config file to load: ")
# $ cat merged # Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) # # CONFIG_FOO is not set # CONFIG_BAR=y # CONFIG_BAZ="baz string" from __future__ import print_function import sys from kconfiglib import Kconfig, BOOL, TRISTATE, TRI_TO_STR if len(sys.argv) < 4: sys.exit("usage: merge_config.py Kconfig merged_config config1 [config2 ...]") kconf = Kconfig(sys.argv[1]) # Enable warnings for assignments to undefined symbols kconf.warn_assign_undef = True # (This script uses alldefconfig as the base. Other starting states could be # set up here as well. The approach in examples/allnoconfig_simpler.py could # provide an allnoconfig starting state for example.) # Disable warnings generated for multiple assignments to the same symbol within # a (set of) configuration files. Assigning a symbol multiple times might be # done intentionally when merging configuration files. kconf.warn_assign_override = False kconf.warn_assign_redun = False # Create a merged configuration by loading the fragments with replace=False.
if sc.type == HEX and not val.startswith(("0x", "0X")): val = "0x" + val # Let Kconfiglib itself print a warning here if the value is invalid. We # could also disable warnings temporarily with # kconf.disable_warnings() / kconf.enable_warnings() and print our own # warning. return sc.set_value(val) if __name__ == "__main__": if len(sys.argv) != 2: sys.exit("usage: menuconfig.py <Kconfig file>") # Load Kconfig configuration files kconf = Kconfig(sys.argv[1]) # Print the initial configuration tree print_menuconfig(kconf) while True: try: cmd = input('Enter a symbol/choice name, "load_config", or ' '"write_config" (or press CTRL+D to exit): ').strip() except EOFError: print("") break if cmd == "load_config": config_filename = input(".config file to load: ")
#!/usr/bin/env python3 # Modified from: https://github.com/ulfalizer/Kconfiglib/blob/master/examples/merge_config.py from kconfiglib import Kconfig, Symbol, BOOL, STRING, TRISTATE, TRI_TO_STR import sys if len(sys.argv) < 5: print('usage: {} Kconfig dotconfig autoconf conf1 [conf2 ...]'.format( sys.argv[0])) sys.exit(1) print("Parsing Kconfig tree in {}".format(sys.argv[1])) kconf = Kconfig(sys.argv[1]) # Enable warnings for assignments to undefined symbols kconf.enable_undef_warnings() # (This script uses alldefconfig as the base. Other starting states could be # set up here as well. The approach in examples/allnoconfig_simpler.py could # provide an allnoconfig starting state for example.) print("Using {} as base".format(sys.argv[4])) for config in sys.argv[5:]: print("Merging {}".format(config)) # Create a merged configuration by loading the fragments with replace=False for config in sys.argv[4:]: kconf.load_config(config, replace=False) # Write the merged configuration kconf.write_config(sys.argv[2]) # Output autoconf
def main(): args = parse_args() print("Parsing Kconfig tree in " + args.kconfig_root) kconf = Kconfig(args.kconfig_root, warn_to_stderr=False) # Warn for assignments to undefined symbols kconf.warn_assign_undef = True # prj.conf may override settings from the board configuration, so disable # warnings about symbols being assigned more than once kconf.warn_assign_override = False kconf.warn_assign_redun = False print(kconf.load_config(args.conf_fragments[0])) for config in args.conf_fragments[1:]: # replace=False creates a merged configuration print(kconf.load_config(config, replace=False)) # Print warnings for symbols whose actual value doesn't match the assigned # value for sym in kconf.unique_defined_syms: # Was the symbol assigned to? Choice symbols are checked separately. if sym.user_value is not None and not sym.choice: verify_assigned_sym_value(sym) # Print warnings for choices whose actual selection doesn't match the user # selection for choice in kconf.unique_choices: if choice.user_selection: verify_assigned_choice_value(choice) # Hack: Force all symbols to be evaluated, to catch warnings generated # during evaluation. Wait till the end to write the actual output files, so # that we don't generate any output if there are warnings-turned-errors. # # Kconfiglib caches calculated symbol values internally, so this is still # fast. kconf.write_config(os.devnull) # Print warnings ourselves so that we can put a blank line between them for # readability. We could roll this into the loop below, but it's nice to # always print all warnings, even if one of them turns out to be fatal. for warning in kconf.warnings: print("\n" + warning, file=sys.stderr) # Turn all warnings except for explicitly whitelisted ones into errors. In # particular, this will turn assignments to undefined Kconfig variables # into errors. # # A warning is generated by this script whenever a symbol gets a different # value than the one it was assigned. Keep that one as just a warning for # now as well. for warning in kconf.warnings: if fatal(warning): sys.exit("\n" + textwrap.fill( "Error: Aborting due to non-whitelisted Kconfig " "warning '{}'.\nNote: If this warning doesn't point " "to an actual problem, you can add it to the " "whitelist at the top of {}.".format(warning, sys.argv[0]), 100) + "\n") # Write the merged configuration and the C header print(kconf.write_config(args.dotconfig)) kconf.write_autoconf(args.autoconf) # Write the list of processed Kconfig sources to a file write_kconfig_filenames(kconf.kconfig_filenames, kconf.srctree, args.sources)
def main(): parse_args() print("Parsing Kconfig tree in {}".format(args.kconfig_root)) kconf = Kconfig(args.kconfig_root, warn_to_stderr=False) # Enable warnings for assignments to undefined symbols kconf.enable_undef_warnings() for i, config in enumerate(args.conf_fragments): print( ("Loading {} as base" if i == 0 else "Merging {}").format(config)) # replace=False creates a merged configuration kconf.load_config(config, replace=False) # Print warnings for symbols whose actual value doesn't match the assigned # value for sym in kconf.unique_defined_syms: # Was the symbol assigned to? Choice symbols are checked separately. if sym.user_value is not None and not sym.choice: verify_assigned_sym_value(sym) # Print warnings for choices whose actual selection doesn't match the user # selection for choice in kconf.unique_choices: if choice.user_selection: verify_assigned_choice_value(choice) # Hack: Force all symbols to be evaluated, to catch warnings generated # during evaluation. Wait till the end to write the actual output files, so # that we don't generate any output if there are warnings-turned-errors. # # Kconfiglib caches calculated symbol values internally, so this is still # fast. kconf.write_config(os.devnull) # We could roll this into the loop below, but it's nice to always print all # warnings, even if one of them turns out to be fatal for warning in kconf.warnings: if enabled(warning): print("\n" + warning, file=sys.stderr) # Turn all warnings except for explicity whitelisted ones into errors. In # particular, this will turn assignments to undefined Kconfig variables # into errors. # # A warning is generated by this script whenever a symbol gets a different # value than the one it was assigned. Keep that one as just a warning for # now as well. for warning in kconf.warnings: if fatal(warning): sys.exit("\n" + textwrap.fill( "Error: Aborting due to non-whitelisted Kconfig " "warning '{}'.\nNote: If this warning doesn't point " "to an actual problem, you can add it to the " "whitelist at the top of {}.".format(warning, sys.argv[0]), 100) + "\n") # Write the merged configuration and the C header kconf.write_config(args.dotconfig) kconf.write_autoconf(args.autoconf)
if (not sym.is_allnoconfig_y and sym.assignable and sym.assignable[0] < sym.tri_value): # Yup, lower it sym.set_value(sym.assignable[0]) changed = True # Recursively lower children if node.list: do_allnoconfig(node.list) node = node.next # Parse the Kconfig files kconf = Kconfig(sys.argv[1]) # Do an initial pass to set 'option allnoconfig_y' symbols to y for sym in kconf.unique_defined_syms: if sym.is_allnoconfig_y: sym.set_value(2) while True: # Changing later symbols in the configuration can sometimes allow earlier # symbols to be lowered, e.g. if a later symbol 'select's an earlier # symbol. To handle such situations, we do additional passes over the tree # until we're no longer able to change the value of any symbol in a pass. changed = False do_allnoconfig(kconf.top_node)
# warning: QAZ (defined at Kconfig:10) was assigned the value "y" but got the value "n" -- check dependencies # $ cat merged # Generated by Kconfiglib (https://github.com/ulfalizer/Kconfiglib) # # CONFIG_FOO is not set # CONFIG_BAR=y # CONFIG_BAZ="baz string" import sys from kconfiglib import Kconfig, Symbol, BOOL, TRISTATE, TRI_TO_STR if len(sys.argv) < 4: sys.exit( "usage: merge_config.py Kconfig merged_config config1 [config2 ...]") kconf = Kconfig(sys.argv[1]) # Enable warnings for assignments to undefined symbols kconf.enable_undef_warnings() # (This script uses alldefconfig as the base. Other starting states could be # set up here as well. The approach in examples/allnoconfig_simpler.py could # provide an allnoconfig starting state for example.) # Disable warnings generated for multiple assignments to the same symbol within # a (set of) configuration files. Assigning a symbol multiple times might be # done intentionally when merging configuration files. kconf.disable_override_warnings() kconf.disable_redun_warnings() # Create a merged configuration by loading the fragments with replace=False
# This is a simpler version of allnoconfig.py, corresponding to how the C # implementation does it. Verified by the test suite to produce identical # output to 'make allnoconfig' for all ARCHes. # # Usage: # # $ make [ARCH=<arch>] scriptconfig SCRIPT=Kconfiglib/examples/allnoconfig_simpler.py from kconfiglib import Kconfig, BOOL, TRISTATE import sys kconf = Kconfig(sys.argv[1]) # Avoid warnings printed by Kconfiglib when assigning a value to a symbol that # has no prompt. Such assignments never have an effect. kconf.disable_warnings() for sym in kconf.defined_syms: if sym.type in (BOOL, TRISTATE): sym.set_value(2 if sym.is_allnoconfig_y else 0) kconf.write_config(".config")
def main(): args = parse_args() print("Parsing " + args.kconfig_file) kconf = Kconfig(args.kconfig_file, warn_to_stderr=False, suppress_traceback=True) if args.handwritten_input_configs: # Warn for assignments to undefined symbols, but only for handwritten # fragments, to avoid warnings-turned-errors when using an old # configuration file together with updated Kconfig files kconf.warn_assign_undef = True # prj.conf may override settings from the board configuration, so # disable warnings about symbols being assigned more than once kconf.warn_assign_override = False kconf.warn_assign_redun = False # Load configuration files print(kconf.load_config(args.configs_in[0])) for config in args.configs_in[1:]: # replace=False creates a merged configuration print(kconf.load_config(config, replace=False)) if args.handwritten_input_configs: # Check that there are no assignments to promptless symbols, which # have no effect. # # This only makes sense when loading handwritten fragments and not when # loading zephyr/.config, because zephyr/.config is configuration # output and also assigns promptless symbols. check_no_promptless_assign(kconf) # Print warnings for symbols that didn't get the assigned value. Only # do this for handwritten input too, to avoid likely unhelpful warnings # when using an old configuration and updating Kconfig files. check_assigned_sym_values(kconf) check_assigned_choice_values(kconf) # Hack: Force all symbols to be evaluated, to catch warnings generated # during evaluation. Wait till the end to write the actual output files, so # that we don't generate any output if there are warnings-turned-errors. # # Kconfiglib caches calculated symbol values internally, so this is still # fast. kconf.write_config(os.devnull) if kconf.warnings: # Put a blank line between warnings to make them easier to read for warning in kconf.warnings: print("\n" + warning, file=sys.stderr) # Turn all warnings into errors, so that e.g. assignments to undefined # Kconfig symbols become errors. # # A warning is generated by this script whenever a symbol gets a # different value than the one it was assigned. Keep that one as just a # warning for now. err("Aborting due to Kconfig warnings") # Write the merged configuration and the C header print(kconf.write_config(args.config_out)) kconf.write_autoconf(args.header_out) # Write the list of parsed Kconfig files to a file write_kconfig_filenames(kconf, args.kconfig_list_out)
sym.assignable and sym.assignable[0] < sym.tri_value): # Yup, lower it sym.set_value(sym.assignable[0]) changed = True # Recursively lower children if node.list: do_allnoconfig(node.list) node = node.next # Parse the Kconfig files kconf = Kconfig(sys.argv[1]) # Do an initial pass to set 'option allnoconfig_y' symbols to y for sym in kconf.unique_defined_syms: if sym.is_allnoconfig_y: sym.set_value(2) while True: # Changing later symbols in the configuration can sometimes allow earlier # symbols to be lowered, e.g. if a later symbol 'select's an earlier # symbol. To handle such situations, we do additional passes over the tree # until we're no longer able to change the value of any symbol in a pass. changed = False do_allnoconfig(kconf.top_node)
from kconfiglib import Kconfig, Symbol, Choice, MENU, COMMENT import sys def indent_print(s, indent): print(" " * indent + s) def print_items(node, indent): while node: if isinstance(node.item, Symbol): indent_print("config " + node.item.name, indent) elif isinstance(node.item, Choice): indent_print("choice", indent) elif node.item == MENU: indent_print('menu "{}"'.format(node.prompt[0]), indent) elif node.item == COMMENT: indent_print('comment "{}"'.format(node.prompt[0]), indent) if node.list: print_items(node.list, indent + 2) node = node.next kconf = Kconfig(sys.argv[1]) print_items(kconf.top_node, 0)
def main(): parse_args() print("Parsing Kconfig tree in {}".format(args.kconfig_root)) kconf = Kconfig(args.kconfig_root) # Enable warnings for assignments to undefined symbols kconf.enable_undef_warnings() # This script uses alldefconfig as the base. Other starting states could be set # up here as well. The approach in examples/allnoconfig_simpler.py could # provide an allnoconfig starting state for example. print("Using {} as base".format(args.conf_fragments[0])) for config in args.conf_fragments[1:]: print("Merging {}".format(config)) # Create a merged configuration by loading the fragments with replace=False for config in args.conf_fragments: kconf.load_config(config, replace=False) # Print warnings for symbols whose actual value doesn't match the assigned # value def name_and_loc(sym): # Helper for printing symbol names and Kconfig file location(s) in warnings if not sym.nodes: return sym.name + " (undefined)" return "{} (defined at {})".format( sym.name, ", ".join("{}:{}".format(node.filename, node.linenr) for node in sym.nodes)) for sym in kconf.defined_syms: # Was the symbol assigned to? if sym.user_value is not None: # Tristate values are represented as 0, 1, 2. Having them as # "n", "m", "y" is more convenient here, so convert. if sym.type in (BOOL, TRISTATE): user_value = TRI_TO_STR[sym.user_value] else: user_value = sym.user_value if user_value != sym.str_value: print('warning: {} was assigned the value "{}" but got the ' 'value "{}" -- check dependencies'.format( name_and_loc(sym), user_value, sym.str_value ), file=sys.stderr) # Turn the warning for malformed .config lines into an error for warning in kconf.warnings: if "ignoring malformed line" in warning: print("Aborting due to malformed configuration settings", file=sys.stderr) sys.exit(1) # Write the merged configuration kconf.write_config(args.dotconfig) # Write the C header kconf.write_autoconf(args.autoconf)
if not conf_changed: break def do_oldconfig_rec(node): while node: do_oldconfig_for_node(node) if node.list: do_oldconfig_rec(node.list) node = node.next if __name__ == "__main__": if len(sys.argv) != 2: eprint("error: pass name of base Kconfig file as argument") sys.exit(1) if not os.path.exists(".config"): eprint("error: no existing .config") sys.exit(1) kconf = Kconfig(sys.argv[1]) kconf.load_config(".config") do_oldconfig(kconf) kconf.write_config(".config") print("Configuration written to .config")
#!/usr/bin/env python3 """ Script to generate a JSON config with all build targets (for CI) """ import argparse import os import sys import json import re from kconfiglib import Kconfig kconf = Kconfig() # Supress warning output kconf.warn_assign_undef = False kconf.warn_assign_override = False kconf.warn_assign_redun = False source_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..') parser = argparse.ArgumentParser(description='Generate build targets') parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', help='Verbose Output') parser.add_argument('-p', '--pretty', dest='pretty', action='store_true', help='Pretty output instead of a single line')
# set_value() doesn't do it automatically. if sc.type == HEX and not val.startswith(("0x", "0X")): val = "0x" + val # Let Kconfiglib itself print a warning here if the value is invalid. We # could also disable warnings temporarily with 'kconf.warn = False' and # print our own warning. return sc.set_value(val) if __name__ == "__main__": if len(sys.argv) != 2: sys.exit("usage: menuconfig.py <Kconfig file>") # Load Kconfig configuration files kconf = Kconfig(sys.argv[1]) # Print the initial configuration tree print_menuconfig(kconf) while True: try: cmd = input('Enter a symbol/choice name, "load_config", or ' '"write_config" (or press CTRL+D to exit): ').strip() except EOFError: print("") break if cmd == "load_config": config_filename = input(".config file to load: ") try:
def main(): args = parse_args() print("Parsing " + args.kconfig_file) kconf = Kconfig(args.kconfig_file, warn_to_stderr=False, suppress_traceback=True) if args.handwritten_input_configs: # Warn for assignments to undefined symbols, but only for handwritten # fragments, to avoid warnings-turned-errors when using an old # configuration file together with updated Kconfig files kconf.warn_assign_undef = True # prj.conf may override settings from the board configuration, so # disable warnings about symbols being assigned more than once kconf.warn_assign_override = False kconf.warn_assign_redun = False # Load configuration files print(kconf.load_config(args.configs_in[0])) for config in args.configs_in[1:]: # replace=False creates a merged configuration print(kconf.load_config(config, replace=False)) if args.handwritten_input_configs: # Check that there are no assignments to promptless symbols, which # have no effect. # # This only makes sense when loading handwritten fragments and not when # loading zephyr/.config, because zephyr/.config is configuration # output and also assigns promptless symbols. check_no_promptless_assign(kconf) # Print warnings for symbols that didn't get the assigned value. Only # do this for handwritten input too, to avoid likely unhelpful warnings # when using an old configuration and updating Kconfig files. check_assigned_sym_values(kconf) check_assigned_choice_values(kconf) # Hack: Force all symbols to be evaluated, to catch warnings generated # during evaluation. Wait till the end to write the actual output files, so # that we don't generate any output if there are warnings-turned-errors. # # Kconfiglib caches calculated symbol values internally, so this is still # fast. kconf.write_config(os.devnull) # Print warnings ourselves so that we can put a blank line between them for # readability. We could roll this into the loop below, but it's nice to # always print all warnings, even if one of them turns out to be fatal. for warning in kconf.warnings: print("\n" + warning, file=sys.stderr) # Turn all warnings except for explicitly whitelisted ones into errors. In # particular, this will turn assignments to undefined Kconfig variables # into errors. # # A warning is generated by this script whenever a symbol gets a different # value than the one it was assigned. Keep that one as just a warning for # now as well. for warning in kconf.warnings: if fatal(warning): err(f"""\ Aborting due to non-whitelisted Kconfig warning '{warning}'. If this warning doesn't point to an actual problem, you can add it to the whitelist at the top of {sys.argv[0]}.""") # Write the merged configuration and the C header print(kconf.write_config(args.config_out)) kconf.write_autoconf(args.header_out) # Write the list of parsed Kconfig files to a file write_kconfig_filenames(kconf, args.kconfig_list_out)