Skip to content

Commit

Permalink
SCons: Generate all scripts natively
Browse files Browse the repository at this point in the history
  • Loading branch information
Repiteo committed May 7, 2024
1 parent 55b8724 commit 34fb3f7
Show file tree
Hide file tree
Showing 8 changed files with 361 additions and 280 deletions.
13 changes: 5 additions & 8 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,14 @@ _helper_module("platform_methods", "platform_methods.py")
_helper_module("version", "version.py")
_helper_module("core.core_builders", "core/core_builders.py")
_helper_module("main.main_builders", "main/main_builders.py")
_helper_module("modules.modules_builders", "modules/modules_builders.py")

# Local
import methods
import glsl_builders
import gles3_builders
import scu_builders
from methods import print_warning, print_error
from platform_methods import architectures, architecture_aliases, generate_export_icons
from platform_methods import architectures, architecture_aliases

if ARGUMENTS.get("target", "editor") == "editor":
_helper_module("editor.editor_builders", "editor/editor_builders.py")
Expand Down Expand Up @@ -107,7 +106,6 @@ for x in sorted(glob.glob("platform/*")):

if os.path.exists(x + "/export/export.cpp"):
platform_exporters.append(platform_name)
generate_export_icons(x, platform_name)
if os.path.exists(x + "/api/api.cpp"):
platform_apis.append(platform_name)
if detect.can_build():
Expand Down Expand Up @@ -428,7 +426,7 @@ for name, path in modules_detected.items():
sys.path.remove(path)
sys.modules.pop("config")

methods.write_modules(modules_detected)
env.modules_detected = modules_detected

# Update the environment again after all the module options are added.
opts.Update(env)
Expand Down Expand Up @@ -544,23 +542,22 @@ env.Append(CFLAGS=env.get("cflags", "").split())
env.Append(LINKFLAGS=env.get("linkflags", "").split())

# Feature build profile
disabled_classes = []
env.disabled_classes = []
if env["build_profile"] != "":
print('Using feature build profile: "{}"'.format(env["build_profile"]))
import json

try:
ft = json.load(open(env["build_profile"]))
if "disabled_classes" in ft:
disabled_classes = ft["disabled_classes"]
env.disabled_classes = ft["disabled_classes"]
if "disabled_build_options" in ft:
dbo = ft["disabled_build_options"]
for c in dbo:
env[c] = dbo[c]
except:
print_error('Failed to open feature build profile: "{}"'.format(env["build_profile"]))
Exit(255)
methods.write_disabled_classes(disabled_classes)

# Platform specific flags.
# These can sometimes override default options.
Expand Down Expand Up @@ -926,7 +923,7 @@ if env.editor_build:
print_error("Not all modules required by editor builds are enabled.")
Exit(255)

methods.generate_version_header(env.module_version_string)
env.version_info = methods.get_version_info(env.module_version_string)

env["PROGSUFFIX_WRAP"] = suffix + env.module_version_string + ".console" + env["PROGSUFFIX"]
env["PROGSUFFIX"] = suffix + env.module_version_string + env["PROGSUFFIX"]
Expand Down
129 changes: 91 additions & 38 deletions core/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,9 @@ Import("env")

import core_builders
import methods

env.core_sources = []


# Generate AES256 script encryption key
import os

txt = "0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0"
if "SCRIPT_AES256_ENCRYPTION_KEY" in os.environ:
key = os.environ["SCRIPT_AES256_ENCRYPTION_KEY"]
ec_valid = True
if len(key) != 64:
ec_valid = False
else:
txt = ""
for i in range(len(key) >> 1):
if i > 0:
txt += ","
txts = "0x" + key[i * 2 : i * 2 + 2]
try:
int(txts, 16)
except Exception:
ec_valid = False
txt += txts
if not ec_valid:
methods.print_error(
f'Invalid AES256 encryption key, not 64 hexadecimal characters: "{key}".\n'
"Unset 'SCRIPT_AES256_ENCRYPTION_KEY' in your environment "
"or make sure that it contains exactly 64 hexadecimal characters."
)
Exit(255)


script_encryption_key_contents = (
'#include "core/config/project_settings.h"\nuint8_t script_encryption_key[32]={' + txt + "};\n"
)

methods.write_file_if_needed("script_encryption_key.gen.cpp", script_encryption_key_contents)
env.core_sources = []

# Add required thirdparty code.

Expand Down Expand Up @@ -193,8 +158,96 @@ env.core_sources += thirdparty_obj
# Godot source files

env.add_source_files(env.core_sources, "*.cpp")
env.add_source_files(env.core_sources, "script_encryption_key.gen.cpp")
env.add_source_files(env.core_sources, "version_hash.gen.cpp")


