-
Notifications
You must be signed in to change notification settings - Fork 0
/
kconfig
executable file
·109 lines (89 loc) · 3.91 KB
/
kconfig
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
#!/usr/bin/python3
from __future__ import print_function
import os, sys, subprocess, platform
import collections, argparse
import glob, gzip
from kernel.config import KernelConfig
def check_call(*args, **kargs):
print(args, kargs, file=sys.stderr)
subprocess.check_call(*args, **kargs)
def count(seq, pred):
return sum(1 for v in seq if pred(v))
class Report:
matches = {
None: ['y', 'm'],
}
def __init__(self, kernel, *configs):
self.missing = []
for config in configs:
for options in config.alternatives:
found = False
for name in options:
if kernel.options.get(name) in self.matches[config.options[name]]:
found = True
if not found:
self.missing.append((' || '.join(options), config))
def __bool__(self):
return bool(self.missing)
__nonzero__ = __bool__
def __repr__(self):
return repr(self.missing)
class Application:
def __init__(self, argv):
self.args = argv[1:]
self.configs = [KernelConfig.from_file(path) for path in glob.glob("/etc/kconfig/rules/*")]
def run(self):
parser = argparse.ArgumentParser(description="Tool for reproducible non-interactive kernel configuration")
parser.add_argument("--check", "-c", action="store_true", help="Check kernel configuration")
parser.add_argument("--configure", "--config", "-C", action="store_true", help="KernelConfigure kernel in current directory from scratch")
parser.add_argument("--build", "-g", action="store_true", help="Build kernel (using genkernel) and check it")
parser.add_argument("--modules", "-m", action="store_true", help="Use loadable modules by default")
parser.add_argument("CONFIG_FILE", nargs="*")
args = parser.parse_args()
if args.build:
self.build(args.modules)
elif args.configure:
self.configure(args.modules)
elif args.check:
if args.CONFIG_FILE:
configs = [KernelConfig.from_file(path) for path in args.CONFIG_FILE]
else:
configs = [KernelConfig.from_gzipped_file("/proc/config.gz")] + [KernelConfig.from_file(path) for path in glob.glob("/etc/kernels/*")]
self.check(*configs)
else:
parser.print_help()
exit(1)
def check(self, *configs):
for kernel in configs:
print("KernelConfig '{}'".format(kernel.source))
report = Report(kernel, *self.configs)
if report.missing:
print(" Missing options:")
for item, config in report.missing:
print(" * {} ({})".format(item, config.source))
def configure(self, modules):
check_call(["make", "defconfig"])
with open(".config", "a") as ostream:
self.write_custom_config(ostream, modules)
check_call(["make", "olddefconfig"])
self.check(KernelConfig.from_file(".config"))
def build(self, modules):
path = "/etc/kernels/kernel-config-{}-{}".format(platform.machine(), os.readlink("/usr/src/linux").split('-', 1)[1])
with open(path, "w") as ostream:
with open("/usr/share/genkernel/arch/{arch}/kernel-config".format(arch=platform.machine())) as istream:
ostream.write(istream.read())
self.write_custom_config(ostream, modules)
check_call([
"genkernel",
"--kernel-cc=/usr/lib/ccache/bin/gcc",
"--mrproper",
"--clean",
"--no-menuconfig",
"all"])
self.check(KernelConfig.from_file(path))
def write_custom_config(self, ostream, modules):
stream.write("\n#\n# Generated by kconfig tool from kernel-tools\n#\n")
for config in self.configs:
config.dump(stream)
if __name__ == '__main__':
Application(sys.argv).run()