| #!/usr/bin/env python3 |
| # -*- coding: utf-8 -*- |
| |
| import os |
| import sys |
| |
| def print_array(name, values): |
| if len(values) == 0: |
| return |
| list = ", ".join(values) |
| print(" .%s = ((const char*[]){ %s, NULL })," % (name, list)) |
| |
| def parse_line(line): |
| kind = "" |
| data = "" |
| get_kind = False |
| get_data = False |
| for item in line.split(): |
| if item == "MODINFO_START": |
| get_kind = True |
| continue |
| if item.startswith("MODINFO_END"): |
| get_data = False |
| continue |
| if get_kind: |
| kind = item |
| get_kind = False |
| get_data = True |
| continue |
| if get_data: |
| data += " " + item |
| continue |
| return (kind, data) |
| |
| def generate(name, lines, enabled): |
| arch = "" |
| objs = [] |
| deps = [] |
| opts = [] |
| for line in lines: |
| if line.find("MODINFO_START") != -1: |
| (kind, data) = parse_line(line) |
| if kind == 'obj': |
| objs.append(data) |
| elif kind == 'dep': |
| deps.append(data) |
| elif kind == 'opts': |
| opts.append(data) |
| elif kind == 'arch': |
| arch = data; |
| elif kind == 'kconfig': |
| # don't add a module which dependency is not enabled |
| # in kconfig |
| if data.strip() not in enabled: |
| print(" /* module {} isn't enabled in Kconfig. */" |
| .format(data.strip())) |
| print("/* },{ */") |
| return None |
| else: |
| print("unknown:", kind) |
| exit(1) |
| |
| print(" .name = \"%s\"," % name) |
| if arch != "": |
| print(" .arch = %s," % arch) |
| print_array("objs", objs) |
| print_array("deps", deps) |
| print_array("opts", opts) |
| print("},{") |
| return {dep.strip('" ') for dep in deps} |
| |
| def print_pre(): |
| print("/* generated by scripts/modinfo-generate.py */") |
| print("#include \"qemu/osdep.h\"") |
| print("#include \"qemu/module.h\"") |
| print("const QemuModinfo qemu_modinfo[] = {{") |
| |
| def print_post(): |
| print(" /* end of list */") |
| print("}};") |
| |
| def main(args): |
| if len(args) < 3 or args[0] != '--devices': |
| print('Expected: modinfo-generate.py --devices ' |
| 'config-device.mak [modinfo files]', file=sys.stderr) |
| exit(1) |
| |
| # get all devices enabled in kconfig, from *-config-device.mak |
| enabled = set() |
| with open(args[1]) as file: |
| for line in file.readlines(): |
| config = line.split('=') |
| if config[1].rstrip() == 'y': |
| enabled.add(config[0][7:]) # remove CONFIG_ |
| |
| deps = set() |
| modules = set() |
| print_pre() |
| for modinfo in args[2:]: |
| with open(modinfo) as f: |
| lines = f.readlines() |
| print(" /* %s */" % modinfo) |
| (basename, _) = os.path.splitext(modinfo) |
| moddeps = generate(basename, lines, enabled) |
| if moddeps is not None: |
| modules.add(basename) |
| deps.update(moddeps) |
| print_post() |
| |
| error = False |
| for dep in deps.difference(modules): |
| print("Dependency {} cannot be satisfied".format(dep), |
| file=sys.stderr) |
| error = True |
| |
| if error: |
| exit(1) |
| |
| if __name__ == "__main__": |
| main(sys.argv[1:]) |