# Generate disabled classes
def disabled_class_builder(target, source, env):
with methods.generated_wrapper(target) as file:
for c in source[0].read():
cs = c.strip()
if cs != "":
file.write(f"#define ClassDB_Disable_{cs} 1")


env.CommandNoCache("disabled_classes.gen.h", env.Value(env.disabled_classes), env.Run(disabled_class_builder))


# Generate version info
def version_info_builder(target, source, env):
with methods.generated_wrapper(target) as file:
file.write(
"""\
#define VERSION_SHORT_NAME "{short_name}"
#define VERSION_NAME "{name}"
#define VERSION_MAJOR {major}
#define VERSION_MINOR {minor}
#define VERSION_PATCH {patch}
#define VERSION_STATUS "{status}"
#define VERSION_BUILD "{build}"
#define VERSION_MODULE_CONFIG "{module_config}"
#define VERSION_WEBSITE "{website}"
#define VERSION_DOCS_BRANCH "{docs_branch}"
#define VERSION_DOCS_URL "https://docs.godotengine.org/en/" VERSION_DOCS_BRANCH
""".format(
**env.version_info
)
)


env.CommandNoCache("version_generated.gen.h", "#version.py", env.Run(version_info_builder))


# Generate version hash
def version_hash_builder(target, source, env):
with methods.generated_wrapper(target) as file:
file.write(
"""\
#include "core/version.h"
const char *const VERSION_HASH = "{git_hash}";
const uint64_t VERSION_TIMESTAMP = {git_timestamp};
""".format(
**env.version_info
)
)


gen_hash = env.CommandNoCache(
"version_hash.gen.cpp", env.Value(env.version_info["git_hash"]), env.Run(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(target) 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))
env.add_source_files(env.core_sources, gen_encrypt)


# Certificates
env.Depends(
Expand Down
83 changes: 50 additions & 33 deletions editor/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,59 @@ import editor_builders
import methods


def _make_doc_data_class_path(to_path):
file_path = os.path.join(to_path, "doc_data_class_path.gen.h")

class_path_data = ""
class_path_data += "static const int _doc_data_class_path_count = " + str(len(env.doc_class_path)) + ";\n"
class_path_data += "struct _DocDataClassPath { const char* name; const char* path; };\n"
class_path_data += (
"static const _DocDataClassPath _doc_data_class_paths[" + str(len(env.doc_class_path) + 1) + "] = {\n"
)
for c in sorted(env.doc_class_path):
class_path_data += '\t{"' + c + '", "' + env.doc_class_path[c] + '"},\n'
class_path_data += "\t{nullptr, nullptr}\n"
class_path_data += "};\n"

methods.write_file_if_needed(file_path, class_path_data)


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(target) as file:
file.write(
f"""\
static const int _doc_data_class_path_count = {len(paths)};
struct _DocDataClassPath {{
const char *name;
const char *path;
}};
static const _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))

# Register exporters
reg_exporters_inc = '#include "register_exporters.h"\n\n'
reg_exporters = "void register_exporters() {\n"
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(target) 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)
)
for e in env.platform_exporters:
# Add all .cpp files in export folder
env.add_source_files(env.editor_sources, "../platform/" + e + "/export/" + "*.cpp")

reg_exporters += "\tregister_" + e + "_exporter();\n"
reg_exporters_inc += '#include "platform/' + e + '/export/export.h"\n'
reg_exporters += "}\n\n"
reg_exporters += "void register_exporter_types() {\n"
for e in env.platform_exporters:
reg_exporters += "\tregister_" + e + "_exporter_types();\n"
reg_exporters += "}\n"

methods.write_file_if_needed("register_exporters.gen.cpp", reg_exporters_inc + reg_exporters)
env.add_source_files(env.editor_sources, f"../platform/{e}/export/*.cpp")

# Core API documentation.
docs = []
Expand All @@ -61,8 +80,6 @@ if env.editor_build:
else:
docs += Glob(d + "/*.xml") # Custom.

_make_doc_data_class_path(env.Dir("#editor").abspath)

docs = sorted(docs)
env.Depends("#editor/doc_data_compressed.gen.h", docs)
env.CommandNoCache(
Expand Down Expand Up @@ -115,7 +132,7 @@ if env.editor_build:
)

env.add_source_files(env.editor_sources, "*.cpp")
env.add_source_files(env.editor_sources, "register_exporters.gen.cpp")
env.add_source_files(env.editor_sources, gen_exporters)

SConscript("debugger/SCsub")
SConscript("export/SCsub")
Expand Down
Loading

0 comments on commit 34fb3f7

Please sign in to comment.