You've already forked godot
							
							
				mirror of
				https://github.com/godotengine/godot.git
				synced 2025-11-03 11:50:27 +00:00 
			
		
		
		
	SCons: Begin decoupling generation & build code
This commit is contained in:
		
							
								
								
									
										90
									
								
								core/SCsub
									
									
									
									
									
								
							
							
						
						
									
										90
									
								
								core/SCsub
									
									
									
									
									
								
							@@ -1,14 +1,14 @@
 | 
			
		||||
#!/usr/bin/env python
 | 
			
		||||
from misc.utility.scons_hints import *
 | 
			
		||||
 | 
			
		||||
Import("env")
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
import core_builders
 | 
			
		||||
 | 
			
		||||
import methods
 | 
			
		||||
 | 
			
		||||
Import("env")
 | 
			
		||||
 | 
			
		||||
env.core_sources = []
 | 
			
		||||
 | 
			
		||||
# Add required thirdparty code.
 | 
			
		||||
@@ -161,96 +161,34 @@ env.core_sources += thirdparty_obj
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Godot source files
 | 
			
		||||
 | 
			
		||||
env.add_source_files(env.core_sources, "*.cpp")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Generate disabled classes
 | 
			
		||||
def disabled_class_builder(target, source, env):
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        for c in source[0].read():
 | 
			
		||||
            if cs := c.strip():
 | 
			
		||||
                file.write(f"#define ClassDB_Disable_{cs} 1\n")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
env.CommandNoCache("disabled_classes.gen.h", env.Value(env.disabled_classes), env.Run(disabled_class_builder))
 | 
			
		||||
 | 
			
		||||
