1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4import os 5import sys 6 7def print_array(name, values): 8 if len(values) == 0: 9 return 10 list = ", ".join(values) 11 print(" .%s = ((const char*[]){ %s, NULL })," % (name, list)) 12 13def parse_line(line): 14 kind = "" 15 data = "" 16 get_kind = False 17 get_data = False 18 for item in line.split(): 19 if item == "MODINFO_START": 20 get_kind = True 21 continue 22 if item.startswith("MODINFO_END"): 23 get_data = False 24 continue 25 if get_kind: 26 kind = item 27 get_kind = False 28 get_data = True 29 continue 30 if get_data: 31 data += " " + item 32 continue 33 return (kind, data) 34 35def generate(name, lines, enabled): 36 arch = "" 37 objs = [] 38 deps = [] 39 opts = [] 40 for line in lines: 41 if line.find("MODINFO_START") != -1: 42 (kind, data) = parse_line(line) 43 if kind == 'obj': 44 objs.append(data) 45 elif kind == 'dep': 46 deps.append(data) 47 elif kind == 'opts': 48 opts.append(data) 49 elif kind == 'arch': 50 arch = data; 51 elif kind == 'kconfig': 52 # don't add a module which dependency is not enabled 53 # in kconfig 54 if data.strip() not in enabled: 55 print(" /* module {} isn't enabled in Kconfig. */" 56 .format(data.strip())) 57 print("/* },{ */") 58 return None 59 else: 60 print("unknown:", kind) 61 exit(1) 62 63 print(" .name = \"%s\"," % name) 64 if arch != "": 65 print(" .arch = %s," % arch) 66 print_array("objs", objs) 67 print_array("deps", deps) 68 print_array("opts", opts) 69 print("},{") 70 return {dep.strip('" ') for dep in deps} 71 72def print_pre(): 73 print("/* generated by scripts/modinfo-generate.py */") 74 print("#include \"qemu/osdep.h\"") 75 print("#include \"qemu/module.h\"") 76 print("const QemuModinfo qemu_modinfo[] = {{") 77 78def print_post(): 79 print(" /* end of list */") 80 print("}};") 81 82def main(args): 83 if len(args) < 3 or args[0] != '--devices': 84 print('Expected: modinfo-generate.py --devices ' 85 'config-device.mak [modinfo files]', file=sys.stderr) 86 exit(1) 87 88 # get all devices enabled in kconfig, from *-config-device.mak 89 enabled = set() 90 with open(args[1]) as file: 91 for line in file.readlines(): 92 config = line.split('=') 93 if config[1].rstrip() == 'y': 94 enabled.add(config[0][7:]) # remove CONFIG_ 95 96 deps = set() 97 modules = set() 98 print_pre() 99 for modinfo in args[2:]: 100 with open(modinfo) as f: 101 lines = f.readlines() 102 print(" /* %s */" % modinfo) 103 (basename, _) = os.path.splitext(modinfo) 104 moddeps = generate(basename, lines, enabled) 105 if moddeps is not None: 106 modules.add(basename) 107 deps.update(moddeps) 108 print_post() 109 110 error = False 111 for dep in deps.difference(modules): 112 print("Dependency {} cannot be satisfied".format(dep), 113 file=sys.stderr) 114 error = True 115 116 if error: 117 exit(1) 118 119if __name__ == "__main__": 120 main(sys.argv[1:]) 121