modinfo-generate.py 3.3 KB

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