Atlas - list_undefined.py

Home / ext / kconfiglib / examples Lines: 6 | Size: 5022 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1# Prints a list of symbols that are referenced in the Kconfig files of some 2# architecture but not defined by the Kconfig files of any architecture. 3# 4# A Kconfig file might be shared between many architectures and legitimately 5# reference undefined symbols for some of them, but if no architecture defines 6# the symbol, it usually indicates a problem or potential cleanup. 7# 8# This script could be sped up a lot if needed. See the comment near the 9# referencing_nodes() call. 10# 11# Run with the following command in the kernel root: 12# 13# $ python(3) Kconfiglib/examples/list_undefined.py 14# 15# Example output: 16# 17# Registering defined and undefined symbols for all arches 18# Processing mips 19# Processing ia64 20# Processing metag 21# ... 22# 23# Finding references to each undefined symbol 24# Processing mips 25# Processing ia64 26# Processing metag 27# ... 28# 29# The following globally undefined symbols were found, listed here 30# together with the locations of the items that reference them. 31# References might come from enclosing menus and ifs. 32# 33# ARM_ERRATA_753970: arch/arm/mach-mvebu/Kconfig:56, arch/arm/mach-mvebu/Kconfig:39 34# SUNXI_CCU_MP: drivers/clk/sunxi-ng/Kconfig:14 35# SUNXI_CCU_DIV: drivers/clk/sunxi-ng/Kconfig:14 36# AC97: sound/ac97/Kconfig:6 37# ... 38 39import os 40import subprocess 41 42from kconfiglib import Kconfig 43 44 45# Referenced inside the Kconfig files 46os.environ["KERNELVERSION"] = str( 47 subprocess.check_output(("make", "kernelversion")).decode("utf-8").rstrip() 48) 49 50 51def all_arch_srcarch_pairs(): 52 """ 53 Generates all valid (ARCH, SRCARCH) tuples for the kernel, corresponding to 54 different architectures. SRCARCH holds the arch/ subdirectory. 55 """ 56 for srcarch in os.listdir("arch"): 57 # Each subdirectory of arch/ containing a Kconfig file corresponds to 58 # an architecture 59 if os.path.exists(os.path.join("arch", srcarch, "Kconfig")): 60 yield (srcarch, srcarch) 61 62 # Some architectures define additional ARCH settings with ARCH != SRCARCH 63 # (search for "Additional ARCH settings for" in the top-level Makefile) 64 65 yield ("i386", "x86") 66 yield ("x86_64", "x86") 67 68 yield ("sparc32", "sparc") 69 yield ("sparc64", "sparc") 70 71 yield ("sh64", "sh") 72 73 yield ("um", "um") 74 75 76def all_arch_srcarch_kconfigs(): 77 """ 78 Generates Kconfig instances for all the architectures in the kernel 79 """ 80 81 os.environ["srctree"] = "." 82 os.environ["HOSTCC"] = "gcc" 83 os.environ["HOSTCXX"] = "g++" 84 os.environ["CC"] = "gcc" 85 os.environ["LD"] = "ld" 86 87 for arch, srcarch in all_arch_srcarch_pairs(): 88 print(" Processing " + arch) 89 90 os.environ["ARCH"] = arch 91 os.environ["SRCARCH"] = srcarch 92 93 # um (User Mode Linux) uses a different base Kconfig file 94 yield Kconfig("Kconfig" if arch != "um" else "arch/x86/um/Kconfig", 95 warn=False) 96 97 98print("Registering defined and undefined symbols for all arches") 99 100# Sets holding the names of all defined and undefined symbols, for all 101# architectures 102defined = set() 103undefined = set() 104 105for kconf in all_arch_srcarch_kconfigs(): 106 for name, sym in kconf.syms.items(): 107 if sym.nodes: 108 # If the symbol has a menu node, it is defined 109 defined.add(name) 110 else: 111 # Undefined symbol. We skip some of the uninteresting ones. 112 113 # Due to how Kconfig works, integer literals show up as symbols 114 # (from e.g. 'default 1'). Skip those. 115 try: 116 int(name, 0) 117 continue 118 except ValueError: 119 # Interesting undefined symbol 120 undefined.add(name) 121 122 123print("\nFinding references to each undefined symbol") 124 125def referencing_nodes(kconf, name): 126 # Returns a list of all menu nodes that reference a symbol named 'name' in 127 # any of their properties or property conditions 128 res = [] 129 130 for node in kconf.node_iter(): 131 for ref in node.referenced: 132 if ref.name == name: 133 res.append(node) 134 135 return res 136 137 138# Maps each globally undefined symbol to the menu nodes that reference it 139undef_sym_refs = [(name, set()) for name in undefined - defined] 140 141for kconf in all_arch_srcarch_kconfigs(): 142 for name, refs in undef_sym_refs: 143 # This means that we search the entire configuration tree for each 144 # undefined symbol, which is terribly inefficient. We could speed 145 # things up by tweaking referencing_nodes() to compare each symbol to 146 # multiple symbols while walking the configuration tree. 147 for node in referencing_nodes(kconf, name): 148 refs.add("{}:{}".format(node.filename, node.linenr)) 149 150 151print("\nThe following globally undefined symbols were found, listed here\n" 152 "together with the locations of the items that reference them.\n" 153 "References might come from enclosing menus and ifs.\n") 154 155for name, refs in undef_sym_refs: 156 print(" {}: {}".format(name, ", ".join(refs))) 157
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.