SCsub 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #!/usr/bin/env python
  2. import os
  3. import methods
  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. # Header with MODULE_*_ENABLED defines.
  10. def modules_enabled_builder(target, source, env):
  11. with methods.generated_wrapper(target) as file:
  12. for module in source[0].read():
  13. file.write(f"#define MODULE_{module.upper()}_ENABLED\n")
  14. modules_enabled = env.CommandNoCache(
  15. "modules_enabled.gen.h", env.Value(env.module_list), env.Run(modules_enabled_builder)
  16. )
  17. def register_module_types_builder(target, source, env):
  18. modules = source[0].read()
  19. mod_inc = "\n".join([f'#include "{p}/register_types.h"' for p in modules.values()])
  20. mod_init = "\n".join(
  21. [f"#ifdef MODULE_{n.upper()}_ENABLED\n\tinitialize_{n}_module(p_level);\n#endif" for n in modules.keys()]
  22. )
  23. mod_uninit = "\n".join(
  24. [f"#ifdef MODULE_{n.upper()}_ENABLED\n\tuninitialize_{n}_module(p_level);\n#endif" for n in modules.keys()]
  25. )
  26. with methods.generated_wrapper(target) as file:
  27. file.write(
  28. f"""\
  29. #include "register_module_types.h"
  30. #include "modules/modules_enabled.gen.h"
  31. {mod_inc}
  32. void initialize_modules(ModuleInitializationLevel p_level) {{
  33. {mod_init}
  34. }}
  35. void uninitialize_modules(ModuleInitializationLevel p_level) {{
  36. {mod_uninit}
  37. }}
  38. """
  39. )
  40. register_module_types = env.CommandNoCache(
  41. "register_module_types.gen.cpp",
  42. [env.Value(env.modules_detected), modules_enabled],
  43. env.Run(register_module_types_builder),
  44. )
  45. vs_sources = []
  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["vsproj"]:
  56. vs_sources += env.modules_sources
  57. if env["tests"]:
  58. # Lookup potential headers in `tests` subfolder.
  59. import glob
  60. module_tests = sorted(glob.glob(os.path.join(base_path, "tests", "*.h")))
  61. if module_tests != []:
  62. test_headers += module_tests
  63. # Generate header to be included in `tests/test_main.cpp` to run module-specific tests.
  64. if env["tests"]:
  65. def modules_tests_builder(target, source, env):
  66. with methods.generated_wrapper(target) as file:
  67. for header in source:
  68. file.write('#include "{}"\n'.format(os.path.normpath(header.path).replace("\\", "/")))
  69. env.CommandNoCache("modules_tests.gen.h", test_headers, env.Run(modules_tests_builder))
  70. # libmodules.a with only register_module_types.
  71. # Must be last so that all libmodule_<name>.a libraries are on the right side
  72. # in the linker command.
  73. env.modules_sources = []
  74. env_modules.add_source_files(env.modules_sources, register_module_types)
  75. lib = env_modules.add_library("modules", env.modules_sources)
  76. env.Prepend(LIBS=[lib])
  77. if env["vsproj"]:
  78. env.modules_sources += vs_sources