env.CommandNoCache(
 | 
			
		||||
    "disabled_classes.gen.h", env.Value(env.disabled_classes), env.Run(core_builders.disabled_class_builder)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# Generate version info
 | 
			
		||||
def version_info_builder(target, source, env):
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        file.write(
 | 
			
		||||
            """\
 | 
			
		||||
#define GODOT_VERSION_SHORT_NAME "{short_name}"
 | 
			
		||||
#define GODOT_VERSION_NAME "{name}"
 | 
			
		||||
#define GODOT_VERSION_MAJOR {major}
 | 
			
		||||
#define GODOT_VERSION_MINOR {minor}
 | 
			
		||||
#define GODOT_VERSION_PATCH {patch}
 | 
			
		||||
#define GODOT_VERSION_STATUS "{status}"
 | 
			
		||||
#define GODOT_VERSION_BUILD "{build}"
 | 
			
		||||
#define GODOT_VERSION_MODULE_CONFIG "{module_config}"
 | 
			
		||||
#define GODOT_VERSION_WEBSITE "{website}"
 | 
			
		||||
#define GODOT_VERSION_DOCS_BRANCH "{docs_branch}"
 | 
			
		||||
#define GODOT_VERSION_DOCS_URL "https://docs.godotengine.org/en/" GODOT_VERSION_DOCS_BRANCH
 | 
			
		||||
""".format(**source[0].read())
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
env.CommandNoCache(
 | 
			
		||||
    "version_generated.gen.h",
 | 
			
		||||
    env.Value(methods.get_version_info(env.module_version_string)),
 | 
			
		||||
    env.Run(version_info_builder),
 | 
			
		||||
    env.Run(core_builders.version_info_builder),
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Generate version hash
 | 
			
		||||
def version_hash_builder(target, source, env):
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        file.write(
 | 
			
		||||
            """\
 | 
			
		||||
#include "core/version.h"
 | 
			
		||||
 | 
			
		||||
const char *const GODOT_VERSION_HASH = "{git_hash}";
 | 
			
		||||
const uint64_t GODOT_VERSION_TIMESTAMP = {git_timestamp};
 | 
			
		||||
""".format(**source[0].read())
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
gen_hash = env.CommandNoCache("version_hash.gen.cpp", env.Value(methods.get_git_info()), env.Run(version_hash_builder))
 | 
			
		||||
gen_hash = env.CommandNoCache(
 | 
			
		||||
    "version_hash.gen.cpp", env.Value(methods.get_git_info()), env.Run(core_builders.version_hash_builder)
 | 
			
		||||
)
 | 
			
		||||
env.add_source_files(env.core_sources, gen_hash)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Generate AES256 script encryption key
 | 
			
		||||
def encryption_key_builder(target, source, env):
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        file.write(
 | 
			
		||||
            f"""\
 | 
			
		||||
#include "core/config/project_settings.h"
 | 
			
		||||
 | 
			
		||||
uint8_t script_encryption_key[32] = {{
 | 
			
		||||
	{source[0]}
 | 
			
		||||
}};"""
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
gdkey = os.environ.get("SCRIPT_AES256_ENCRYPTION_KEY", "0" * 64)
 | 
			
		||||
ec_valid = len(gdkey) == 64
 | 
			
		||||
if ec_valid:
 | 
			
		||||
    try:
 | 
			
		||||
        gdkey = ", ".join([str(int(f"{a}{b}", 16)) for a, b in zip(gdkey[0::2], gdkey[1::2])])
 | 
			
		||||
    except Exception:
 | 
			
		||||
        ec_valid = False
 | 
			
		||||
if not ec_valid:
 | 
			
		||||
    methods.print_error(
 | 
			
		||||
        f'Invalid AES256 encryption key, not 64 hexadecimal characters: "{gdkey}".\n'
 | 
			
		||||
        "Unset `SCRIPT_AES256_ENCRYPTION_KEY` in your environment "
 | 
			
		||||
        "or make sure that it contains exactly 64 hexadecimal characters."
 | 
			
		||||
    )
 | 
			
		||||
    Exit(255)
 | 
			
		||||
gen_encrypt = env.CommandNoCache("script_encryption_key.gen.cpp", env.Value(gdkey), env.Run(encryption_key_builder))
 | 
			
		||||
gen_encrypt = env.CommandNoCache(
 | 
			
		||||
    "script_encryption_key.gen.cpp",
 | 
			
		||||
    env.Value(os.environ.get("SCRIPT_AES256_ENCRYPTION_KEY")),
 | 
			
		||||
    env.Run(core_builders.encryption_key_builder),
 | 
			
		||||
)
 | 
			
		||||
env.add_source_files(env.core_sources, gen_encrypt)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Certificates
 | 
			
		||||
env.CommandNoCache(
 | 
			
		||||
    "#core/io/certs_compressed.gen.h",
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,71 @@ from io import TextIOWrapper
 | 
			
		||||
import methods
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Generate disabled classes
 | 
			
		||||
def disabled_class_builder(target, source, env):
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        for c in source[0].read():
 | 
			
		||||
            if cs := c.strip():
 | 
			
		||||
                file.write(f"#define ClassDB_Disable_{cs} 1\n")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Generate version info
 | 
			
		||||
def version_info_builder(target, source, env):
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        file.write(
 | 
			
		||||
            """\
 | 
			
		||||
#define GODOT_VERSION_SHORT_NAME "{short_name}"
 | 
			
		||||
#define GODOT_VERSION_NAME "{name}"
 | 
			
		||||
#define GODOT_VERSION_MAJOR {major}
 | 
			
		||||
#define GODOT_VERSION_MINOR {minor}
 | 
			
		||||
#define GODOT_VERSION_PATCH {patch}
 | 
			
		||||
#define GODOT_VERSION_STATUS "{status}"
 | 
			
		||||
#define GODOT_VERSION_BUILD "{build}"
 | 
			
		||||
#define GODOT_VERSION_MODULE_CONFIG "{module_config}"
 | 
			
		||||
#define GODOT_VERSION_WEBSITE "{website}"
 | 
			
		||||
#define GODOT_VERSION_DOCS_BRANCH "{docs_branch}"
 | 
			
		||||
#define GODOT_VERSION_DOCS_URL "https://docs.godotengine.org/en/" GODOT_VERSION_DOCS_BRANCH
 | 
			
		||||
""".format(**source[0].read())
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def version_hash_builder(target, source, env):
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        file.write(
 | 
			
		||||
            """\
 | 
			
		||||
#include "core/version.h"
 | 
			
		||||
 | 
			
		||||
const char *const GODOT_VERSION_HASH = "{git_hash}";
 | 
			
		||||
const uint64_t GODOT_VERSION_TIMESTAMP = {git_timestamp};
 | 
			
		||||
""".format(**source[0].read())
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def encryption_key_builder(target, source, env):
 | 
			
		||||
    src = source[0].read() or "0" * 64
 | 
			
		||||
    try:
 | 
			
		||||
        buffer = bytes.fromhex(src)
 | 
			
		||||
        if len(buffer) != 32:
 | 
			
		||||
            raise ValueError
 | 
			
		||||
    except ValueError:
 | 
			
		||||
        methods.print_error(
 | 
			
		||||
            f'Invalid AES256 encryption key, not 64 hexadecimal characters: "{src}".\n'
 | 
			
		||||
            "Unset `SCRIPT_AES256_ENCRYPTION_KEY` in your environment "
 | 
			
		||||
            "or make sure that it contains exactly 64 hexadecimal characters."
 | 
			
		||||
        )
 | 
			
		||||
        raise
 | 
			
		||||
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        file.write(
 | 
			
		||||
            f"""\
 | 
			
		||||
#include "core/config/project_settings.h"
 | 
			
		||||
 | 
			
		||||
uint8_t script_encryption_key[32] = {{
 | 
			
		||||
	{methods.format_buffer(buffer, 1)}
 | 
			
		||||
}};"""
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def make_certs_header(target, source, env):
 | 
			
		||||
    buffer = methods.get_buffer(str(source[0]))
 | 
			
		||||
    decomp_size = len(buffer)
 | 
			
		||||
@@ -13,8 +78,8 @@ def make_certs_header(target, source, env):
 | 
			
		||||
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        # System certs path. Editor will use them if defined. (for package maintainers)
 | 
			
		||||
        file.write('#define _SYSTEM_CERTS_PATH "{}"\n'.format(env["system_certs_path"]))
 | 
			
		||||
        if env["builtin_certs"]:
 | 
			
		||||
        file.write(f'#define _SYSTEM_CERTS_PATH "{source[2]}"\n')
 | 
			
		||||
        if source[1].read():
 | 
			
		||||
            # Defined here and not in env so changing it does not trigger a full rebuild.
 | 
			
		||||
            file.write(f"""\
 | 
			
		||||
#define BUILTIN_CERTS_ENABLED
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										57
									
								
								editor/SCsub
									
									
									
									
									
								
							
							
						
						
									
										57
									
								
								editor/SCsub
									
									
									
									
									
								
							@@ -1,64 +1,25 @@
 | 
			
		||||
#!/usr/bin/env python
 | 
			
		||||
from misc.utility.scons_hints import *
 | 
			
		||||
 | 
			
		||||
Import("env")
 | 
			
		||||
 | 
			
		||||
env.editor_sources = []
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
import editor_builders
 | 
			
		||||
 | 
			
		||||
import methods
 | 
			
		||||
Import("env")
 | 
			
		||||
 | 
			
		||||
env.editor_sources = []
 | 
			
		||||
 | 
			
		||||
if env.editor_build:
 | 
			
		||||
    # Generate doc data paths
 | 
			
		||||
    def doc_data_class_path_builder(target, source, env):
 | 
			
		||||
        paths = dict(sorted(source[0].read().items()))
 | 
			
		||||
        data = "\n".join([f'\t{{"{key}", "{value}"}},' for key, value in paths.items()])
 | 
			
		||||
        with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
            file.write(
 | 
			
		||||
                f"""\
 | 
			
		||||
struct _DocDataClassPath {{
 | 
			
		||||
	const char *name;
 | 
			
		||||
	const char *path;
 | 
			
		||||
}};
 | 
			
		||||
 | 
			
		||||
inline constexpr int _doc_data_class_path_count = {len(paths)};
 | 
			
		||||
inline constexpr _DocDataClassPath _doc_data_class_paths[{len(env.doc_class_path) + 1}] = {{
 | 
			
		||||
{data}
 | 
			
		||||
	{{nullptr, nullptr}},
 | 
			
		||||
}};
 | 
			
		||||
"""
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
    env.CommandNoCache("doc_data_class_path.gen.h", env.Value(env.doc_class_path), env.Run(doc_data_class_path_builder))
 | 
			
		||||
    env.CommandNoCache(
 | 
			
		||||
        "doc_data_class_path.gen.h", env.Value(env.doc_class_path), env.Run(editor_builders.doc_data_class_path_builder)
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    # Register exporters
 | 
			
		||||
    def register_exporters_builder(target, source, env):
 | 
			
		||||
        platforms = source[0].read()
 | 
			
		||||
        exp_inc = "\n".join([f'#include "platform/{p}/export/export.h"' for p in platforms])
 | 
			
		||||
        exp_reg = "\n".join([f"\tregister_{p}_exporter();" for p in platforms])
 | 
			
		||||
        exp_type = "\n".join([f"\tregister_{p}_exporter_types();" for p in platforms])
 | 
			
		||||
        with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
            file.write(
 | 
			
		||||
                f"""\
 | 
			
		||||
#include "register_exporters.h"
 | 
			
		||||
 | 
			
		||||
{exp_inc}
 | 
			
		||||
 | 
			
		||||
void register_exporters() {{
 | 
			
		||||
{exp_reg}
 | 
			
		||||
}}
 | 
			
		||||
 | 
			
		||||
void register_exporter_types() {{
 | 
			
		||||
{exp_type}
 | 
			
		||||
}}
 | 
			
		||||
"""
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
    gen_exporters = env.CommandNoCache(
 | 
			
		||||
        "register_exporters.gen.cpp", env.Value(env.platform_exporters), env.Run(register_exporters_builder)
 | 
			
		||||
        "register_exporters.gen.cpp",
 | 
			
		||||
        env.Value(env.platform_exporters),
 | 
			
		||||
        env.Run(editor_builders.register_exporters_builder),
 | 
			
		||||
    )
 | 
			
		||||
    for e in env.platform_exporters:
 | 
			
		||||
        # Add all .cpp files in export folder
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,49 @@ import uuid
 | 
			
		||||
import methods
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def doc_data_class_path_builder(target, source, env):
 | 
			
		||||
    paths = dict(sorted(source[0].read().items()))
 | 
			
		||||
    data = "\n".join([f'\t{{"{key}", "{value}"}},' for key, value in paths.items()])
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        file.write(
 | 
			
		||||
            f"""\
 | 
			
		||||
struct _DocDataClassPath {{
 | 
			
		||||
	const char *name;
 | 
			
		||||
	const char *path;
 | 
			
		||||
}};
 | 
			
		||||
 | 
			
		||||
inline constexpr int _doc_data_class_path_count = {len(paths)};
 | 
			
		||||
inline constexpr _DocDataClassPath _doc_data_class_paths[{len(paths) + 1}] = {{
 | 
			
		||||
	{data}
 | 
			
		||||
	{{nullptr, nullptr}},
 | 
			
		||||
}};
 | 
			
		||||
"""
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def register_exporters_builder(target, source, env):
 | 
			
		||||
    platforms = source[0].read()
 | 
			
		||||
    exp_inc = "\n".join([f'#include "platform/{p}/export/export.h"' for p in platforms])
 | 
			
		||||
    exp_reg = "\n\t".join([f"register_{p}_exporter();" for p in platforms])
 | 
			
		||||
    exp_type = "\n\t".join([f"register_{p}_exporter_types();" for p in platforms])
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        file.write(
 | 
			
		||||
            f"""\
 | 
			
		||||
#include "register_exporters.h"
 | 
			
		||||
 | 
			
		||||
{exp_inc}
 | 
			
		||||
 | 
			
		||||
void register_exporters() {{
 | 
			
		||||
	{exp_reg}
 | 
			
		||||
}}
 | 
			
		||||
 | 
			
		||||
void register_exporter_types() {{
 | 
			
		||||
	{exp_type}
 | 
			
		||||
}}
 | 
			
		||||
"""
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def make_doc_header(target, source, env):
 | 
			
		||||
    buffer = b"".join([methods.get_buffer(src) for src in map(str, source)])
 | 
			
		||||
    decomp_size = len(buffer)
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@ from misc.utility.scons_hints import *
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
import methods
 | 
			
		||||
import modules_builders
 | 
			
		||||
 | 
			
		||||
Import("env")
 | 
			
		||||
 | 
			
		||||
@@ -16,63 +16,15 @@ Export("env_modules")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Header with MODULE_*_ENABLED defines.
 | 
			
		||||
def modules_enabled_builder(target, source, env):
 | 
			
		||||
    modules = sorted(source[0].read())
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        for module in modules:
 | 
			
		||||
            file.write(f"#define MODULE_{module.upper()}_ENABLED\n")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
modules_enabled = env.CommandNoCache(
 | 
			
		||||
    "modules_enabled.gen.h", env.Value(env.module_list), env.Run(modules_enabled_builder)
 | 
			
		||||
    "modules_enabled.gen.h", env.Value(env.module_list), env.Run(modules_builders.modules_enabled_builder)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def register_module_types_builder(target, source, env):
 | 
			
		||||
    modules = source[0].read()
 | 
			
		||||
    mod_inc = "\n".join([f'#include "{value}/register_types.h"' for value in modules.values()])
 | 
			
		||||
    mod_init = "\n".join(
 | 
			
		||||
        [
 | 
			
		||||
            f"""\
 | 
			
		||||
#ifdef MODULE_{key.upper()}_ENABLED
 | 
			
		||||
	initialize_{key}_module(p_level);
 | 
			
		||||
#endif"""
 | 
			
		||||
            for key in modules.keys()
 | 
			
		||||
        ]
 | 
			
		||||
    )
 | 
			
		||||
    mod_uninit = "\n".join(
 | 
			
		||||
        [
 | 
			
		||||
            f"""\
 | 
			
		||||
#ifdef MODULE_{key.upper()}_ENABLED
 | 
			
		||||
	uninitialize_{key}_module(p_level);
 | 
			
		||||
#endif"""
 | 
			
		||||
            for key in modules.keys()
 | 
			
		||||
        ]
 | 
			
		||||
    )
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        file.write(
 | 
			
		||||
            f"""\
 | 
			
		||||
#include "register_module_types.h"
 | 
			
		||||
 | 
			
		||||
#include "modules/modules_enabled.gen.h"
 | 
			
		||||
 | 
			
		||||
{mod_inc}
 | 
			
		||||
 | 
			
		||||
void initialize_modules(ModuleInitializationLevel p_level) {{
 | 
			
		||||
{mod_init}
 | 
			
		||||
}}
 | 
			
		||||
 | 
			
		||||
void uninitialize_modules(ModuleInitializationLevel p_level) {{
 | 
			
		||||
{mod_uninit}
 | 
			
		||||
}}
 | 
			
		||||
"""
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
register_module_types = env.CommandNoCache(
 | 
			
		||||
    "register_module_types.gen.cpp",
 | 
			
		||||
    [env.Value(env.modules_detected), modules_enabled],
 | 
			
		||||
    env.Run(register_module_types_builder),
 | 
			
		||||
    env.Run(modules_builders.register_module_types_builder),
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -99,14 +51,7 @@ for name, path in env.module_list.items():
 | 
			
		||||
 | 
			
		||||
# Generate header to be included in `tests/test_main.cpp` to run module-specific tests.
 | 
			
		||||
if env["tests"]:
 | 
			
		||||
 | 
			
		||||
    def modules_tests_builder(target, source, env):
 | 
			
		||||
        headers = sorted([os.path.relpath(src.path, methods.base_folder).replace("\\", "/") for src in source])
 | 
			
		||||
        with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
            for header in headers:
 | 
			
		||||
                file.write(f'#include "{header}"\n')
 | 
			
		||||
 | 
			
		||||
    env.CommandNoCache("modules_tests.gen.h", test_headers, env.Run(modules_tests_builder))
 | 
			
		||||
    env.CommandNoCache("modules_tests.gen.h", test_headers, env.Run(modules_builders.modules_tests_builder))
 | 
			
		||||
 | 
			
		||||
# libmodules.a with only register_module_types.
 | 
			
		||||
# Must be last so that all libmodule_<name>.a libraries are on the right side
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										60
									
								
								modules/modules_builders.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								modules/modules_builders.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
"""Functions used to generate source files during build time"""
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
import methods
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def modules_enabled_builder(target, source, env):
 | 
			
		||||
    modules = sorted(source[0].read())
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        for module in modules:
 | 
			
		||||
            file.write(f"#define MODULE_{module.upper()}_ENABLED\n")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def register_module_types_builder(target, source, env):
 | 
			
		||||
    modules = source[0].read()
 | 
			
		||||
    mod_inc = "\n".join([f'#include "{value}/register_types.h"' for value in modules.values()])
 | 
			
		||||
    mod_init = "\n".join(
 | 
			
		||||
        [
 | 
			
		||||
            f"""\
 | 
			
		||||
#ifdef MODULE_{key.upper()}_ENABLED
 | 
			
		||||
	initialize_{key}_module(p_level);
 | 
			
		||||
#endif"""
 | 
			
		||||
            for key in modules.keys()
 | 
			
		||||
        ]
 | 
			
		||||
    )
 | 
			
		||||
    mod_uninit = "\n".join(
 | 
			
		||||
        [
 | 
			
		||||
            f"""\
 | 
			
		||||
#ifdef MODULE_{key.upper()}_ENABLED
 | 
			
		||||
	uninitialize_{key}_module(p_level);
 | 
			
		||||
#endif"""
 | 
			
		||||
            for key in modules.keys()
 | 
			
		||||
        ]
 | 
			
		||||
    )
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        file.write(
 | 
			
		||||
            f"""\
 | 
			
		||||
#include "register_module_types.h"
 | 
			
		||||
 | 
			
		||||
#include "modules/modules_enabled.gen.h"
 | 
			
		||||
 | 
			
		||||
{mod_inc}
 | 
			
		||||
 | 
			
		||||
void initialize_modules(ModuleInitializationLevel p_level) {{
 | 
			
		||||
{mod_init}
 | 
			
		||||
}}
 | 
			
		||||
 | 
			
		||||
void uninitialize_modules(ModuleInitializationLevel p_level) {{
 | 
			
		||||
{mod_uninit}
 | 
			
		||||
}}
 | 
			
		||||
"""
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def modules_tests_builder(target, source, env):
 | 
			
		||||
    headers = sorted([os.path.relpath(src.path, methods.base_folder).replace("\\", "/") for src in source])
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        for header in headers:
 | 
			
		||||
            file.write(f'#include "{header}"\n')
 | 
			
		||||
@@ -1,32 +1,13 @@
 | 
			
		||||
#!/usr/bin/env python
 | 
			
		||||
from misc.utility.scons_hints import *
 | 
			
		||||
 | 
			
		||||
import methods
 | 
			
		||||
import text_server_adv_builders
 | 
			
		||||
 | 
			
		||||
Import("env")
 | 
			
		||||
Import("env_modules")
 | 
			
		||||
 | 
			
		||||
env_text_server_adv = env_modules.Clone()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def make_icu_data(target, source, env):
 | 
			
		||||
    buffer = methods.get_buffer(str(source[0]))
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        file.write(f"""\
 | 
			
		||||
/* (C) 2016 and later: Unicode, Inc. and others. */
 | 
			
		||||
/* License & terms of use: https://www.unicode.org/copyright.html */
 | 
			
		||||
 | 
			
		||||
#include <unicode/utypes.h>
 | 
			
		||||
#include <unicode/udata.h>
 | 
			
		||||
#include <unicode/uversion.h>
 | 
			
		||||
 | 
			
		||||
extern "C" U_EXPORT const size_t U_ICUDATA_SIZE = {len(buffer)};
 | 
			
		||||
extern "C" U_EXPORT const unsigned char U_ICUDATA_ENTRY_POINT[] = {{
 | 
			
		||||
	{methods.format_buffer(buffer, 1)}
 | 
			
		||||
}};
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Thirdparty source files
 | 
			
		||||
 | 
			
		||||
thirdparty_obj = []
 | 
			
		||||
@@ -512,7 +493,9 @@ if env["builtin_icu4c"]:
 | 
			
		||||
 | 
			
		||||
    if env.editor_build:
 | 
			
		||||
        icudata = env_icu.CommandNoCache(
 | 
			
		||||
            "#thirdparty/icu4c/icudata.gen.h", "#thirdparty/icu4c/icudt_godot.dat", env.Run(make_icu_data)
 | 
			
		||||
            "#thirdparty/icu4c/icudata.gen.h",
 | 
			
		||||
            "#thirdparty/icu4c/icudt_godot.dat",
 | 
			
		||||
            env.Run(text_server_adv_builders.make_icu_data),
 | 
			
		||||
        )
 | 
			
		||||
        env_text_server_adv.Prepend(CPPEXTPATH=["#thirdparty/icu4c/"])
 | 
			
		||||
        env_icu.Depends(lib, icudata)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								modules/text_server_adv/text_server_adv_builders.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								modules/text_server_adv/text_server_adv_builders.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
"""Functions used to generate source files during build time"""
 | 
			
		||||
 | 
			
		||||
import methods
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def make_icu_data(target, source, env):
 | 
			
		||||
    buffer = methods.get_buffer(str(source[0]))
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        file.write(f"""\
 | 
			
		||||
/* (C) 2016 and later: Unicode, Inc. and others. */
 | 
			
		||||
/* License & terms of use: https://www.unicode.org/copyright.html */
 | 
			
		||||
 | 
			
		||||
#include <unicode/utypes.h>
 | 
			
		||||
#include <unicode/udata.h>
 | 
			
		||||
#include <unicode/uversion.h>
 | 
			
		||||
 | 
			
		||||
extern "C" U_EXPORT const size_t U_ICUDATA_SIZE = {len(buffer)};
 | 
			
		||||
extern "C" U_EXPORT const unsigned char U_ICUDATA_ENTRY_POINT[] = {{
 | 
			
		||||
	{methods.format_buffer(buffer, 1)}
 | 
			
		||||
}};
 | 
			
		||||
""")
 | 
			
		||||
@@ -2,9 +2,8 @@
 | 
			
		||||
from misc.utility.scons_hints import *
 | 
			
		||||
 | 
			
		||||
from glob import glob
 | 
			
		||||
from pathlib import Path
 | 
			
		||||
 | 
			
		||||
import methods
 | 
			
		||||
import platform_builders
 | 
			
		||||
 | 
			
		||||
Import("env")
 | 
			
		||||
 | 
			
		||||
@@ -12,51 +11,16 @@ env.platform_sources = []
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Generate export icons
 | 
			
		||||
def export_icon_builder(target, source, env):
 | 
			
		||||
    src_path = Path(str(source[0]))
 | 
			
		||||
    src_name = src_path.stem
 | 
			
		||||
    platform = src_path.parent.parent.stem
 | 
			
		||||
    with open(str(source[0]), "r") as file:
 | 
			
		||||
        svg = file.read()
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        file.write(
 | 
			
		||||
            f"""\
 | 
			
		||||
inline constexpr const char *_{platform}_{src_name}_svg = {methods.to_raw_cstring(svg)};
 | 
			
		||||
"""
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
for platform in env.platform_exporters:
 | 
			
		||||
    for path in glob(f"{platform}/export/*.svg"):
 | 
			
		||||
        env.CommandNoCache(path.replace(".svg", "_svg.gen.h"), path, env.Run(export_icon_builder))
 | 
			
		||||
        env.CommandNoCache(path.replace(".svg", "_svg.gen.h"), path, env.Run(platform_builders.export_icon_builder))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Register platform-exclusive APIs
 | 
			
		||||
def register_platform_apis_builder(target, source, env):
 | 
			
		||||
    platforms = source[0].read()
 | 
			
		||||
    api_inc = "\n".join([f'#include "{p}/api/api.h"' for p in platforms])
 | 
			
		||||
    api_reg = "\n".join([f"\tregister_{p}_api();" for p in platforms])
 | 
			
		||||
    api_unreg = "\n".join([f"\tunregister_{p}_api();" for p in platforms])
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        file.write(
 | 
			
		||||
            f"""\
 | 
			
		||||
#include "register_platform_apis.h"
 | 
			
		||||
 | 
			
		||||
{api_inc}
 | 
			
		||||
 | 
			
		||||
void register_platform_apis() {{
 | 
			
		||||
{api_reg}
 | 
			
		||||
}}
 | 
			
		||||
 | 
			
		||||
void unregister_platform_apis() {{
 | 
			
		||||
{api_unreg}
 | 
			
		||||
}}
 | 
			
		||||
"""
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
register_platform_apis = env.CommandNoCache(
 | 
			
		||||
    "register_platform_apis.gen.cpp", env.Value(env.platform_apis), env.Run(register_platform_apis_builder)
 | 
			
		||||
    "register_platform_apis.gen.cpp",
 | 
			
		||||
    env.Value(env.platform_apis),
 | 
			
		||||
    env.Run(platform_builders.register_platform_apis_builder),
 | 
			
		||||
)
 | 
			
		||||
env.add_source_files(env.platform_sources, register_platform_apis)
 | 
			
		||||
for platform in env.platform_apis:
 | 
			
		||||
 
 | 
			
		||||
@@ -2,9 +2,10 @@
 | 
			
		||||
from misc.utility.scons_hints import *
 | 
			
		||||
 | 
			
		||||
import platform
 | 
			
		||||
import subprocess
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
import platform_android_builders
 | 
			
		||||
 | 
			
		||||
from methods import print_warning
 | 
			
		||||
 | 
			
		||||
Import("env")
 | 
			
		||||
@@ -101,33 +102,9 @@ if lib_arch_dir != "" and host_subpath != "":
 | 
			
		||||
    stl_lib_path = f"{env['ANDROID_NDK_ROOT']}/toolchains/llvm/prebuilt/{host_subpath}/sysroot/usr/lib/{triple_target_dir}/libc++_shared.so"
 | 
			
		||||
    env_android.CommandNoCache(out_dir + "/libc++_shared.so", stl_lib_path, Copy("$TARGET", "$SOURCE"))
 | 
			
		||||
 | 
			
		||||
    def generate_android_binaries(target, source, env):
 | 
			
		||||
        gradle_process = []
 | 
			
		||||
 | 
			
		||||
        if sys.platform.startswith("win"):
 | 
			
		||||
            gradle_process = [
 | 
			
		||||
                "cmd",
 | 
			
		||||
                "/c",
 | 
			
		||||
                "gradlew.bat",
 | 
			
		||||
            ]
 | 
			
		||||
        else:
 | 
			
		||||
            gradle_process = ["./gradlew"]
 | 
			
		||||
 | 
			
		||||
        if env["target"] == "editor":
 | 
			
		||||
            gradle_process += ["generateGodotEditor", "generateGodotHorizonOSEditor", "generateGodotPicoOSEditor"]
 | 
			
		||||
        else:
 | 
			
		||||
            gradle_process += ["generateGodotTemplates"]
 | 
			
		||||
        gradle_process += ["--quiet"]
 | 
			
		||||
 | 
			
		||||
        if env["gradle_do_not_strip"]:
 | 
			
		||||
            gradle_process += ["-PdoNotStrip=true"]
 | 
			
		||||
 | 
			
		||||
        subprocess.run(
 | 
			
		||||
            gradle_process,
 | 
			
		||||
            cwd="platform/android/java",
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    if env["generate_android_binaries"]:
 | 
			
		||||
        env_android.AlwaysBuild(
 | 
			
		||||
            env_android.CommandNoCache("generate_android_binaries", lib, env.Run(generate_android_binaries))
 | 
			
		||||
            env_android.CommandNoCache(
 | 
			
		||||
                "generate_android_binaries", lib, env.Run(platform_android_builders.generate_android_binaries)
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										31
									
								
								platform/android/platform_android_builders.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								platform/android/platform_android_builders.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
"""Functions used to generate source files during build time"""
 | 
			
		||||
 | 
			
		||||
import subprocess
 | 
			
		||||
import sys
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def generate_android_binaries(target, source, env):
 | 
			
		||||
    gradle_process = []
 | 
			
		||||
 | 
			
		||||
    if sys.platform.startswith("win"):
 | 
			
		||||
        gradle_process = [
 | 
			
		||||
            "cmd",
 | 
			
		||||
            "/c",
 | 
			
		||||
            "gradlew.bat",
 | 
			
		||||
        ]
 | 
			
		||||
    else:
 | 
			
		||||
        gradle_process = ["./gradlew"]
 | 
			
		||||
 | 
			
		||||
    if env["target"] == "editor":
 | 
			
		||||
        gradle_process += ["generateGodotEditor", "generateGodotHorizonOSEditor", "generateGodotPicoOSEditor"]
 | 
			
		||||
    else:
 | 
			
		||||
        gradle_process += ["generateGodotTemplates"]
 | 
			
		||||
    gradle_process += ["--quiet"]
 | 
			
		||||
 | 
			
		||||
    if env["gradle_do_not_strip"]:
 | 
			
		||||
        gradle_process += ["-PdoNotStrip=true"]
 | 
			
		||||
 | 
			
		||||
    subprocess.run(
 | 
			
		||||
        gradle_process,
 | 
			
		||||
        cwd="platform/android/java",
 | 
			
		||||
    )
 | 
			
		||||
@@ -1,64 +1,10 @@
 | 
			
		||||
#!/usr/bin/env python
 | 
			
		||||
from misc.utility.scons_hints import *
 | 
			
		||||
 | 
			
		||||
import platform_ios_builders
 | 
			
		||||
 | 
			
		||||
Import("env")
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
import shutil
 | 
			
		||||
 | 
			
		||||
from platform_methods import detect_mvk, lipo
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def generate_bundle(target, source, env):
 | 
			
		||||
    bin_dir = Dir("#bin").abspath
 | 
			
		||||
 | 
			
		||||
    # Template bundle.
 | 
			
		||||
    app_prefix = "godot." + env["platform"]
 | 
			
		||||
    rel_prefix = "libgodot." + env["platform"] + "." + "template_release"
 | 
			
		||||
    dbg_prefix = "libgodot." + env["platform"] + "." + "template_debug"
 | 
			
		||||
    if env.dev_build:
 | 
			
		||||
        app_prefix += ".dev"
 | 
			
		||||
        rel_prefix += ".dev"
 | 
			
		||||
        dbg_prefix += ".dev"
 | 
			
		||||
    if env["precision"] == "double":
 | 
			
		||||
        app_prefix += ".double"
 | 
			
		||||
        rel_prefix += ".double"
 | 
			
		||||
        dbg_prefix += ".double"
 | 
			
		||||
 | 
			
		||||
    # Lipo template libraries.
 | 
			
		||||
    rel_target_bin = lipo(bin_dir + "/" + rel_prefix, env.extra_suffix + ".a")
 | 
			
		||||
    dbg_target_bin = lipo(bin_dir + "/" + dbg_prefix, env.extra_suffix + ".a")
 | 
			
		||||
    rel_target_bin_sim = lipo(bin_dir + "/" + rel_prefix, ".simulator" + env.extra_suffix + ".a")
 | 
			
		||||
    dbg_target_bin_sim = lipo(bin_dir + "/" + dbg_prefix, ".simulator" + env.extra_suffix + ".a")
 | 
			
		||||
 | 
			
		||||
    # Assemble Xcode project bundle.
 | 
			
		||||
    app_dir = Dir("#bin/ios_xcode").abspath
 | 
			
		||||
    templ = Dir("#misc/dist/ios_xcode").abspath
 | 
			
		||||
    if os.path.exists(app_dir):
 | 
			
		||||
        shutil.rmtree(app_dir)
 | 
			
		||||
    shutil.copytree(templ, app_dir)
 | 
			
		||||
    if rel_target_bin != "":
 | 
			
		||||
        shutil.copy(rel_target_bin, app_dir + "/libgodot.ios.release.xcframework/ios-arm64/libgodot.a")
 | 
			
		||||
    if dbg_target_bin != "":
 | 
			
		||||
        shutil.copy(dbg_target_bin, app_dir + "/libgodot.ios.debug.xcframework/ios-arm64/libgodot.a")
 | 
			
		||||
    if rel_target_bin_sim != "":
 | 
			
		||||
        shutil.copy(
 | 
			
		||||
            rel_target_bin_sim, app_dir + "/libgodot.ios.release.xcframework/ios-arm64_x86_64-simulator/libgodot.a"
 | 
			
		||||
        )
 | 
			
		||||
    if dbg_target_bin_sim != "":
 | 
			
		||||
        shutil.copy(
 | 
			
		||||
            dbg_target_bin_sim, app_dir + "/libgodot.ios.debug.xcframework/ios-arm64_x86_64-simulator/libgodot.a"
 | 
			
		||||
        )
 | 
			
		||||
    mvk_path = detect_mvk(env, "ios-arm64")
 | 
			
		||||
    if mvk_path != "":
 | 
			
		||||
        shutil.copytree(mvk_path, app_dir + "/MoltenVK.xcframework")
 | 
			
		||||
 | 
			
		||||
    # ZIP Xcode project bundle.
 | 
			
		||||
    zip_dir = Dir("#bin/" + (app_prefix + env.extra_suffix).replace(".", "_")).abspath
 | 
			
		||||
    shutil.make_archive(zip_dir, "zip", root_dir=app_dir)
 | 
			
		||||
    shutil.rmtree(app_dir)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ios_lib = [
 | 
			
		||||
    "godot_ios.mm",
 | 
			
		||||
    "os_ios.mm",
 | 
			
		||||
@@ -86,20 +32,11 @@ ios_lib = env_ios.add_library("ios", ios_lib)
 | 
			
		||||
env_ios.Append(CCFLAGS=["-fmodules", "-fcxx-modules"])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def combine_libs(target=None, source=None, env=None):
 | 
			
		||||
    lib_path = target[0].srcnode().abspath
 | 
			
		||||
    if "osxcross" in env:
 | 
			
		||||
        libtool = "$IOS_TOOLCHAIN_PATH/usr/bin/${ios_triple}libtool"
 | 
			
		||||
    else:
 | 
			
		||||
        libtool = "$IOS_TOOLCHAIN_PATH/usr/bin/libtool"
 | 
			
		||||
    env.Execute(
 | 
			
		||||
        libtool + ' -static -o "' + lib_path + '" ' + " ".join([('"' + lib.srcnode().abspath + '"') for lib in source])
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
combine_command = env_ios.CommandNoCache(
 | 
			
		||||
    "#bin/libgodot" + env_ios["LIBSUFFIX"], [ios_lib] + env_ios["LIBS"], env.Run(combine_libs)
 | 
			
		||||
    "#bin/libgodot" + env_ios["LIBSUFFIX"], [ios_lib] + env_ios["LIBS"], env.Run(platform_ios_builders.combine_libs)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if env["generate_bundle"]:
 | 
			
		||||
    env.AlwaysBuild(env.CommandNoCache("generate_bundle", combine_command, env.Run(generate_bundle)))
 | 
			
		||||
    env.AlwaysBuild(
 | 
			
		||||
        env.CommandNoCache("generate_bundle", combine_command, env.Run(platform_ios_builders.generate_bundle))
 | 
			
		||||
    )
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										67
									
								
								platform/ios/platform_ios_builders.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								platform/ios/platform_ios_builders.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
"""Functions used to generate source files during build time"""
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
import shutil
 | 
			
		||||
 | 
			
		||||
from platform_methods import detect_mvk, lipo
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def combine_libs(target, source, env):
 | 
			
		||||
    lib_path = target[0].srcnode().abspath
 | 
			
		||||
    if "osxcross" in env:
 | 
			
		||||
        libtool = "$IOS_TOOLCHAIN_PATH/usr/bin/${ios_triple}libtool"
 | 
			
		||||
    else:
 | 
			
		||||
        libtool = "$IOS_TOOLCHAIN_PATH/usr/bin/libtool"
 | 
			
		||||
    env.Execute(
 | 
			
		||||
        libtool + ' -static -o "' + lib_path + '" ' + " ".join([('"' + lib.srcnode().abspath + '"') for lib in source])
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def generate_bundle(target, source, env):
 | 
			
		||||
    bin_dir = env.Dir("#bin").abspath
 | 
			
		||||
 | 
			
		||||
    # Template bundle.
 | 
			
		||||
    app_prefix = "godot." + env["platform"]
 | 
			
		||||
    rel_prefix = "libgodot." + env["platform"] + "." + "template_release"
 | 
			
		||||
    dbg_prefix = "libgodot." + env["platform"] + "." + "template_debug"
 | 
			
		||||
    if env.dev_build:
 | 
			
		||||
        app_prefix += ".dev"
 | 
			
		||||
        rel_prefix += ".dev"
 | 
			
		||||
        dbg_prefix += ".dev"
 | 
			
		||||
    if env["precision"] == "double":
 | 
			
		||||
        app_prefix += ".double"
 | 
			
		||||
        rel_prefix += ".double"
 | 
			
		||||
        dbg_prefix += ".double"
 | 
			
		||||
 | 
			
		||||
    # Lipo template libraries.
 | 
			
		||||
    rel_target_bin = lipo(bin_dir + "/" + rel_prefix, env.extra_suffix + ".a")
 | 
			
		||||
    dbg_target_bin = lipo(bin_dir + "/" + dbg_prefix, env.extra_suffix + ".a")
 | 
			
		||||
    rel_target_bin_sim = lipo(bin_dir + "/" + rel_prefix, ".simulator" + env.extra_suffix + ".a")
 | 
			
		||||
    dbg_target_bin_sim = lipo(bin_dir + "/" + dbg_prefix, ".simulator" + env.extra_suffix + ".a")
 | 
			
		||||
 | 
			
		||||
    # Assemble Xcode project bundle.
 | 
			
		||||
    app_dir = env.Dir("#bin/ios_xcode").abspath
 | 
			
		||||
    templ = env.Dir("#misc/dist/ios_xcode").abspath
 | 
			
		||||
    if os.path.exists(app_dir):
 | 
			
		||||
        shutil.rmtree(app_dir)
 | 
			
		||||
    shutil.copytree(templ, app_dir)
 | 
			
		||||
    if rel_target_bin != "":
 | 
			
		||||
        shutil.copy(rel_target_bin, app_dir + "/libgodot.ios.release.xcframework/ios-arm64/libgodot.a")
 | 
			
		||||
    if dbg_target_bin != "":
 | 
			
		||||
        shutil.copy(dbg_target_bin, app_dir + "/libgodot.ios.debug.xcframework/ios-arm64/libgodot.a")
 | 
			
		||||
    if rel_target_bin_sim != "":
 | 
			
		||||
        shutil.copy(
 | 
			
		||||
            rel_target_bin_sim, app_dir + "/libgodot.ios.release.xcframework/ios-arm64_x86_64-simulator/libgodot.a"
 | 
			
		||||
        )
 | 
			
		||||
    if dbg_target_bin_sim != "":
 | 
			
		||||
        shutil.copy(
 | 
			
		||||
            dbg_target_bin_sim, app_dir + "/libgodot.ios.debug.xcframework/ios-arm64_x86_64-simulator/libgodot.a"
 | 
			
		||||
        )
 | 
			
		||||
    mvk_path = detect_mvk(env, "ios-arm64")
 | 
			
		||||
    if mvk_path != "":
 | 
			
		||||
        shutil.copytree(mvk_path, app_dir + "/MoltenVK.xcframework")
 | 
			
		||||
 | 
			
		||||
    # ZIP Xcode project bundle.
 | 
			
		||||
    zip_dir = env.Dir("#bin/" + (app_prefix + env.extra_suffix).replace(".", "_")).abspath
 | 
			
		||||
    shutil.make_archive(zip_dir, "zip", root_dir=app_dir)
 | 
			
		||||
    shutil.rmtree(app_dir)
 | 
			
		||||
@@ -1,117 +1,9 @@
 | 
			
		||||
#!/usr/bin/env python
 | 
			
		||||
from misc.utility.scons_hints import *
 | 
			
		||||
 | 
			
		||||
Import("env")
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
import shutil
 | 
			
		||||
import subprocess
 | 
			
		||||
 | 
			
		||||
import platform_macos_builders
 | 
			
		||||
 | 
			
		||||
from platform_methods import get_build_version, lipo
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def generate_bundle(target, source, env):
 | 
			
		||||
    bin_dir = Dir("#bin").abspath
 | 
			
		||||
 | 
			
		||||
    if env.editor_build:
 | 
			
		||||
        # Editor bundle.
 | 
			
		||||
        prefix = "godot." + env["platform"] + "." + env["target"]
 | 
			
		||||
        if env.dev_build:
 | 
			
		||||
            prefix += ".dev"
 | 
			
		||||
        if env["precision"] == "double":
 | 
			
		||||
            prefix += ".double"
 | 
			
		||||
 | 
			
		||||
        # Lipo editor executable.
 | 
			
		||||
        target_bin = lipo(bin_dir + "/" + prefix, env.extra_suffix + env.module_version_string)
 | 
			
		||||
 | 
			
		||||
        # Assemble .app bundle and update version info.
 | 
			
		||||
        app_dir = Dir(
 | 
			
		||||
            "#bin/" + (prefix + env.extra_suffix + env.module_version_string).replace(".", "_") + ".app"
 | 
			
		||||
        ).abspath
 | 
			
		||||
        templ = Dir("#misc/dist/macos_tools.app").abspath
 | 
			
		||||
        if os.path.exists(app_dir):
 | 
			
		||||
            shutil.rmtree(app_dir)
 | 
			
		||||
 | 
			
		||||
        # Create the .app bundle directory itself from scratch so that the creation
 | 
			
		||||
        # date is accurate, but copy the rest of the template over.
 | 
			
		||||
        os.mkdir(app_dir)
 | 
			
		||||
        shutil.copytree(
 | 
			
		||||
            os.path.join(templ, "Contents"),
 | 
			
		||||
            os.path.join(app_dir, "Contents"),
 | 
			
		||||
            ignore=shutil.ignore_patterns("Info.plist"),
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        if not os.path.isdir(app_dir + "/Contents/MacOS"):
 | 
			
		||||
            os.mkdir(app_dir + "/Contents/MacOS")
 | 
			
		||||
        if target_bin != "":
 | 
			
		||||
            shutil.copy(target_bin, app_dir + "/Contents/MacOS/Godot")
 | 
			
		||||
        if "mono" in env.module_version_string:
 | 
			
		||||
            shutil.copytree(Dir("#bin/GodotSharp").abspath, app_dir + "/Contents/Resources/GodotSharp")
 | 
			
		||||
        version = get_build_version(False)
 | 
			
		||||
        short_version = get_build_version(True)
 | 
			
		||||
        with open(Dir("#misc/dist/macos").abspath + "/editor_info_plist.template", "rt", encoding="utf-8") as fin:
 | 
			
		||||
            with open(app_dir + "/Contents/Info.plist", "wt", encoding="utf-8", newline="\n") as fout:
 | 
			
		||||
                for line in fin:
 | 
			
		||||
                    line = line.replace("$version", version)
 | 
			
		||||
                    line = line.replace("$short_version", short_version)
 | 
			
		||||
                    fout.write(line)
 | 
			
		||||
 | 
			
		||||
        # Sign .app bundle.
 | 
			
		||||
        if env["bundle_sign_identity"] != "":
 | 
			
		||||
            sign_command = [
 | 
			
		||||
                "codesign",
 | 
			
		||||
                "-s",
 | 
			
		||||
                env["bundle_sign_identity"],
 | 
			
		||||
                "--deep",
 | 
			
		||||
                "--force",
 | 
			
		||||
                "--options=runtime",
 | 
			
		||||
                "--entitlements",
 | 
			
		||||
            ]
 | 
			
		||||
            if env.dev_build:
 | 
			
		||||
                sign_command += [Dir("#misc/dist/macos").abspath + "/editor_debug.entitlements"]
 | 
			
		||||
            else:
 | 
			
		||||
                sign_command += [Dir("#misc/dist/macos").abspath + "/editor.entitlements"]
 | 
			
		||||
            sign_command += [app_dir]
 | 
			
		||||
            subprocess.run(sign_command)
 | 
			
		||||
 | 
			
		||||
    else:
 | 
			
		||||
        # Template bundle.
 | 
			
		||||
        app_prefix = "godot." + env["platform"]
 | 
			
		||||
        rel_prefix = "godot." + env["platform"] + "." + "template_release"
 | 
			
		||||
        dbg_prefix = "godot." + env["platform"] + "." + "template_debug"
 | 
			
		||||
        if env.dev_build:
 | 
			
		||||
            app_prefix += ".dev"
 | 
			
		||||
            rel_prefix += ".dev"
 | 
			
		||||
            dbg_prefix += ".dev"
 | 
			
		||||
        if env["precision"] == "double":
 | 
			
		||||
            app_prefix += ".double"
 | 
			
		||||
            rel_prefix += ".double"
 | 
			
		||||
            dbg_prefix += ".double"
 | 
			
		||||
 | 
			
		||||
        # Lipo template executables.
 | 
			
		||||
        rel_target_bin = lipo(bin_dir + "/" + rel_prefix, env.extra_suffix + env.module_version_string)
 | 
			
		||||
        dbg_target_bin = lipo(bin_dir + "/" + dbg_prefix, env.extra_suffix + env.module_version_string)
 | 
			
		||||
 | 
			
		||||
        # Assemble .app bundle.
 | 
			
		||||
        app_dir = Dir("#bin/macos_template.app").abspath
 | 
			
		||||
        templ = Dir("#misc/dist/macos_template.app").abspath
 | 
			
		||||
        if os.path.exists(app_dir):
 | 
			
		||||
            shutil.rmtree(app_dir)
 | 
			
		||||
        shutil.copytree(templ, app_dir)
 | 
			
		||||
        if not os.path.isdir(app_dir + "/Contents/MacOS"):
 | 
			
		||||
            os.mkdir(app_dir + "/Contents/MacOS")
 | 
			
		||||
        if rel_target_bin != "":
 | 
			
		||||
            shutil.copy(rel_target_bin, app_dir + "/Contents/MacOS/godot_macos_release.universal")
 | 
			
		||||
        if dbg_target_bin != "":
 | 
			
		||||
            shutil.copy(dbg_target_bin, app_dir + "/Contents/MacOS/godot_macos_debug.universal")
 | 
			
		||||
 | 
			
		||||
        # ZIP .app bundle.
 | 
			
		||||
        zip_dir = Dir("#bin/" + (app_prefix + env.extra_suffix + env.module_version_string).replace(".", "_")).abspath
 | 
			
		||||
        shutil.make_archive(zip_dir, "zip", root_dir=bin_dir, base_dir="macos_template.app")
 | 
			
		||||
        shutil.rmtree(app_dir)
 | 
			
		||||
 | 
			
		||||
Import("env")
 | 
			
		||||
 | 
			
		||||
files = [
 | 
			
		||||
    "os_macos.mm",
 | 
			
		||||
@@ -144,4 +36,4 @@ if env["debug_symbols"] and env["separate_debug_symbols"]:
 | 
			
		||||
    env.AddPostAction(prog, env.Run(platform_macos_builders.make_debug_macos))
 | 
			
		||||
 | 
			
		||||
if env["generate_bundle"]:
 | 
			
		||||
    env.AlwaysBuild(env.CommandNoCache("generate_bundle", prog, env.Run(generate_bundle)))
 | 
			
		||||
    env.AlwaysBuild(env.CommandNoCache("generate_bundle", prog, env.Run(platform_macos_builders.generate_bundle)))
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,113 @@
 | 
			
		||||
"""Functions used to generate source files during build time"""
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
import shutil
 | 
			
		||||
import subprocess
 | 
			
		||||
 | 
			
		||||
from platform_methods import get_build_version, lipo
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def generate_bundle(target, source, env):
 | 
			
		||||
    bin_dir = env.Dir("#bin").abspath
 | 
			
		||||
 | 
			
		||||
    if env.editor_build:
 | 
			
		||||
        # Editor bundle.
 | 
			
		||||
        prefix = "godot." + env["platform"] + "." + env["target"]
 | 
			
		||||
        if env.dev_build:
 | 
			
		||||
            prefix += ".dev"
 | 
			
		||||
        if env["precision"] == "double":
 | 
			
		||||
            prefix += ".double"
 | 
			
		||||
 | 
			
		||||
        # Lipo editor executable.
 | 
			
		||||
        target_bin = lipo(bin_dir + "/" + prefix, env.extra_suffix + env.module_version_string)
 | 
			
		||||
 | 
			
		||||
        # Assemble .app bundle and update version info.
 | 
			
		||||
        app_dir = env.Dir(
 | 
			
		||||
            "#bin/" + (prefix + env.extra_suffix + env.module_version_string).replace(".", "_") + ".app"
 | 
			
		||||
        ).abspath
 | 
			
		||||
        templ = env.Dir("#misc/dist/macos_tools.app").abspath
 | 
			
		||||
        if os.path.exists(app_dir):
 | 
			
		||||
            shutil.rmtree(app_dir)
 | 
			
		||||
 | 
			
		||||
        # Create the .app bundle directory itself from scratch so that the creation
 | 
			
		||||
        # date is accurate, but copy the rest of the template over.
 | 
			
		||||
        os.mkdir(app_dir)
 | 
			
		||||
        shutil.copytree(
 | 
			
		||||
            os.path.join(templ, "Contents"),
 | 
			
		||||
            os.path.join(app_dir, "Contents"),
 | 
			
		||||
            ignore=shutil.ignore_patterns("Info.plist"),
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        if not os.path.isdir(app_dir + "/Contents/MacOS"):
 | 
			
		||||
            os.mkdir(app_dir + "/Contents/MacOS")
 | 
			
		||||
        if target_bin != "":
 | 
			
		||||
            shutil.copy(target_bin, app_dir + "/Contents/MacOS/Godot")
 | 
			
		||||
        if "mono" in env.module_version_string:
 | 
			
		||||
            shutil.copytree(env.Dir("#bin/GodotSharp").abspath, app_dir + "/Contents/Resources/GodotSharp")
 | 
			
		||||
        version = get_build_version(False)
 | 
			
		||||
        short_version = get_build_version(True)
 | 
			
		||||
        with open(env.Dir("#misc/dist/macos").abspath + "/editor_info_plist.template", "rt", encoding="utf-8") as fin:
 | 
			
		||||
            with open(app_dir + "/Contents/Info.plist", "wt", encoding="utf-8", newline="\n") as fout:
 | 
			
		||||
                for line in fin:
 | 
			
		||||
                    line = line.replace("$version", version)
 | 
			
		||||
                    line = line.replace("$short_version", short_version)
 | 
			
		||||
                    fout.write(line)
 | 
			
		||||
 | 
			
		||||
        # Sign .app bundle.
 | 
			
		||||
        if env["bundle_sign_identity"] != "":
 | 
			
		||||
            sign_command = [
 | 
			
		||||
                "codesign",
 | 
			
		||||
                "-s",
 | 
			
		||||
                env["bundle_sign_identity"],
 | 
			
		||||
                "--deep",
 | 
			
		||||
                "--force",
 | 
			
		||||
                "--options=runtime",
 | 
			
		||||
                "--entitlements",
 | 
			
		||||
            ]
 | 
			
		||||
            if env.dev_build:
 | 
			
		||||
                sign_command += [env.Dir("#misc/dist/macos").abspath + "/editor_debug.entitlements"]
 | 
			
		||||
            else:
 | 
			
		||||
                sign_command += [env.Dir("#misc/dist/macos").abspath + "/editor.entitlements"]
 | 
			
		||||
            sign_command += [app_dir]
 | 
			
		||||
            subprocess.run(sign_command)
 | 
			
		||||
 | 
			
		||||
    else:
 | 
			
		||||
        # Template bundle.
 | 
			
		||||
        app_prefix = "godot." + env["platform"]
 | 
			
		||||
        rel_prefix = "godot." + env["platform"] + "." + "template_release"
 | 
			
		||||
        dbg_prefix = "godot." + env["platform"] + "." + "template_debug"
 | 
			
		||||
        if env.dev_build:
 | 
			
		||||
            app_prefix += ".dev"
 | 
			
		||||
            rel_prefix += ".dev"
 | 
			
		||||
            dbg_prefix += ".dev"
 | 
			
		||||
        if env["precision"] == "double":
 | 
			
		||||
            app_prefix += ".double"
 | 
			
		||||
            rel_prefix += ".double"
 | 
			
		||||
            dbg_prefix += ".double"
 | 
			
		||||
 | 
			
		||||
        # Lipo template executables.
 | 
			
		||||
        rel_target_bin = lipo(bin_dir + "/" + rel_prefix, env.extra_suffix + env.module_version_string)
 | 
			
		||||
        dbg_target_bin = lipo(bin_dir + "/" + dbg_prefix, env.extra_suffix + env.module_version_string)
 | 
			
		||||
 | 
			
		||||
        # Assemble .app bundle.
 | 
			
		||||
        app_dir = env.Dir("#bin/macos_template.app").abspath
 | 
			
		||||
        templ = env.Dir("#misc/dist/macos_template.app").abspath
 | 
			
		||||
        if os.path.exists(app_dir):
 | 
			
		||||
            shutil.rmtree(app_dir)
 | 
			
		||||
        shutil.copytree(templ, app_dir)
 | 
			
		||||
        if not os.path.isdir(app_dir + "/Contents/MacOS"):
 | 
			
		||||
            os.mkdir(app_dir + "/Contents/MacOS")
 | 
			
		||||
        if rel_target_bin != "":
 | 
			
		||||
            shutil.copy(rel_target_bin, app_dir + "/Contents/MacOS/godot_macos_release.universal")
 | 
			
		||||
        if dbg_target_bin != "":
 | 
			
		||||
            shutil.copy(dbg_target_bin, app_dir + "/Contents/MacOS/godot_macos_debug.universal")
 | 
			
		||||
 | 
			
		||||
        # ZIP .app bundle.
 | 
			
		||||
        zip_dir = env.Dir(
 | 
			
		||||
            "#bin/" + (app_prefix + env.extra_suffix + env.module_version_string).replace(".", "_")
 | 
			
		||||
        ).abspath
 | 
			
		||||
        shutil.make_archive(zip_dir, "zip", root_dir=bin_dir, base_dir="macos_template.app")
 | 
			
		||||
        shutil.rmtree(app_dir)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def make_debug_macos(target, source, env):
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										44
									
								
								platform/platform_builders.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								platform/platform_builders.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
"""Functions used to generate source files during build time"""
 | 
			
		||||
 | 
			
		||||
from pathlib import Path
 | 
			
		||||
 | 
			
		||||
import methods
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def export_icon_builder(target, source, env):
 | 
			
		||||
    src_path = Path(str(source[0]))
 | 
			
		||||
    src_name = src_path.stem
 | 
			
		||||
    platform = src_path.parent.parent.stem
 | 
			
		||||
 | 
			
		||||
    with open(str(source[0]), "r") as file:
 | 
			
		||||
        svg = file.read()
 | 
			
		||||
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        file.write(
 | 
			
		||||
            f"""\
 | 
			
		||||
inline constexpr const char *_{platform}_{src_name}_svg = {methods.to_raw_cstring(svg)};
 | 
			
		||||
"""
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def register_platform_apis_builder(target, source, env):
 | 
			
		||||
    platforms = source[0].read()
 | 
			
		||||
    api_inc = "\n".join([f'#include "{p}/api/api.h"' for p in platforms])
 | 
			
		||||
    api_reg = "\n\t".join([f"register_{p}_api();" for p in platforms])
 | 
			
		||||
    api_unreg = "\n\t".join([f"unregister_{p}_api();" for p in platforms])
 | 
			
		||||
    with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
        file.write(
 | 
			
		||||
            f"""\
 | 
			
		||||
#include "register_platform_apis.h"
 | 
			
		||||
 | 
			
		||||
{api_inc}
 | 
			
		||||
 | 
			
		||||
void register_platform_apis() {{
 | 
			
		||||
	{api_reg}
 | 
			
		||||
}}
 | 
			
		||||
 | 
			
		||||
void unregister_platform_apis() {{
 | 
			
		||||
	{api_unreg}
 | 
			
		||||
}}
 | 
			
		||||
"""
 | 
			
		||||
        )
 | 
			
		||||
		Reference in New Issue
	
	Block a user