summaryrefslogtreecommitdiff
path: root/kconfiglib.py
diff options
context:
space:
mode:
authorUlf Magnusson <ulfalizer@gmail.com>2012-12-06 17:01:09 +0100
committerUlf Magnusson <ulfalizer@gmail.com>2012-12-06 17:01:29 +0100
commitc805e3143bada2df897927996ae23a469cf83eb3 (patch)
tree38212ced8df505ee2814ac5b8d29460f0fa5e98b /kconfiglib.py
parent94fb111d02b95413f7c36d923dabd4ec1ca1c90e (diff)
Move examples into separate directory.
Diffstat (limited to 'kconfiglib.py')
-rw-r--r--kconfiglib.py377
1 files changed, 25 insertions, 352 deletions
diff --git a/kconfiglib.py b/kconfiglib.py
index 9300021..8cdb543 100644
--- a/kconfiglib.py
+++ b/kconfiglib.py
@@ -2,18 +2,21 @@
# information from Kconfig-based configuration systems. To view the
# documentation, run
#
-# $ pydoc kconfiglib
+# $ pydoc kconfiglib
#
# or, if you prefer HTML,
#
-# $ pydoc -w kconfiglib
+# $ pydoc -w kconfiglib
#
-# By Ulf "Ulfalizer" Magnusson.
+# The examples/ subdirectory contains examples, to be run with e.g.
+#
+# $ make scriptconfig SCRIPT=Kconfiglib/examples/print_tree.py
+#
+# Look in kconfigtest.py for the test suite.
"""
-Kconfiglib is a Python library for scripting, debugging, and extracting
-information from Kconfig-based configuration systems. Features include the
-following:
+Kconfiglib is a Python library for scripting and extracting information from
+Kconfig-based configuration systems. Features include the following:
- Symbol values and properties can be looked up and values assigned
programmatically.
@@ -31,368 +34,38 @@ following:
Linux 2.6.38-rc3.
* Also generates a .config that is character-for-character identical to the
one generated by mconf for all architectures when no .config is supplied.
- * The 'make allyesconfig' and 'make allnoconfig' implementations below
+ * The 'make allyesconfig' and 'make allnoconfig' implementations in the
generate output character-for-character identical to the C implementation
for all architectures.
- See scripts/kconfig/kconfigtest.py for the Kconfiglib test suite.
+For the Linux kernel, scripts are run using
-For the Linux kernel, scripts should be run with
+ $ make scriptconfig SCRIPT=<path to script>
-$ make scriptconfig SCRIPT=<path to script>
+This ensures that needed environment variables (SRCARCH, ARCH, srctree,
+KERNELVERSION, etc.) are set up correctly. Alternative architectures can be
+specified like for other 'make *config' targets:
-to ensure that the environment (SRCARCH, ARCH, and KERNELVERSION) is set up
-correctly. Alternative architectures can be specified like for other 'make
-*config' targets:
+ $ make scriptconfig ARCH=mips SCRIPT=<path to script>
-$ make scriptconfig ARCH=mips SCRIPT=<path to script>
-
-The script will receive the name of the Kconfig file to load in sys.argv[1]. (As
+The script will receive the name of the Kconfig file to load in sys.argv[1]. As
of Linux 2.6.38-rc3 this is always "Kconfig" from the kernel top-level
-directory.)
+directory.
-To get an interactive Python prompt with Kconfiglib preloaded, use
+To get an interactive Python prompt with Kconfiglib preloaded and a Config
+object 'c' created, use
-$ make iscriptconfig [ARCH=<architecture>]
+ $ make iscriptconfig [ARCH=<architecture>]
Kconfiglib requires Python 2. For (i)scriptconfig the command to run the Python
interpreter can be passed in the environment variable PYTHONCMD (defaults to
-'python').
-
-Learning to use the library is probably easiest by looking at a few examples,
-reading the documentation, and experimenting. The API is designed to be
-intuitive and easy to use.
-
-===============================================================================
-Example 1: Load a configuration and a .config and print information about a
- symbol.
-
-import kconfiglib
-import sys
-
-# Create a Config object representing a Kconfig configuration. (Any number of
-# these can be created -- the library has no global state.)
-conf = kconfiglib.Config(sys.argv[1])
-
-# Load values from a .config file. 'srctree' is an environment variable set by
-# the Linux makefiles to the top-level directory of the kernel tree. It needs
-# to be used here for the script to work with alternative build directories
-# (specified e.g. with O=).
-conf.load_config("$srctree/arch/x86/configs/i386_defconfig")
-
-# Print some information about a symbol. (The Config class implements
-# __getitem__() to provide a handy syntax for getting symbols.)
-print conf["SERIAL_UARTLITE_CONSOLE"]
-
-Output for ARCH=i386:
-Symbol SERIAL_UARTLITE_CONSOLE
-Type : bool
-Value : "n"
-User value : (no user value)
-Visibility : "n"
-Is choice item : false
-Is defined : true
-Is from env. : false
-Is special : false
-Prompts:
- "Support for console on Xilinx uartlite serial port" if SERIAL_UARTLITE = y (value: "n")
-Default values:
- (no default values)
-Selects:
- SERIAL_CORE_CONSOLE if SERIAL_UARTLITE = y (value: "n")
-Reverse dependencies:
- (no reverse dependencies)
-Additional dependencies from enclosing menus and if's:
- HAS_IOMEM (value: "y")
-Locations: drivers/serial/Kconfig:913
-
-===============================================================================
-Example 2: Evaluate an expression in the context of a configuration. (Here we
- could load a .config as well.)
-
-import kconfiglib
-import sys
-
-conf = kconfiglib.Config(sys.argv[1])
-print conf.eval("(TRACE_IRQFLAGS_SUPPORT || PPC32) && STACKTRACE_SUPPORT")
-
-Output for ARCH=mips:
-y
-
-===============================================================================
-Example 3: Print the names of all symbols that are referenced but never defined
- in the current configuration together with the locations where they
- are referenced. Integers being included in the list is not a bug, as
- these need to be treated as symbols per the design of Kconfig.
-
-import kconfiglib
-import sys
-
-conf = kconfiglib.Config(sys.argv[1])
-
-for sym in conf.get_symbols():
- if not sym.is_defined():
- print sym.get_name()
- for (filename, linenr) in sym.get_ref_locations():
- print " {0}:{1}".format(filename, linenr)
-
-Output for ARCH=i386:
-MACH_NET2BIG_V2
- drivers/leds/Kconfig:365
-MACH_OMAP3517EVM
- sound/soc/omap/Kconfig:84
-ARCH_OMAP16XX
- drivers/pcmcia/Kconfig:271
- drivers/char/hw_random/Kconfig:117
- drivers/watchdog/Kconfig:210
- drivers/rtc/Kconfig:694
-SOC_JZ4740
- sound/soc/codecs/Kconfig:30
-MACH_AT91SAM9261EK
- drivers/video/Kconfig:1055
-PPC_83xx
- drivers/mtd/nand/Kconfig:463
- drivers/watchdog/Kconfig:951
- drivers/usb/Kconfig:58
- drivers/edac/Kconfig:221
-PPC_PSERIES
- init/Kconfig:999
- drivers/pci/hotplug/Kconfig:146
- drivers/scsi/Kconfig:964
- drivers/scsi/Kconfig:975
- drivers/scsi/Kconfig:989
- drivers/net/Kconfig:1353
- drivers/serial/Kconfig:1261
- drivers/char/Kconfig:628
- drivers/char/Kconfig:712
- drivers/char/Kconfig:729
-... (lots more)
-
-===============================================================================
-Example 4: Print the names of all symbols that reference a particular symbol.
- (There's also a method get_selected_symbols() for determining
- just selection relations.)
-
-import kconfiglib
-import sys
-
-conf = kconfiglib.Config(sys.argv[1])
-
-x86 = conf["X86"]
-for sym in conf:
- if x86 in sym.get_referenced_symbols():
- print sym.get_name()
-
-Output for ARCH=i386:
-AUDITSYSCALL
-PCSPKR_PLATFORM
-OPROFILE_EVENT_MULTIPLEX
-GCOV_PROFILE_ALL
-SCHED_OMIT_FRAME_POINTER
-MEMORY_HOTPLUG
-PM_TRACE_RTC
-ACPI
-ACPI_AC
-ACPI_BATTERY
-ACPI_VIDEO
-ACPI_PROCESSOR_AGGREGATOR
-ACPI_NUMA
-X86_PM_TIMER
-ACPI_SBS
-ACPI_APEI
-ACPI_APEI_GHES
-INTEL_IDLE
-XEN_PCIDEV_FRONTEND
-EISA_VLB_PRIMING
-EISA_VIRTUAL_ROOT
-HOTPLUG_PCI_COMPAQ
-HOTPLUG_PCI_IBM
-HOTPLUG_PCI_CPCI_ZT5550
-HOTPLUG_PCI_CPCI_GENERIC
-MTD_SC520CDP
-... (lots more)
-
-===============================================================================
-Example 5: Print a tree of all items in the configuration.
-
-import kconfiglib
-import sys
-
-def print_with_indent(s, indent):
- print (" " * indent) + s
-
-def print_items(items, indent):
- for item in items:
- if item.is_symbol():
- print_with_indent("config {0}".format(item.get_name()), indent)
- elif item.is_menu():
- print_with_indent('menu "{0}"'.format(item.get_title()), indent)
- print_items(item.get_items(), indent + 2)
- elif item.is_choice():
- print_with_indent('choice', indent)
- print_items(item.get_items(), indent + 2)
- elif item.is_comment():
- print_with_indent('comment "{0}"'.format(item.get_text()), indent)
-
-conf = kconfiglib.Config(sys.argv[1])
-print_items(conf.get_top_level_items(), 0)
-
-Output for ARCH=i386:
-...
-config ARCH
-config KERNELVERSION
-config CONSTRUCTORS
-config HAVE_IRQ_WORK
-config IRQ_WORK
-menu "General setup"
- config EXPERIMENTAL
- config BROKEN
- config BROKEN_ON_SMP
- config LOCK_KERNEL
- config INIT_ENV_ARG_LIMIT
- config CROSS_COMPILE
- config LOCALVERSION
- config LOCALVERSION_AUTO
- config HAVE_KERNEL_GZIP
- config HAVE_KERNEL_BZIP2
- config HAVE_KERNEL_LZMA
- config HAVE_KERNEL_XZ
- config HAVE_KERNEL_LZO
- choice
- config KERNEL_GZIP
- config KERNEL_BZIP2
- config KERNEL_LZMA
- config KERNEL_XZ
- config KERNEL_LZO
- config SWAP
- config SYSVIPC
- config SYSVIPC_SYSCTL
- config POSIX_MQUEUE
- config POSIX_MQUEUE_SYSCTL
- config BSD_PROCESS_ACCT
- config BSD_PROCESS_ACCT_V3
-...
-
-===============================================================================
-Example 6: This does the same thing as entering "make menuconfig" and
- immediately saving and exiting.
-
-import kconfiglib
-import os
-import sys
-
-conf = kconfiglib.Config(sys.argv[1])
-
-if os.path.exists(".config"):
- conf.load_config(".config")
-else:
- defconfig = conf.get_defconfig_filename()
- if defconfig is not None:
- print "Using " + defconfig
- conf.load_config(defconfig)
-
-conf.write_config(".config")
-
-===============================================================================
-Example 7: As a more complex example, this is a reimplementation of allnoconfig
- (verified to produce identical output to 'make allnoconfig' for all
- ARCHes). The looping is done in case setting one symbol to "n"
- allows other symbols to be set to "n" (due to dependencies).
-
-import kconfiglib
-import sys
-
-conf = kconfiglib.Config(sys.argv[1])
-
-while True:
- done = True
-
- for sym in conf:
- # Choices take care of themselves for allnoconfig, so we only need to
- # worry about non-choice symbols
- if not sym.is_choice_item():
- lower_bound = sym.get_lower_bound()
-
- # If we can assign a lower value to the symbol (where "n", "m" and
- # "y" are ordered from lowest to highest), then do so.
- # lower_bound() returns None for symbols whose values cannot
- # (currently) be changed, as well as for non-bool, non-tristate
- # symbols.
- if lower_bound is not None and \\
- kconfiglib.tri_less(lower_bound, sym.calc_value()):
-
- sym.set_value(lower_bound)
-
- # We just changed the value of some symbol. As this may affect
- # other symbols, keep going.
- done = False
-
- if done:
- break
-
-conf.write_config(".config")
-
-===============================================================================
-Example 8: here's allyesconfig (also verified), which is a bit more involved
- as we need to handle choices in two different modes ("y", i.e.
- one-is-y-rest-is-n, and "m", i.e.
- any-number-of-symbols-are-m-rest-are-n). The looping is in case
- setting one symbol to "y" (or "m") allows the value of other symbols
- to be raised.
-
-import kconfiglib
-import sys
-
-conf = kconfiglib.Config(sys.argv[1])
-
-# Get a list of all symbols that are not in choices
-non_choice_syms = [sym for sym in conf.get_symbols() if
- not sym.is_choice_item()]
-
-while True:
- done = True
-
- # Handle symbols outside of choices
-
- for sym in non_choice_syms:
- upper_bound = sym.get_upper_bound()
-
- # See corresponding comment for allnoconfig implementation
- if upper_bound is not None and \\
- kconfiglib.tri_less(sym.calc_value(), upper_bound):
- sym.set_value(upper_bound)
- done = False
-
- # Handle symbols within choices
-
- for choice in conf.get_choices():
-
- # Handle choices whose visibility allow them to be in "y" mode
-
- if choice.get_visibility() == "y":
- selection = choice.get_selection_from_defaults()
- if selection is not None and \\
- selection is not choice.get_user_selection():
- selection.set_value("y")
- done = False
-
- # Handle choices whose visibility only allow them to be in "m" mode
-
- elif choice.get_visibility() == "m":
- for sym in choice.get_items():
- if sym.calc_value() != "m" and \\
- sym.get_upper_bound() != "n":
- sym.set_value("m")
- done = False
-
-
- if done:
- break
+'python'; PyPy works too and is a bit faster).
-conf.write_config(".config")
+Look in the examples/ subdirectory for examples.
+Look in kconfigtest.py for the test suite.
-Credits: written by Ulf "Ulfalizer" Magnusson
+Credits: Written by Ulf "Ulfalizer" Magnusson
Send bug reports, suggestions (any missing APIs that would make your life
easier?) and other feedback to kconfiglib@gmail.com ."""