SCsub 3.1 KB

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