From 04bb58a69cda64083d4340c9c597a5f24ec527bd Mon Sep 17 00:00:00 2001 From: Janusz Jankowski Date: Tue, 25 Dec 2018 20:24:35 +0100 Subject: [PATCH 01/21] kconfig: add Kconfiglib Signed-off-by: Janusz Jankowski --- scripts/kconfig/alldefconfig.py | 24 + scripts/kconfig/genconfig.py | 89 + scripts/kconfig/kconfiglib.py | 6640 +++++++++++++++++++++++++++++++ scripts/kconfig/menuconfig.py | 3082 ++++++++++++++ scripts/kconfig/olddefconfig.py | 27 + 5 files changed, 9862 insertions(+) create mode 100644 scripts/kconfig/alldefconfig.py create mode 100644 scripts/kconfig/genconfig.py create mode 100644 scripts/kconfig/kconfiglib.py create mode 100644 scripts/kconfig/menuconfig.py create mode 100644 scripts/kconfig/olddefconfig.py diff --git a/scripts/kconfig/alldefconfig.py b/scripts/kconfig/alldefconfig.py new file mode 100644 index 000000000000..66759e06e21c --- /dev/null +++ b/scripts/kconfig/alldefconfig.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +# Copyright (c) 2018, Ulf Magnusson +# SPDX-License-Identifier: ISC + +# Works like 'make alldefconfig'. Verified by the test suite to generate +# identical output to 'make alldefconfig' for all ARCHes. +# +# The default output filename is '.config'. A different filename can be passed +# in the KCONFIG_CONFIG environment variable. +# +# Usage for the Linux kernel: +# +# $ make [ARCH=] scriptconfig SCRIPT=Kconfiglib/alldefconfig.py + +import kconfiglib + +def main(): + kconf = kconfiglib.standard_kconfig() + kconfiglib.load_allconfig(kconf, "alldef.config") + kconf.write_config() + +if __name__ == "__main__": + main() diff --git a/scripts/kconfig/genconfig.py b/scripts/kconfig/genconfig.py new file mode 100644 index 000000000000..a7c9e07c0235 --- /dev/null +++ b/scripts/kconfig/genconfig.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python + +# Copyright (c) 2018, Ulf Magnusson +# SPDX-License-Identifier: ISC + +# Generates a C header from the configuration, matching the format of +# include/generated/autoconf.h in the kernel. +# +# Optionally generates a directory structure with one file per symbol that can +# be used to implement incremental builds. See the docstring for +# Kconfig.sync_deps() in Kconfiglib. +# +# Usage (see argument help texts for more information): +# +# genconfig.py [-h] [--header-path HEADER_FILE] +# [--sync-deps [OUTPUT_DIR]] [--config-out CONFIG_FILE] +# [KCONFIG_FILENAME] + +import argparse + +import kconfiglib + +DESCRIPTION = """ +Generates a header file with defines from the configuration. Optionally +creates/updates a directory with incremental build information as well (see the +docstring for the Kconfig.sync_deps() function in Kconfiglib). The .config file +to generate the configuration from can be specified by setting the +KCONFIG_CONFIG environment variable. +""" + +DEFAULT_HEADER_PATH = "config.h" +DEFAULT_SYNC_DEPS_PATH = "deps/" + +def main(): + parser = argparse.ArgumentParser(description=DESCRIPTION) + + parser.add_argument( + "--header-path", + metavar="HEADER_FILE", + default=DEFAULT_HEADER_PATH, + help="Path for the generated header file (default: {})" + .format(DEFAULT_HEADER_PATH)) + + parser.add_argument( + "--sync-deps", + dest="sync_deps_path", + metavar="OUTPUT_DIR", + nargs="?", + const=DEFAULT_SYNC_DEPS_PATH, + help="Enable generation of build dependency information for " + "incremental builds, optionally specifying the output path " + "(default: {})".format(DEFAULT_SYNC_DEPS_PATH)) + + parser.add_argument( + "--config-out", + dest="config_path", + metavar="CONFIG_FILE", + help="Write the configuration to the specified filename. " + "This is useful if you include .config files in Makefiles, as " + "the generated configuration file will be a full .config file " + "even if .config is outdated. The generated configuration " + "matches what olddefconfig would produce. If you use " + "--sync-deps, you can include deps/auto.conf instead. " + "--config-out is meant for cases where incremental build " + "information isn't needed.") + + parser.add_argument( + "kconfig_filename", + metavar="KCONFIG_FILENAME", + nargs="?", + default="Kconfig", + help="Top-level Kconfig file (default: Kconfig)") + + args = parser.parse_args() + + + kconf = kconfiglib.Kconfig(args.kconfig_filename) + kconf.load_config(verbose=False) + + kconf.write_autoconf(args.header_path) + + if args.sync_deps_path is not None: + kconf.sync_deps(args.sync_deps_path) + + if args.config_path is not None: + kconf.write_config(args.config_path, save_old=False) + +if __name__ == "__main__": + main() diff --git a/scripts/kconfig/kconfiglib.py b/scripts/kconfig/kconfiglib.py new file mode 100644 index 000000000000..30b750731764 --- /dev/null +++ b/scripts/kconfig/kconfiglib.py @@ -0,0 +1,6640 @@ +# Copyright (c) 2011-2018, Ulf Magnusson +# SPDX-License-Identifier: ISC + +""" +Overview +======== + +Kconfiglib is a Python 2/3 library for scripting and extracting information +from Kconfig (https://www.kernel.org/doc/Documentation/kbuild/kconfig-language.txt) +configuration systems. + +See the homepage at https://github.com/ulfalizer/Kconfiglib for a longer +overview. + +Using Kconfiglib on the Linux kernel with the Makefile targets +============================================================== + +For the Linux kernel, a handy interface is provided by the +scripts/kconfig/Makefile patch, which can be applied with either 'git am' or +the 'patch' utility: + + $ wget -qO- https://raw.githubusercontent.com/ulfalizer/Kconfiglib/master/makefile.patch | git am + $ wget -qO- https://raw.githubusercontent.com/ulfalizer/Kconfiglib/master/makefile.patch | patch -p1 + +Warning: Not passing -p1 to patch will cause the wrong file to be patched. + +Please tell me if the patch does not apply. It should be trivial to apply +manually, as it's just a block of text that needs to be inserted near the other +*conf: targets in scripts/kconfig/Makefile. + +Look further down for a motivation for the Makefile patch and for instructions +on how you can use Kconfiglib without it. + +If you do not wish to install Kconfiglib via pip, the Makefile patch is set up +so that you can also just clone Kconfiglib into the kernel root: + + $ git clone git://github.com/ulfalizer/Kconfiglib.git + $ git am Kconfiglib/makefile.patch (or 'patch -p1 < Kconfiglib/makefile.patch') + +Warning: The directory name Kconfiglib/ is significant in this case, because +it's added to PYTHONPATH by the new targets in makefile.patch. + +The targets added by the Makefile patch are described in the following +sections. + + +make kmenuconfig +---------------- + +This target runs the curses menuconfig interface with Python 3 (Python 2 is +currently not supported for the menuconfig). + + +make [ARCH=] iscriptconfig +-------------------------------- + +This target gives an interactive Python prompt where a Kconfig instance has +been preloaded and is available in 'kconf'. To change the Python interpreter +used, pass PYTHONCMD= to make. The default is "python". + +To get a feel for the API, try evaluating and printing the symbols in +kconf.defined_syms, and explore the MenuNode menu tree starting at +kconf.top_node by following 'next' and 'list' pointers. + +The item contained in a menu node is found in MenuNode.item (note that this can +be one of the constants kconfiglib.MENU and kconfiglib.COMMENT), and all +symbols and choices have a 'nodes' attribute containing their menu nodes +(usually only one). Printing a menu node will print its item, in Kconfig +format. + +If you want to look up a symbol by name, use the kconf.syms dictionary. + + +make scriptconfig SCRIPT=