gdnative_builders.py 8.4 KB

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