SCsub 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. #!/usr/bin/env python
  2. Import('env')
  3. gdn_env = env.Clone()
  4. gdn_env.add_source_files(env.modules_sources, "gdnative.cpp")
  5. gdn_env.add_source_files(env.modules_sources, "register_types.cpp")
  6. gdn_env.add_source_files(env.modules_sources, "gdnative/*.cpp")
  7. gdn_env.add_source_files(env.modules_sources, "nativescript/*.cpp")
  8. gdn_env.add_source_files(env.modules_sources, "gdnative_library_singleton_editor.cpp")
  9. gdn_env.add_source_files(env.modules_sources, "gdnative_library_editor_plugin.cpp")
  10. gdn_env.Append(CPPPATH=['#modules/gdnative/include/'])
  11. SConscript("arvr/SCsub")
  12. SConscript("pluginscript/SCsub")
  13. def _spaced(e):
  14. return e if e[-1] == '*' else e + ' '
  15. def _build_gdnative_api_struct_header(api):
  16. gdnative_api_init_macro = [
  17. '\textern const godot_gdnative_core_api_struct *_gdnative_wrapper_api_struct;'
  18. ]
  19. for name in api['extensions']:
  20. gdnative_api_init_macro.append(
  21. '\textern const godot_gdnative_ext_{0}_api_struct *_gdnative_wrapper_{0}_api_struct;'.format(name))
  22. gdnative_api_init_macro.append('\t_gdnative_wrapper_api_struct = options->api_struct;')
  23. gdnative_api_init_macro.append('\tfor (int i = 0; i < _gdnative_wrapper_api_struct->num_extensions; i++) { ')
  24. gdnative_api_init_macro.append('\t\tswitch (_gdnative_wrapper_api_struct->extensions[i]->type) {')
  25. for name in api['extensions']:
  26. gdnative_api_init_macro.append(
  27. '\t\t\tcase GDNATIVE_EXT_%s:' % api['extensions'][name]['type'])
  28. gdnative_api_init_macro.append(
  29. '\t\t\t\t_gdnative_wrapper_{0}_api_struct = (godot_gdnative_ext_{0}_api_struct *)'
  30. ' _gdnative_wrapper_api_struct->extensions[i];'.format(name))
  31. gdnative_api_init_macro.append('\t\t\t\tbreak;')
  32. gdnative_api_init_macro.append('\t\t}')
  33. gdnative_api_init_macro.append('\t}')
  34. out = [
  35. '/* THIS FILE IS GENERATED DO NOT EDIT */',
  36. '#ifndef GODOT_GDNATIVE_API_STRUCT_H',
  37. '#define GODOT_GDNATIVE_API_STRUCT_H',
  38. '',
  39. '#include <gdnative/gdnative.h>',
  40. '#include <arvr/godot_arvr.h>',
  41. '#include <nativescript/godot_nativescript.h>',
  42. '#include <pluginscript/godot_pluginscript.h>',
  43. '',
  44. '#define GDNATIVE_API_INIT(options) do { \\\n' + ' \\\n'.join(gdnative_api_init_macro) + ' \\\n } while (0)',
  45. '',
  46. '#ifdef __cplusplus',
  47. 'extern "C" {',
  48. '#endif',
  49. '',
  50. 'enum GDNATIVE_API_TYPES {',
  51. '\tGDNATIVE_' + api['core']['type'] + ','
  52. ]
  53. for name in api['extensions']:
  54. out += ['\tGDNATIVE_EXT_' + api['extensions'][name]['type'] + ',']
  55. out += ['};', '']
  56. for name in api['extensions']:
  57. out += [
  58. 'typedef struct godot_gdnative_ext_' + name + '_api_struct {',
  59. '\tunsigned int type;',
  60. '\tgodot_gdnative_api_version version;',
  61. '\tconst godot_gdnative_api_struct *next;'
  62. ]
  63. for funcdef in api['extensions'][name]['api']:
  64. args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']])
  65. out.append('\t%s(*%s)(%s);' % (_spaced(funcdef['return_type']), funcdef['name'], args))
  66. out += ['} godot_gdnative_ext_' + name + '_api_struct;', '']
  67. out += [
  68. 'typedef struct godot_gdnative_core_api_struct {',
  69. '\tunsigned int type;',
  70. '\tgodot_gdnative_api_version version;',
  71. '\tconst godot_gdnative_api_struct *next;',
  72. '\tunsigned int num_extensions;',
  73. '\tconst godot_gdnative_api_struct **extensions;',
  74. ]
  75. for funcdef in api['core']['api']:
  76. args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']])
  77. out.append('\t%s(*%s)(%s);' % (_spaced(funcdef['return_type']), funcdef['name'], args))
  78. out += [
  79. '} godot_gdnative_core_api_struct;',
  80. '',
  81. '#ifdef __cplusplus',
  82. '}',
  83. '#endif',
  84. '',
  85. '#endif // GODOT_GDNATIVE_API_STRUCT_H',
  86. ''
  87. ]
  88. return '\n'.join(out)
  89. def _build_gdnative_api_struct_source(api):
  90. out = [
  91. '/* THIS FILE IS GENERATED DO NOT EDIT */',
  92. '',
  93. '#include <gdnative_api_struct.gen.h>',
  94. ''
  95. ]
  96. for name in api['extensions']:
  97. out += [
  98. 'extern const godot_gdnative_ext_' + name + '_api_struct api_extension_' + name + '_struct = {',
  99. '\tGDNATIVE_EXT_' + api['extensions'][name]['type'] + ',',
  100. '\t{' + str(api['extensions'][name]['version']['major']) + ', ' + str(api['extensions'][name]['version']['minor']) + '},',
  101. '\tNULL,'
  102. ]
  103. for funcdef in api['extensions'][name]['api']:
  104. out.append('\t%s,' % funcdef['name'])
  105. out += ['};\n']
  106. out += ['', 'const godot_gdnative_api_struct *gdnative_extensions_pointers[] = {']
  107. for name in api['extensions']:
  108. out += ['\t(godot_gdnative_api_struct *)&api_extension_' + name + '_struct,']
  109. out += ['};\n']
  110. out += [
  111. 'extern const godot_gdnative_core_api_struct api_struct = {',
  112. '\tGDNATIVE_' + api['core']['type'] + ',',
  113. '\t{' + str(api['core']['version']['major']) + ', ' + str(api['core']['version']['minor']) + '},',
  114. '\tNULL,',
  115. '\t' + str(len(api['extensions'])) + ',',
  116. '\tgdnative_extensions_pointers,',
  117. ]
  118. for funcdef in api['core']['api']:
  119. out.append('\t%s,' % funcdef['name'])
  120. out.append('};\n')
  121. return '\n'.join(out)
  122. def build_gdnative_api_struct(target, source, env):
  123. import json
  124. from collections import OrderedDict
  125. with open(source[0].path, 'r') as fd:
  126. api = json.load(fd)
  127. header, source = target
  128. with open(header.path, 'w') as fd:
  129. fd.write(_build_gdnative_api_struct_header(api))
  130. with open(source.path, 'w') as fd:
  131. fd.write(_build_gdnative_api_struct_source(api))
  132. _, gensource = gdn_env.CommandNoCache(['include/gdnative_api_struct.gen.h', 'gdnative_api_struct.gen.cpp'],
  133. 'gdnative_api.json', build_gdnative_api_struct)
  134. gdn_env.add_source_files(env.modules_sources, [gensource])
  135. env.use_ptrcall = True
  136. def _build_gdnative_wrapper_code(api):
  137. out = [
  138. '/* THIS FILE IS GENERATED DO NOT EDIT */',
  139. '',
  140. '#include <gdnative/gdnative.h>',
  141. '#include <nativescript/godot_nativescript.h>',
  142. '#include <pluginscript/godot_pluginscript.h>',
  143. '#include <arvr/godot_arvr.h>',
  144. '',
  145. '#include <gdnative_api_struct.gen.h>',
  146. '',
  147. '#ifdef __cplusplus',
  148. 'extern "C" {',
  149. '#endif',
  150. '',
  151. 'godot_gdnative_core_api_struct *_gdnative_wrapper_api_struct = 0;',
  152. ]
  153. for name in api['extensions']:
  154. out.append('godot_gdnative_ext_' + name + '_api_struct *_gdnative_wrapper_' + name + '_api_struct = 0;')
  155. out += ['']
  156. for funcdef in api['core']['api']:
  157. args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']])
  158. out.append('%s%s(%s) {' % (_spaced(funcdef['return_type']), funcdef['name'], args))
  159. args = ', '.join(['%s' % n for t, n in funcdef['arguments']])
  160. return_line = '\treturn ' if funcdef['return_type'] != 'void' else '\t'
  161. return_line += '_gdnative_wrapper_api_struct->' + funcdef['name'] + '(' + args + ');'
  162. out.append(return_line)
  163. out.append('}')
  164. out.append('')
  165. for name in api['extensions']:
  166. for funcdef in api['extensions'][name]['api']:
  167. args = ', '.join(['%s%s' % (_spaced(t), n) for t, n in funcdef['arguments']])
  168. out.append('%s%s(%s) {' % (_spaced(funcdef['return_type']), funcdef['name'], args))
  169. args = ', '.join(['%s' % n for t, n in funcdef['arguments']])
  170. return_line = '\treturn ' if funcdef['return_type'] != 'void' else '\t'
  171. return_line += '_gdnative_wrapper_' + name + '_api_struct->' + funcdef['name'] + '(' + args + ');'
  172. out.append(return_line)
  173. out.append('}')
  174. out.append('')
  175. out += [
  176. '#ifdef __cplusplus',
  177. '}',
  178. '#endif'
  179. ]
  180. return '\n'.join(out)
  181. def build_gdnative_wrapper_code(target, source, env):
  182. import json
  183. with open(source[0].path, 'r') as fd:
  184. api = json.load(fd)
  185. wrapper_file = target[0]
  186. with open(wrapper_file.path, 'w') as fd:
  187. fd.write(_build_gdnative_wrapper_code(api))
  188. if ARGUMENTS.get('gdnative_wrapper', False):
  189. #build wrapper code
  190. gensource, = gdn_env.CommandNoCache('gdnative_wrapper_code.gen.cpp', 'gdnative_api.json', build_gdnative_wrapper_code)
  191. gd_wrapper_env = env.Clone()
  192. gd_wrapper_env.Append(CPPPATH=['#modules/gdnative/include/'])
  193. if gd_wrapper_env['use_lto']:
  194. if not env.msvc:
  195. gd_wrapper_env.Append(CCFLAGS=['-fno-lto'])
  196. gd_wrapper_env.Append(LINKFLAGS=['-fno-lto'])
  197. else:
  198. gd_wrapper_env.Append(CCFLAGS=['/GL-'])
  199. gd_wrapper_env.Append(LINKFLAGS=['/LTCG:OFF'])
  200. if not env.msvc:
  201. gd_wrapper_env.Append(CCFLAGS=['-fPIC'])
  202. lib = gd_wrapper_env.add_library("#bin/gdnative_wrapper_code", [gensource])