15ebbfeccSGerd Hoffmann#!/usr/bin/env python3 25ebbfeccSGerd Hoffmann# -*- coding: utf-8 -*- 35ebbfeccSGerd Hoffmann 45ebbfeccSGerd Hoffmannimport os 55ebbfeccSGerd Hoffmannimport sys 65ebbfeccSGerd Hoffmann 75ebbfeccSGerd Hoffmanndef print_array(name, values): 85ebbfeccSGerd Hoffmann if len(values) == 0: 95ebbfeccSGerd Hoffmann return 105ebbfeccSGerd Hoffmann list = ", ".join(values) 115ebbfeccSGerd Hoffmann print(" .%s = ((const char*[]){ %s, NULL })," % (name, list)) 125ebbfeccSGerd Hoffmann 135ebbfeccSGerd Hoffmanndef parse_line(line): 145ebbfeccSGerd Hoffmann kind = "" 155ebbfeccSGerd Hoffmann data = "" 165ebbfeccSGerd Hoffmann get_kind = False 175ebbfeccSGerd Hoffmann get_data = False 185ebbfeccSGerd Hoffmann for item in line.split(): 195ebbfeccSGerd Hoffmann if item == "MODINFO_START": 205ebbfeccSGerd Hoffmann get_kind = True 215ebbfeccSGerd Hoffmann continue 225ebbfeccSGerd Hoffmann if item.startswith("MODINFO_END"): 235ebbfeccSGerd Hoffmann get_data = False 245ebbfeccSGerd Hoffmann continue 255ebbfeccSGerd Hoffmann if get_kind: 265ebbfeccSGerd Hoffmann kind = item 275ebbfeccSGerd Hoffmann get_kind = False 285ebbfeccSGerd Hoffmann get_data = True 295ebbfeccSGerd Hoffmann continue 305ebbfeccSGerd Hoffmann if get_data: 315ebbfeccSGerd Hoffmann data += " " + item 325ebbfeccSGerd Hoffmann continue 335ebbfeccSGerd Hoffmann return (kind, data) 345ebbfeccSGerd Hoffmann 35*05d6814cSJose R. Zivianidef generate(name, lines, enabled): 365ebbfeccSGerd Hoffmann arch = "" 375ebbfeccSGerd Hoffmann objs = [] 385ebbfeccSGerd Hoffmann deps = [] 395ebbfeccSGerd Hoffmann opts = [] 405ebbfeccSGerd Hoffmann for line in lines: 415ebbfeccSGerd Hoffmann if line.find("MODINFO_START") != -1: 425ebbfeccSGerd Hoffmann (kind, data) = parse_line(line) 435ebbfeccSGerd Hoffmann if kind == 'obj': 445ebbfeccSGerd Hoffmann objs.append(data) 455ebbfeccSGerd Hoffmann elif kind == 'dep': 465ebbfeccSGerd Hoffmann deps.append(data) 475ebbfeccSGerd Hoffmann elif kind == 'opts': 485ebbfeccSGerd Hoffmann opts.append(data) 495ebbfeccSGerd Hoffmann elif kind == 'arch': 505ebbfeccSGerd Hoffmann arch = data; 5124ce7aa7SJose R. Ziviani elif kind == 'kconfig': 52*05d6814cSJose R. Ziviani # don't add a module which dependency is not enabled 53*05d6814cSJose R. Ziviani # in kconfig 54*05d6814cSJose R. Ziviani if data.strip() not in enabled: 55*05d6814cSJose R. Ziviani print(" /* module {} isn't enabled in Kconfig. */" 56*05d6814cSJose R. Ziviani .format(data.strip())) 57*05d6814cSJose R. Ziviani print("/* },{ */") 58*05d6814cSJose R. Ziviani return None 595ebbfeccSGerd Hoffmann else: 605ebbfeccSGerd Hoffmann print("unknown:", kind) 615ebbfeccSGerd Hoffmann exit(1) 625ebbfeccSGerd Hoffmann 635ebbfeccSGerd Hoffmann print(" .name = \"%s\"," % name) 645ebbfeccSGerd Hoffmann if arch != "": 655ebbfeccSGerd Hoffmann print(" .arch = %s," % arch) 665ebbfeccSGerd Hoffmann print_array("objs", objs) 675ebbfeccSGerd Hoffmann print_array("deps", deps) 685ebbfeccSGerd Hoffmann print_array("opts", opts) 69*05d6814cSJose R. Ziviani print("},{") 70*05d6814cSJose R. Ziviani return {dep.strip('" ') for dep in deps} 715ebbfeccSGerd Hoffmann 725ebbfeccSGerd Hoffmanndef print_pre(): 735ebbfeccSGerd Hoffmann print("/* generated by scripts/modinfo-generate.py */") 745ebbfeccSGerd Hoffmann print("#include \"qemu/osdep.h\"") 755ebbfeccSGerd Hoffmann print("#include \"qemu/module.h\"") 765ebbfeccSGerd Hoffmann print("const QemuModinfo qemu_modinfo[] = {{") 775ebbfeccSGerd Hoffmann 785ebbfeccSGerd Hoffmanndef print_post(): 795ebbfeccSGerd Hoffmann print(" /* end of list */") 805ebbfeccSGerd Hoffmann print("}};") 815ebbfeccSGerd Hoffmann 825ebbfeccSGerd Hoffmanndef main(args): 83*05d6814cSJose R. Ziviani if len(args) < 3 or args[0] != '--devices': 84*05d6814cSJose R. Ziviani print('Expected: modinfo-generate.py --devices ' 85*05d6814cSJose R. Ziviani 'config-device.mak [modinfo files]', file=sys.stderr) 86*05d6814cSJose R. Ziviani exit(1) 87*05d6814cSJose R. Ziviani 88*05d6814cSJose R. Ziviani # get all devices enabled in kconfig, from *-config-device.mak 89*05d6814cSJose R. Ziviani enabled = set() 90*05d6814cSJose R. Ziviani with open(args[1]) as file: 91*05d6814cSJose R. Ziviani for line in file.readlines(): 92*05d6814cSJose R. Ziviani config = line.split('=') 93*05d6814cSJose R. Ziviani if config[1].rstrip() == 'y': 94*05d6814cSJose R. Ziviani enabled.add(config[0][7:]) # remove CONFIG_ 95*05d6814cSJose R. Ziviani 96*05d6814cSJose R. Ziviani deps = set() 97*05d6814cSJose R. Ziviani modules = set() 985ebbfeccSGerd Hoffmann print_pre() 99*05d6814cSJose R. Ziviani for modinfo in args[2:]: 1005ebbfeccSGerd Hoffmann with open(modinfo) as f: 1015ebbfeccSGerd Hoffmann lines = f.readlines() 1025ebbfeccSGerd Hoffmann print(" /* %s */" % modinfo) 103*05d6814cSJose R. Ziviani (basename, _) = os.path.splitext(modinfo) 104*05d6814cSJose R. Ziviani moddeps = generate(basename, lines, enabled) 105*05d6814cSJose R. Ziviani if moddeps is not None: 106*05d6814cSJose R. Ziviani modules.add(basename) 107*05d6814cSJose R. Ziviani deps.update(moddeps) 1085ebbfeccSGerd Hoffmann print_post() 1095ebbfeccSGerd Hoffmann 110af19eecfSJose R. Ziviani error = False 111*05d6814cSJose R. Ziviani for dep in deps.difference(modules): 112af19eecfSJose R. Ziviani print("Dependency {} cannot be satisfied".format(dep), 113af19eecfSJose R. Ziviani file=sys.stderr) 114af19eecfSJose R. Ziviani error = True 115af19eecfSJose R. Ziviani 116af19eecfSJose R. Ziviani if error: 117af19eecfSJose R. Ziviani exit(1) 118af19eecfSJose R. Ziviani 1195ebbfeccSGerd Hoffmannif __name__ == "__main__": 1205ebbfeccSGerd Hoffmann main(sys.argv[1:]) 121