Fabio Alessandrelli 2024-01-18 20:20:51 +00:00 committed by GitHub
commit 9d840ce0e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 106 additions and 7 deletions

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
import json import json
import os
import re import re
import shutil import shutil
from pathlib import Path from pathlib import Path
@ -70,7 +71,15 @@ def generate_wrappers(target):
f.write(txt) f.write(txt)
def get_file_list(api_filepath, output_dir, headers=False, sources=False): def is_class_included(class_name, build_profile):
if "enabled_classes" in build_profile:
return class_name in build_profile["enabled_classes"]
if "disabled_classes" in build_profile:
return class_name not in build_profile["disabled_classes"]
return True
def get_file_list(api_filepath, output_dir, headers=False, sources=False, build_profile={}):
api = {} api = {}
files = [] files = []
with open(api_filepath, encoding="utf-8") as api_file: with open(api_filepath, encoding="utf-8") as api_file:
@ -97,6 +106,8 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
files.append(str(source_filename.as_posix())) files.append(str(source_filename.as_posix()))
for engine_class in api["classes"]: for engine_class in api["classes"]:
if not is_class_included(engine_class["name"], build_profile):
continue
# Generate code for the ClassDB singleton under a different name. # Generate code for the ClassDB singleton under a different name.
if engine_class["name"] == "ClassDB": if engine_class["name"] == "ClassDB":
engine_class["name"] = "ClassDBSingleton" engine_class["name"] = "ClassDBSingleton"
@ -137,12 +148,64 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
return files return files
def print_file_list(api_filepath, output_dir, headers=False, sources=False): def print_file_list(api_filepath, output_dir, headers=False, sources=False, build_profile={}):
print(*get_file_list(api_filepath, output_dir, headers, sources), sep=";", end=None) print(*get_file_list(api_filepath, output_dir, headers, sources, build_profile), sep=";", end=None)
def scons_parse_build_profile(env, api_filepath):
if not "build_profile" in env:
return {}
profile_filename = env["build_profile"]
if not os.path.isabs(profile_filename):
profile_filename = os.path.join(env.Dir("#").abspath, profile_filename)
print("Using feature build profile: " + profile_filename)
with open(profile_filename, encoding="utf-8") as profile_file:
profile = json.load(profile_file)
with open(api_filepath, encoding="utf-8") as api_file:
api = json.load(api_file)
parents = {}
childs = {}
for engine_class in api["classes"]:
parent = engine_class.get("inherits", "")
child = engine_class["name"]
parents[child] = parent
if parent == "":
continue
if parent not in childs:
childs[parent] = childs.get(parent, [])
childs[parent].append(child)
included = []
front = list(profile.get("enabled_classes", []))
while len(front):
cls = front.pop()
if cls in included:
continue
included.append(cls)
parent = parents.get(cls, "")
if parent:
front.append(parent)
excluded = []
front = list(profile.get("disabled_classes", []))
while len(front):
cls = front.pop()
if cls in excluded:
continue
excluded.append(cls)
front.concat(childs.get(cls, []))
return {
"enabled_classes": included,
"disabled_classes": excluded,
}
def scons_emit_files(target, source, env): def scons_emit_files(target, source, env):
files = [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True)] build_profile = scons_parse_build_profile(env, str(source[0]))
files = [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True, build_profile)]
env.Clean(target, files) env.Clean(target, files)
env["godot_cpp_gen_dir"] = target[0].abspath env["godot_cpp_gen_dir"] = target[0].abspath
return files, source return files, source
@ -159,7 +222,9 @@ def scons_generate_bindings(target, source, env):
return None return None
def generate_bindings(api_filepath, use_template_get_node, bits="64", precision="single", output_dir="."): def generate_bindings(
api_filepath, use_template_get_node, bits="64", precision="single", output_dir=".", build_profile={}
):
api = None api = None
target_dir = Path(output_dir) / "gen" target_dir = Path(output_dir) / "gen"
@ -177,7 +242,7 @@ def generate_bindings(api_filepath, use_template_get_node, bits="64", precision=
generate_version_header(api, target_dir) generate_version_header(api, target_dir)
generate_global_constant_binds(api, target_dir) generate_global_constant_binds(api, target_dir)
generate_builtin_bindings(api, target_dir, real_t + "_" + bits) generate_builtin_bindings(api, target_dir, real_t + "_" + bits)
generate_engine_classes_bindings(api, target_dir, use_template_get_node) generate_engine_classes_bindings(api, target_dir, use_template_get_node, build_profile)
generate_utility_functions(api, target_dir) generate_utility_functions(api, target_dir)
@ -1070,7 +1135,7 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
return "\n".join(result) return "\n".join(result)
def generate_engine_classes_bindings(api, output_dir, use_template_get_node): def generate_engine_classes_bindings(api, output_dir, use_template_get_node, build_profile={}):
global engine_classes global engine_classes
global singletons global singletons
global native_structures global native_structures
@ -1083,6 +1148,8 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
# First create map of classes and singletons. # First create map of classes and singletons.
for class_api in api["classes"]: for class_api in api["classes"]:
if not is_class_included(class_api["name"], build_profile):
continue
# Generate code for the ClassDB singleton under a different name. # Generate code for the ClassDB singleton under a different name.
if class_api["name"] == "ClassDB": if class_api["name"] == "ClassDB":
class_api["name"] = "ClassDBSingleton" class_api["name"] = "ClassDBSingleton"
@ -1102,6 +1169,9 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
singletons.append(singleton["name"]) singletons.append(singleton["name"])
for class_api in api["classes"]: for class_api in api["classes"]:
if not is_class_included(class_api["name"], build_profile):
continue
# Check used classes for header include. # Check used classes for header include.
used_classes = set() used_classes = set()
fully_used_classes = set() fully_used_classes = set()

20
test/build_profile.json Normal file
View File

@ -0,0 +1,20 @@
{
"enabled_classes": [
"Control",
"Viewport",
"InputEventKey",
"TileMap",
"Label",
"ClassDB",
"Texture2D",
"Material",
"StyleBox",
"SceneTree",
"Mesh",
"Window",
"FileAccess",
"DirAccess",
"Shader",
"Multimesh"
]
}

View File

@ -198,6 +198,15 @@ def options(opts, env):
) )
) )
opts.Add(
PathVariable(
"build_profile",
"Path to a file containing a feature build profile",
default=env.get("build_profile", None),
validator=validate_file,
)
)
# Add platform options # Add platform options
for pl in platforms: for pl in platforms:
tool = Tool(pl, toolpath=["tools"]) tool = Tool(pl, toolpath=["tools"])