summaryrefslogtreecommitdiff
path: root/examples/merge_config.py
blob: ec022d5913f13f8a77d2d671f2d0fc161ec41d3d (plain)
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
# 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:
#
#     # 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:
#
#     $ python(3) merge_config.py Kconfig merged conf1 conf2 conf3 conf4
#     conf3:2: warning: FOO (defined at Kconfig:1) 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 (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
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

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))