SCsub 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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. modules = sorted(source[0].read())
  13. with methods.generated_wrapper(str(target[0])) as file:
  14. for module in modules:
  15. file.write(f"#define MODULE_{module.upper()}_ENABLED\n")
  16. modules_enabled = env.CommandNoCache(
  17. "modules_enabled.gen.h", env.Value(env.module_list), env.Run(modules_enabled_builder)
  18. )
  19. def register_module_types_builder(target, source, env):
  20. modules = source[0].read()
  21. mod_inc = "\n".join([f'#include "{value}/register_types.h"' for value in modules.values()])
  22. mod_init = "\n".join(
  23. [
  24. f"""\
  25. #ifdef MODULE_{key.upper()}_ENABLED
  26. initialize_{key}_module(p_level);
  27. #endif"""
  28. for key in modules.keys()
  29. ]
  30. )
  31. mod_uninit = "\n".join(
  32. [
  33. f"""\
  34. #ifdef MODULE_{key.upper()}_ENABLED
  35. uninitialize_{key}_module(p_level);
  36. #endif"""
  37. for key in modules.keys()
  38. ]
  39. )
  40. with methods.generated_wrapper(str(target[0])) as file:
  41. file.write(
  42. f"""\
  43. #include "register_module_types.h"
  44. #include "modules/modules_enabled.gen.h"
  45. {mod_inc}
  46. void initialize_modules(ModuleInitializationLevel p_level) {{
  47. {mod_init}
  48. }}
  49. void uninitialize_modules(ModuleInitializationLevel p_level) {{
  50. {mod_uninit}
  51. }}
  52. """
  53. )
  54. register_module_types = env.CommandNoCache(
  55. "register_module_types.gen.cpp",
  56. [env.Value(env.modules_detected), modules_enabled],
  57. env.Run(register_module_types_builder),
  58. )
  59. test_headers = []
  60. # libmodule_<name>.a for each active module.
  61. for name, path in env.module_list.items():
  62. env.modules_sources = []
  63. # Name for built-in modules, (absolute) path for custom ones.
  64. base_path = path if os.path.isabs(path) else name
  65. SConscript(base_path + "/SCsub")
  66. lib = env_modules.add_library("module_%s" % name, env.modules_sources)
  67. env.Prepend(LIBS=[lib])
  68. if env["tests"]:
  69. # Lookup potential headers in `tests` subfolder.
  70. import glob
  71. module_tests = sorted(glob.glob(os.path.join(base_path, "tests", "*.h")))
  72. if module_tests != []:
  73. test_headers += module_tests
  74. # Generate header to be included in `tests/test_main.cpp` to run module-specific tests.
  75. if env["tests"]:
  76. def modules_tests_builder(target, source, env):
  77. headers = sorted([os.path.relpath(src.path, methods.base_folder).replace("\\", "/") for src in source])
  78. with methods.generated_wrapper(str(target[0])) as file:
  79. for header in headers:
  80. file.write(f'#include "{header}"\n')
  81. env.CommandNoCache("modules_tests.gen.h", test_headers, env.Run(modules_tests_builder))
  82. # libmodules.a with only register_module_types.
  83. # Must be last so that all libmodule_<name>.a libraries are on the right side
  84. # in the linker command.
  85. env.modules_sources = []
  86. env_modules.add_source_files(env.modules_sources, register_module_types)
  87. lib = env_modules.add_library("modules", env.modules_sources)
  88. env.Prepend(LIBS=[lib])