disable impossible symbols
authorJohannes Berg <johannes@sipsolutions.net>
Sun, 31 Mar 2013 00:35:19 +0000 (01:35 +0100)
committerJohannes Berg <johannes@sipsolutions.net>
Sun, 31 Mar 2013 00:35:19 +0000 (01:35 +0100)
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
gentree.py
lib/kconfig.py
lib/make.py [new file with mode: 0644]

index 51bd526b3f33b749b914a2d6b02b23b0638fdccb..c766a0af9ecfa1995f50bef572a7bb9e6f977822 100755 (executable)
@@ -10,7 +10,7 @@ import argparse, sys, os, errno, shutil, re, subprocess
 # find self
 source_dir = os.path.abspath(os.path.dirname(sys.argv[0]))
 sys.path.append(os.path.join(source_dir, 'lib'))
-import kconfig, git, patch
+import kconfig, git, patch, make
 
 def read_copy_list(kerneldir, copyfile):
     ret = []
@@ -262,4 +262,30 @@ def main():
 
     git_debug_snapshot(args, "rename config symbol usage")
 
+    # disable unbuildable Kconfig symbols and stuff Makefiles that doesn't exist
+    maketree = make.MakeTree(os.path.join(args.outdir, 'Makefile.kernel'))
+    disable_kconfig = []
+    disable_makefile = []
+    for sym in maketree.get_impossible_symbols():
+        if sym[:7] == 'CPTCFG_':
+            disable_kconfig.append(sym[7:])
+        else:
+            disable_makefile.append(sym[7:])
+
+    configtree.disable_symbols(disable_kconfig)
+    git_debug_snapshot(args, "disable impossible kconfig symbols")
+
+    regexes = []
+    for some_symbols in [disable_makefile[i:i + 50] for i in range(0, len(disable_makefile), 50)]:
+        r = '(CONFIG_(' + '|'.join([s for s in some_symbols]) + '))'
+        regexes.append(re.compile(r, re.MULTILINE))
+    for f in maketree.get_makefiles():
+        data = open(f, 'r').read()
+        for r in regexes:
+            data = r.sub(r'IMPOSSIBLE_\2', data)
+        fo = open(f, 'w')
+        fo.write(data)
+        fo.close()
+    git_debug_snapshot(args, "disable unsatisfied Makefile parts")
+
 main()
index 3ea534a8d2d1b8cd4f24030b0cd6a8448f8c7c40..f2dc894d1fb3a476e3f40ab21d8b46b80ac9a500 100644 (file)
@@ -76,3 +76,15 @@ class ConfigTree(object):
             outf = open(os.path.join(self.basedir, nf), 'w')
             outf.write(out)
             outf.close()
+
+    def disable_symbols(self, syms):
+        for nf in self._walk(self.rootfile):
+            out = ''
+            for l in open(os.path.join(self.basedir, nf), 'r'):
+                m = cfg_line.match(l)
+                out += l
+                if m and m.group('sym') in syms:
+                    out += "\tdepends on n\n"
+            outf = open(os.path.join(self.basedir, nf), 'w')
+            outf.write(out)
+            outf.close()
diff --git a/lib/make.py b/lib/make.py
new file mode 100644 (file)
index 0000000..3ed2b67
--- /dev/null
@@ -0,0 +1,66 @@
+#
+# Small helper library to read and manipulate kernel Makefiles
+#
+
+import os, re
+
+obj_line = re.compile(r'^obj-(?P<dep>[^\s]*)\s*.?=\s*(?P<tgt>[^\\]*)\s*(?P<cont>\\?)')
+
+class MakeTree(object):
+    def __init__(self, rootfile):
+        self.basedir = os.path.dirname(rootfile)
+        self.rootfile = os.path.basename(rootfile)
+        self._no_syms = []
+        self._walked = False
+        self._found_makefiles = []
+
+    def _check_for_sym(self, f, sym):
+        # re-read Makefile to see if it declared this symbol ...
+        r = re.compile('^%s-(y|objs)\s*[+:]?=' % sym)
+        for l in open(os.path.join(self.basedir, f), 'r'):
+            if r.match(l):
+                # FIXME: check if symbol dependencies can be satisfied!
+                return True
+        return False
+
+    def _walk(self, f=None, subdir='', sym=None):
+        if self._walked:
+            return
+        if not os.path.exists(os.path.join(self.basedir, subdir, f)):
+            #print "no %s" % os.path.join(self.basedir, subdir, f)
+            assert not sym is None
+            self._no_syms.append(sym)
+            return
+        self._found_makefiles.append(os.path.join(self.basedir, subdir, f))
+        for l in open(os.path.join(self.basedir, subdir, f), 'r'):
+            m = obj_line.match(l)
+            if not m:
+                continue
+            dep = m.group('dep')
+            if dep[:2] == '$(':
+                if dep[-1] != ')':
+                    raise Exception("Couldn't parse make dependency %s" % dep)
+                dep = dep[2:-1]
+            tgt = m.group('tgt')
+            for t in tgt.strip().split():
+                t = t.strip()
+                if not t:
+                    continue
+                if t[-1] == '/':
+                    self._walk(f='Makefile', subdir=os.path.join(subdir, t), sym=dep)
+                elif t[-2:] == '.o':
+                    t = t[:-2] + '.c'
+                    if not os.path.exists(os.path.join(self.basedir, subdir, t)):
+                        if not self._check_for_sym(os.path.join(subdir, f), t[:-2]):
+                            self._no_syms.append(dep)
+                else:
+                    assert False
+                # FIXME: consider continuation lines!
+
+    def get_impossible_symbols(self):
+        self._walk(self.rootfile)
+        return self._no_syms
+
+    def get_makefiles(self):
+        self._walk(self.rootfile)
+        return self._found_makefiles