gdnative_builders.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. """Functions used to generate source files during build time
  2. All such functions are invoked in a subprocess on Windows to prevent build flakiness.
  3. """
  4. import json
  5. from platform_methods import subprocess_main
  6. def _spaced(e):
  7. return e if e[-1] == "*" else e + " "
  8. def _build_gdnative_api_struct_header(api):
  9. out = [
  10. "/* THIS FILE IS GENERATED DO NOT EDIT */",
  11. "#ifndef GODOT_GDNATIVE_API_STRUCT_H",
  12. "#define GODOT_GDNATIVE_API_STRUCT_H",
  13. "",
  14. "#include <gdnative/gdnative.h>",
  15. "#include <android/godot_android.h>",
  16. "#include <nativescript/godot_nativescript.h>",
  17. "#include <pluginscript/godot_pluginscript.h>",
  18. "#include <videodecoder/godot_videodecoder.h>",
  19. "",
  20. "#ifdef __cplusplus",
  21. 'extern "C" {',
  22. "#endif",
  23. "",
  24. "enum GDNATIVE_API_TYPES {",
  25. "\tGDNATIVE_" + api["core"]["type"] + ",",
  26. ]
  27. for ext in api["extensions"]:
  28. out += ["\tGDNATIVE_EXT_" + ext["type"] + ","]
  29. out += ["};", ""]
  30. def generate_extension_struct(name, ext, include_version=True):
  31. ret_val = []
  32. if ext["next"]:
  33. ret_val += generate_extension_struct(name, ext["next"])
  34. ret_val += [
  35. "typedef struct godot_gdnative_ext_"
  36. + name
  37. + ("" if not include_version else ("_{0}_{1}".format(ext["version"]["major"], ext["version"]["minor"])))
  38. + "_api_struct {",
  39. "\tunsigned int type;",
  40. "\tgodot_gdnative_api_version version;",
  41. "\tconst godot_gdnative_api_struct *next;",
  42. ]
  43. for funcdef in ext["api"]:
  44. args = ", ".join(["%s%s" % (_spaced(t), n) for t, n in funcdef["arguments"]])
  45. ret_val.append("\t%s(*%s)(%s);" % (_spaced(funcdef["return_type"]), funcdef["name"], args))
  46. ret_val += [
  47. "} godot_gdnative_ext_"
  48. + name
  49. + ("" if not include_version else ("_{0}_{1}".format(ext["version"]["major"], ext["version"]["minor"])))
  50. + "_api_struct;",
  51. "",
  52. ]
  53. return ret_val
  54. def generate_core_extension_struct(core):
  55. ret_val = []
  56. if core["next"]:
  57. ret_val += generate_core_extension_struct(core["next"])
  58. ret_val += [
  59. "typedef struct godot_gdnative_core_"
  60. + "{0}_{1}".format(core["version"]["major"], core["version"]["minor"])
  61. + "_api_struct {",
  62. "\tunsigned int type;",
  63. "\tgodot_gdnative_api_version version;",
  64. "\tconst godot_gdnative_api_struct *next;",
  65. ]
  66. for funcdef in core["api"]:
  67. args = ", ".join(["%s%s" % (_spaced(t), n) for t, n in funcdef["arguments"]])
  68. ret_val.append("\t%s(*%s)(%s);" % (_spaced(funcdef["return_type"]), funcdef["name"], args))
  69. ret_val += [
  70. "} godot_gdnative_core_"
  71. + "{0}_{1}".format(core["version"]["major"], core["version"]["minor"])
  72. + "_api_struct;",
  73. "",
  74. ]
  75. return ret_val
  76. for ext in api["extensions"]:
  77. name = ext["name"]
  78. out += generate_extension_struct(name, ext, False)
  79. if api["core"]["next"]:
  80. out += generate_core_extension_struct(api["core"]["next"])
  81. out += [
  82. "typedef struct godot_gdnative_core_api_struct {",
  83. "\tunsigned int type;",
  84. "\tgodot_gdnative_api_version version;",
  85. "\tconst godot_gdnative_api_struct *next;",
  86. "\tunsigned int num_extensions;",
  87. "\tconst godot_gdnative_api_struct **extensions;",
  88. ]
  89. for funcdef in api["core"]["api"]:
  90. args = ", ".join(["%s%s" % (_spaced(t), n) for t, n in funcdef["arguments"]])
  91. out.append("\t%s(*%s)(%s);" % (_spaced(funcdef["return_type"]), funcdef["name"], args))
  92. out += [
  93. "} godot_gdnative_core_api_struct;",
  94. "",
  95. "#ifdef __cplusplus",
  96. "}",
  97. "#endif",
  98. "",
  99. "#endif // GODOT_GDNATIVE_API_STRUCT_H",
  100. "",
  101. ]
  102. return "\n".join(out)
  103. def _build_gdnative_api_struct_source(api):
  104. out = ["/* THIS FILE IS GENERATED DO NOT EDIT */", "", "#include <gdnative_api_struct.gen.h>", ""]
  105. def get_extension_struct_name(name, ext, include_version=True):
  106. return (
  107. "godot_gdnative_ext_"
  108. + name
  109. + ("" if not include_version else ("_{0}_{1}".format(ext["version"]["major"], ext["version"]["minor"])))
  110. + "_api_struct"
  111. )
  112. def get_extension_struct_instance_name(name, ext, include_version=True):
  113. return (
  114. "api_extension_"
  115. + name
  116. + ("" if not include_version else ("_{0}_{1}".format(ext["version"]["major"], ext["version"]["minor"])))
  117. + "_struct"
  118. )
  119. def get_extension_struct_definition(name, ext, include_version=True):
  120. ret_val = []
  121. if ext["next"]:
  122. ret_val += get_extension_struct_definition(name, ext["next"])
  123. ret_val += [
  124. "extern const "
  125. + get_extension_struct_name(name, ext, include_version)
  126. + " "
  127. + get_extension_struct_instance_name(name, ext, include_version)
  128. + " = {",
  129. "\tGDNATIVE_EXT_" + ext["type"] + ",",
  130. "\t{" + str(ext["version"]["major"]) + ", " + str(ext["version"]["minor"]) + "},",
  131. "\t"
  132. + (
  133. "nullptr"
  134. if not ext["next"]
  135. else ("(const godot_gdnative_api_struct *)&" + get_extension_struct_instance_name(name, ext["next"]))
  136. )
  137. + ",",
  138. ]
  139. for funcdef in ext["api"]:
  140. ret_val.append("\t%s," % funcdef["name"])
  141. ret_val += ["};\n"]
  142. return ret_val
  143. def get_core_struct_definition(core):
  144. ret_val = []
  145. if core["next"]:
  146. ret_val += get_core_struct_definition(core["next"])
  147. ret_val += [
  148. "extern const godot_gdnative_core_"
  149. + "{0}_{1}_api_struct api_{0}_{1}".format(core["version"]["major"], core["version"]["minor"])
  150. + " = {",
  151. "\tGDNATIVE_" + core["type"] + ",",
  152. "\t{" + str(core["version"]["major"]) + ", " + str(core["version"]["minor"]) + "},",
  153. "\t"
  154. + (
  155. "nullptr"
  156. if not core["next"]
  157. else (
  158. "(const godot_gdnative_api_struct *)& api_{0}_{1}".format(
  159. core["next"]["version"]["major"], core["next"]["version"]["minor"]
  160. )
  161. )
  162. )
  163. + ",",
  164. ]
  165. for funcdef in core["api"]:
  166. ret_val.append("\t%s," % funcdef["name"])
  167. ret_val += ["};\n"]
  168. return ret_val
  169. for ext in api["extensions"]:
  170. name = ext["name"]
  171. out += get_extension_struct_definition(name, ext, False)
  172. out += ["", "const godot_gdnative_api_struct *gdnative_extensions_pointers[] = {"]
  173. for ext in api["extensions"]:
  174. name = ext["name"]
  175. out += ["\t(godot_gdnative_api_struct *)&api_extension_" + name + "_struct,"]
  176. out += ["};\n"]
  177. if api["core"]["next"]:
  178. out += get_core_struct_definition(api["core"]["next"])
  179. out += [
  180. "extern const godot_gdnative_core_api_struct api_struct = {",
  181. "\tGDNATIVE_" + api["core"]["type"] + ",",
  182. "\t{" + str(api["core"]["version"]["major"]) + ", " + str(api["core"]["version"]["minor"]) + "},",
  183. "\t"
  184. + (
  185. "nullptr, "
  186. if not api["core"]["next"]
  187. else (
  188. "(const godot_gdnative_api_struct *)& api_{0}_{1},".format(
  189. api["core"]["next"]["version"]["major"], api["core"]["next"]["version"]["minor"]
  190. )
  191. )
  192. ),
  193. "\t" + str(len(api["extensions"])) + ",",
  194. "\tgdnative_extensions_pointers,",
  195. ]
  196. for funcdef in api["core"]["api"]:
  197. out.append("\t%s," % funcdef["name"])
  198. out.append("};\n")
  199. return "\n".join(out)
  200. def build_gdnative_api_struct(target, source, env):
  201. with open(source[0], "r") as fd:
  202. api = json.load(fd)
  203. header, source = target
  204. with open(header, "w") as fd:
  205. fd.write(_build_gdnative_api_struct_header(api))
  206. with open(source, "w") as fd:
  207. fd.write(_build_gdnative_api_struct_source(api))
  208. if __name__ == "__main__":
  209. subprocess_main(globals())