summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.rst2
-rw-r--r--examples/merge_config.py102
2 files changed, 104 insertions, 0 deletions
diff --git a/README.rst b/README.rst
index 09d266d..5fc3be0 100644
--- a/README.rst
+++ b/README.rst
@@ -174,6 +174,8 @@ The `examples/ <examples/>`_ directory contains some simple example scripts. Amo
- `print_tree.py <examples/print_tree.py>`_ prints a tree of all configuration items.
+- `merge_config.py <examples/merge_config.py>`_ merges configuration fragments to produce a complete .config, similarly to ``scripts/kconfig/merge_config.sh`` from the kernel.
+
- `menuconfig.py <examples/menuconfig.py>`_ implements a configuration interface that uses notation similar to ``make menuconfig``. It's deliberately kept as simple as possible to demonstrate just the core concepts, and isn't something you'd actually want to use. Here's a screenshot:
.. code-block::
diff --git a/examples/merge_config.py b/examples/merge_config.py
new file mode 100644
index 0000000..bc6e4b8
--- /dev/null
+++ b/examples/merge_config.py
@@ -0,0 +1,102 @@
+#!/usr/bin/env python3
+#
+# This script functions similarly to scripts/kconfig/merge_config.sh from the
+# kernel tree, merging multiple configurations fragments to produce a complete
+# .config, with unspecified values filled in as for alldefconfig.
+#
+# The generated .config respects symbol dependencies, and a warning is printed
+# if any symbol gets a different value from the assigned value.
+#
+# Here's a demo:
+#
+# Kconfig contents:
+#
+# config FOO
+# bool "FOO"
+#
+# config BAR
+# bool "BAR"
+#
+# config BAZ
+# string "BAZ"
+#
+# config QAZ
+# bool "QAZ" if n
+#
+#
+# conf1 contents:
+#
+# CONFIG_FOO=y
+#
+#
+# conf2 contents:
+#
+# CONFIG_BAR=y
+#
+#
+# conf3 contents:
+#
+# # Ops... assigned twice
+# CONFIG_FOO is not set
+#
+# Ops... this symbol doesn't exist
+# CONFIG_OPS=y
+#
+# CONFIG_BAZ="baz string"
+#
+#
+# conf4 contents:
+#
+# CONFIG_QAZ=y
+#
+#
+# Running:
+#
+# $ ./merge_config.py Kconfig merged conf1 conf2 conf3 conf4
+# conf3:2: warning: FOO set more than once. Old value: "y", new value: "n".
+# conf3:5: warning: attempt to assign the value "y" to the undefined symbol OPS
+# warning: QAZ 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"
+from kconfiglib import Kconfig, Symbol, BOOL, TRISTATE, TRI_TO_STR
+import sys
+
+if len(sys.argv) < 4:
+ print("usage: merge_config.py Kconfig merged_config config1 [config2 ...]")
+ sys.exit(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.)
+
+# Create a merged configuration by loading the fragments with replace=False
+for config in sys.argv[3:]:
+ kconf.load_config(config, replace=False)
+
+# Write the merged configuration
+kconf.write_config(sys.argv[2])
+
+# 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, user_value, sym.str_value))