SCsub 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #!/usr/bin/env python
  2. from misc.utility.scons_hints import *
  3. import os
  4. import methods
  5. Import("env")
  6. env_modules = env.Clone()
  7. # Allow modules to detect if they are being built as a module.
  8. env_modules.Append(CPPDEFINES=["GODOT_MODULE"])
  9. Export("env_modules")
  10. # Header with MODULE_*_ENABLED defines.
  11. def modules_enabled_builder(target, source, env):
  12. with methods.generated_wrapper(target) as file:
  13. for module in source[0].read():
  14. file.write(f"#define MODULE_{module.upper()}_ENABLED\n")
  15. modules_enabled = env.CommandNoCache(
  16. "modules_enabled.gen.h", env.Value(env.module_list), env.Run(modules_enabled_builder)
  17. )
  18. def register_module_types_builder(target, source, env):
  19. modules = source[0].read()
  20. mod_inc = "\n".join([f'#include "{p}/register_types.h"' for p in modules.values()])
  21. mod_init = "\n".join(
  22. [f"#ifdef MODULE_{n.upper()}_ENABLED\n\tinitialize_{n}_module(p_level);\n#endif" for n in modules.keys()]
  23. )
  24. mod_uninit = "\n".join(
  25. [f"#ifdef MODULE_{n.upper()}_ENABLED\n\tuninitialize_{n}_module(p_level);\n#endif" for n in modules.keys()]
  26. )
  27. with methods.generated_wrapper(target) as file:
  28. file.write(
  29. f"""\
  30. #include "register_module_types.h"
  31. #include "modules/modules_enabled.gen.h"
  32. {mod_inc}
  33. void initialize_modules(ModuleInitializationLevel p_level) {{
  34. {mod_init}
  35. }}
  36. void uninitialize_modules(ModuleInitializationLevel p_level) {{
  37. {mod_uninit}
  38. }}
  39. """
  40. )
  41. register_module_types = env.CommandNoCache(
  42. "register_module_types.gen.cpp",
  43. [env.Value(env.modules_detected), modules_enabled],
  44. env.Run(register_module_types_builder),
  45. )
  46. test_headers = []
  47. # libmodule_<name>.a for each active module.
  48. for name, path in env.module_list.items():
  49. env.modules_sources = []
  50. # Name for built-in modules, (absolute) path for custom ones.
  51. base_path = path if os.path.isabs(path) else name
  52. SConscript(base_path + "/SCsub")
  53. lib = env_modules.add_library("module_%s" % name, env.modules_sources)
  54. env.Prepend(LIBS=[lib])
  55. if env["tests"]:
  56. # Lookup potential headers in `tests` subfolder.
  57. import glob
  58. module_tests = sorted(glob.glob(os.path.join(base_path, "tests", "*.h")))
  59. if module_tests != []:
  60. test_headers += module_tests
  61. # Generate header to be included in `tests/test_main.cpp` to run module-specific tests.
  62. if env["tests"]:
  63. def modules_tests_builder(target, source, env):
  64. with methods.generated_wrapper(target) as file:
  65. for header in source:
  66. file.write('#include "{}"\n'.format(os.path.normpath(header.path).replace("\\", "/")))
  67. env.CommandNoCache("modules_tests.gen.h", test_headers, env.Run(modules_tests_builder))
  68. # libmodules.a with only register_module_types.
  69. # Must be last so that all libmodule_<name>.a libraries are on the right side
  70. # in the linker command.
  71. env.modules_sources = []
  72. env_modules.add_source_files(env.modules_sources, register_module_types)
  73. lib = env_modules.add_library("modules", env.modules_sources)
  74. env.Prepend(LIBS=[lib])