#!/usr/bin/python #: kac-sources.py : hardware database generator from kernel sources # # Copyright (c) 2000,2001,2007 Giacomo A. Catenazzi # This is free software, see GNU General Public License v2 for details import sys, os, os.path, fnmatch import re # generic parameters. gloabals for debuging kerneldir="." # kernel main directory, stripped filename="" # actual filename, relative to kerneldir phase="init" logfile = open("kac-sources.log", "w") def log(str): logfile.write("LOG: %s %s\n" % (filename, phase)) logfile.write(str) logfile.write("\n") # --- --- --- --- # # parse Makefile for file dependencies # dictionary of CONFIG_ dependencies on files (from Makefile) # format: filename.c: (CONFIG_FOO, CONFIG_BAR) dependencies = {} # format: filename.c: (virtual-filename-objs.c, ...) dep_aliases = {} kbuild_normalize = re.compile(r"(#.*$|\\[ \t]*\n)", re.MULTILINE) kbuild_rules = re.compile(r"^([A-Za-z0-9-]+)-([^+=: \t\n]+)\s*[:+]?=\s*(.*)$", re.MULTILINE) def parse_kbuild(kerneldir, subdir, deps=-1): filename=subdir mk = os.path.join(kerneldir, subdir, "Makefile") if not os.path.isfile(mk): mk = os.path.join(kerneldir, subdir, "Kbuild") if not os.path.isfile(mk): log("parse_kbuild: could not find file: %s" % mk) return f = open(mk) src = kbuild_normalize.sub(" ", f.read()) f.close() if deps == -1: deps = () for (rule, dep, files) in kbuild_rules.findall(src): if dep in ("y", "m"): d = deps elif dep[0:9] == '$(CONFIG_' and dep[-1] == ')': d = deps + (dep[2:-1] ,) else: log("parse_kbuild: unknow dep in %s: '%s'" % (mk, dep)) continue for f in files.split(): fn = os.path.join(subdir, f) if f[-1] == "/": parse_kbuild(kerneldir, fn, d) elif f[-2:] == ".o": k = fn[:-2] if dependencies.has_key(k): v = dependencies[k] + d else: v = d dependencies[k] = v else: log("parse_kbuild: unknow 'files' in %s: '%s'" % (mk, f)) if not rule in ("init", "drivers", "net", "libs", "core", "obj", "lib"): for f in files.split(): fn = os.path.join(subdir, f) if f[-2:] == ".o": k = fn[:-2] v = (os.path.join(subdir, rule),) if dep_aliases.has_key(k): v = dep_aliases[k] + v dep_aliases[k] = v def list_dep(fn): d = [] if dependencies.has_key(fn): d = dependencies[fn] alias = fn while(dep_aliases.has_key(alias)): alias = dep_aliases[alias] if dependencies.has_key(alias) and not dependencies.has_key(alias) in d: d += dependencies[alias] if not d: return ("CONFIG__UNKNOW__",) return d #----------------------- kerneldir = sys.argv[1] kerdir_len = len(kerneldir) includedir = os.path.join(kerneldir, "include") if len(sys.argv) > 2: dirs = sys.argv[2:] else: dirs = ("arch", "block", "crypto", "drivers", "fs", "init", "ipc", "kernel", "lib", "mm", "net", "security", "sound") for subdir in dirs: phase="kbuild" if subdir == "arch": for arch in os.listdir(os.path.join(kerneldir, "arch/")): mk2 = os.path.join("arch/", arch) parse_kbuild(kerneldir, mk2) else: parse_kbuild(kerneldir, subdir) for k,v in dependencies.items(): if not v: continue i = k.rfind("/") print k[i+1:], ":", " ".join(v)