diff --git a/SConstruct b/SConstruct index 42f8fc0b28..621e7bc250 100644 --- a/SConstruct +++ b/SConstruct @@ -124,6 +124,7 @@ opts.Add(BoolVariable("generate_template_get_node", "Generate a template version opts.Add(BoolVariable("build_library", "Build the godot-cpp library.", True)) opts.Add(EnumVariable("precision", "Set the floating-point precision level", "single", ("single", "double"))) +opts.Add("build_profile", "Path to a file containing a feature build profile", "") # Add platform options tools = {} diff --git a/binding_generator.py b/binding_generator.py index d04c6987b0..015b7decd5 100644 --- a/binding_generator.py +++ b/binding_generator.py @@ -3,9 +3,18 @@ import json import re import shutil +import sys from pathlib import Path +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 generate_mod_version(argcount, const=False, returns=False): s = """ #define MODBIND$VER($RETTYPE m_name$ARG) \\ @@ -70,7 +79,7 @@ def generate_wrappers(target): f.write(txt) -def get_file_list(api_filepath, output_dir, headers=False, sources=False): +def get_file_list(api_filepath, output_dir, headers=False, sources=False, build_profile={}): api = {} files = [] 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())) for engine_class in api["classes"]: + if not is_class_included(engine_class["name"], build_profile): + continue # TODO: Properly setup this singleton since it conflicts with ClassDB in the bindings. if engine_class["name"] == "ClassDB": continue @@ -134,31 +145,49 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False): 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={}): end = ";" - for f in get_file_list(api_filepath, output_dir, headers, sources): + for f in get_file_list(api_filepath, output_dir, headers, sources, build_profile): print(f, end=end) +def scons_parse_build_profile(env): + if env["build_profile"] != "": + print("Using feature build profile: " + env["build_profile"]) + import json + + path = env.File(env["build_profile"]).abspath + try: + ft = json.load(open(path)) + return ft + except: + print("Error opening feature build profile: " + path) + sys.exit(255) + return {} + + 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) + 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["godot_cpp_gen_dir"] = target[0].abspath return files, source def scons_generate_bindings(target, source, env): + build_profile = scons_parse_build_profile(env) generate_bindings( str(source[0]), env["generate_template_get_node"], "32" if "32" in env["arch"] else "64", env["precision"], env["godot_cpp_gen_dir"], + build_profile, ) 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 target_dir = Path(output_dir) / "gen" @@ -175,7 +204,7 @@ def generate_bindings(api_filepath, use_template_get_node, bits="64", precision= generate_global_constants(api, target_dir) generate_global_constant_binds(api, target_dir) 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) @@ -1023,7 +1052,7 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl 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 singletons global native_structures @@ -1036,6 +1065,8 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node): # First create map of classes and singletons. for class_api in api["classes"]: + if not is_class_included(class_api["name"], build_profile): + continue # TODO: Properly setup this singleton since it conflicts with ClassDB in the bindings. if class_api["name"] == "ClassDB": continue @@ -1048,6 +1079,8 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node): singletons.append(singleton["name"]) for class_api in api["classes"]: + if not is_class_included(class_api["name"], build_profile): + continue # TODO: Properly setup this singleton since it conflicts with ClassDB in the bindings. if class_api["name"] == "ClassDB": continue @@ -1161,7 +1194,7 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node): register_engine_classes_filename = Path(output_dir) / "src" / "register_engine_classes.cpp" with register_engine_classes_filename.open("w+", encoding="utf-8") as source_file: - source_file.write(generate_register_engine_classes_source(api)) + source_file.write(generate_register_engine_classes_source(api, build_profile)) for native_struct in api["native_structures"]: struct_name = native_struct["name"] @@ -1585,11 +1618,13 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us return "\n".join(result) -def generate_register_engine_classes_source(api): +def generate_register_engine_classes_source(api, build_profile): includes = [] registrations = [] for class_api in api["classes"]: + if not is_class_included(class_api["name"], build_profile): + continue if class_api["name"] == "ClassDB": continue diff --git a/test/build_profile.json b/test/build_profile.json new file mode 100644 index 0000000000..c50e81e2c8 --- /dev/null +++ b/test/build_profile.json @@ -0,0 +1,131 @@ +{ + "enabled_classes": [ + "Control", + "Image", + "InputEvent", + "InputEventKey", + "Viewport", + "Object", + "FileAccess", + "RefCounted", + "EditorPlugin", + "Node", + "Window", + "Tween", + "SceneTree", + "Texture2D", + "MultiplayerAPI", + "PopupMenu", + "Button", + "EditorUndoRedoManager", + "Script", + "EditorTranslationParserPlugin", + "EditorImportPlugin", + "EditorSceneFormatImporter", + "EditorDebuggerPlugin", + "Camera3D", + "ConfigFile", + "ScriptCreateDialog", + "EditorInspectorPlugin", + "EditorNode3DGizmoPlugin", + "EditorScenePostImportPlugin", + "EditorExportPlugin", + "EditorResourceConversionPlugin", + "EditorInterface", + "WorkerThreadPool", + "XMLParser", + "Texture", + "Resource", + "BaseButton", + "CanvasItem", + "ButtonGroup", + "Material", + "Theme", + "StyleBox", + "Font", + "Shortcut", + "Mesh", + "World2D", + "MultiMesh", + "TextServer", + "Environment", + "Node3D", + "World3D", + "Node3DGizmo", + "CameraAttributes", + "Sky", + "Shader", + "TriangleMesh", + "PhysicsDirectSpaceState2D", + "ConvexPolygonShape3D", + "ConcavePolygonShape3D", + "Shape3D", + "ConfirmationDialog", + "PhysicsShapeQueryParameters2D", + "PhysicsShapeQueryParameters3D", + "EditorExportPlatform", + "AcceptDialog", + "PhysicsRayQueryParameters2D", + "ArrayMesh", + "Camera2D", + "Node2D", + "MethodTweener", + "ViewportTexture", + "Label", + "LabelSettings", + "Popup", + "UndoRedo", + "EditorNode3DGizmo", + "EditorInspector", + "ScriptEditor", + "VBoxContainer", + "EditorSettings", + "EditorSelection", + "EditorResourcePreview", + "EditorPaths", + "EditorFileSystem", + "EditorCommandPalette", + "ResourceImporter", + "EditorDebuggerSession", + "StandardMaterial3D", + "FileSystemDock", + "BoxContainer", + "Container", + "PanelContainer", + "ScriptEditorBase", + "EditorResourcePreviewGenerator", + "ScrollContainer", + "EditorFileSystemDirectory", + "EditorFileSystem", + "SkinReference", + "BaseMaterial3D", + "EditorSyntaxHighlighter", + "VScrollBar", + "HScrollBar", + "ScrollBar", + "Range", + "EditorResourceTooltipPlugin", + "PhysicsPointQueryParameters2D", + "PropertyTweener", + "CallbackTweener", + "Tweener", + "Skin", + "IntervalTweener", + "MultiplayerPeer", + "InputEventWithModifiers", + "SyntaxHighlighter", + "InputEventFromWindow", + "TextureRect", + "PhysicsDirectSpaceState3D", + "PacketPeer", + "TextEdit", + "SceneTreeTimer", + "PackedScene", + "MainLoop", + "SceneState", + "PhysicsRayQueryParameters3D", + "PhysicsPointQueryParameters3D", + "OS", + "Semaphore" + ] +}