1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
#!/usr/bin/env python
# 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.
#
# For a real-world merging example based on this script, see
# https://github.com/zephyrproject-rtos/zephyr/blob/master/scripts/kconfig/kconfig.py.
#
# 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:
#
# # Assigned twice (would generate warning if 'warn_assign_override' was
# # True)
# # CONFIG_FOO is not set
#
# # Ops... this symbol doesn't exist
# CONFIG_OPS=y
#
# CONFIG_BAZ="baz string"
#
#
# conf4 contents:
#
# CONFIG_QAZ=y
#
#
# Running:
#
# $ python(3) merge_config.py Kconfig merged conf1 conf2 conf3 conf4
# Merged configuration 'conf1'
# Merged configuration 'conf2'
# conf3:5: warning: attempt to assign the value 'y' to the undefined symbol OPS
# Merged configuration 'conf3'
# Merged configuration 'conf4'
# Configuration saved to 'merged'
# 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"
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.
# load_config() and write_config() returns a message to print.
for config in sys.argv[3:]:
print(kconf.load_config(config, replace=False))
# Write the merged configuration
print(kconf.write_config(sys.argv[2]))
# 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)
|