From 43e181a00ab39671a3bb0b2d0302e25313f18aef Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Sun, 27 Nov 2022 08:34:07 +0000 Subject: [PATCH] Single Compilation Unit build. Adds support for simple SCU build. This speeds up compilation by compiling multiple cpp files within a single translation unit. --- SConstruct | 6 + core/color_names.inc | 2 + core/make_binders.py | 3 +- drivers/gles2/rasterizer_scene_gles2.cpp | 4 +- drivers/gles2/rasterizer_scene_gles2.h | 2 + drivers/gles2/shader_gles2.cpp | 2 +- drivers/gles2/shader_gles2.h | 2 + drivers/gles3/rasterizer_scene_gles3.cpp | 8 +- drivers/gles3/rasterizer_scene_gles3.h | 7 + editor/SCsub | 9 +- editor/editor_about.cpp | 2 +- editor/editor_about.h | 1 + editor/editor_inspector.cpp | 28 +- editor/editor_inspector.h | 1 + editor/editor_sectioned_inspector.cpp | 28 +- editor/editor_sectioned_inspector.h | 1 + editor/plugins/text_editor.cpp | 2 +- editor/plugins/text_editor.h | 1 + main/tests/test_string.cpp | 2 + main/tests/test_theme.cpp | 2 + methods.py | 84 ++++- .../visual_script/visual_script_editor.cpp | 27 +- .../visual_script_func_nodes.cpp | 29 +- modules/visual_script/visual_script_nodes.cpp | 10 +- modules/visual_script/visual_script_nodes.h | 6 + .../visual_script_yield_nodes.cpp | 25 +- scene/gui/box_container.cpp | 6 - scene/gui/box_container.h | 6 + scene/gui/line_edit.cpp | 2 +- scene/gui/line_edit.h | 1 + scu_builders.py | 351 ++++++++++++++++++ servers/physics/joints/hinge_joint_sw.cpp | 4 +- servers/physics/joints/hinge_joint_sw.h | 3 + servers/physics/joints/slider_joint_sw.cpp | 2 +- servers/physics/joints/slider_joint_sw.h | 3 + 35 files changed, 542 insertions(+), 130 deletions(-) create mode 100755 scu_builders.py diff --git a/SConstruct b/SConstruct index 2e23711c124..e8f000b334c 100644 --- a/SConstruct +++ b/SConstruct @@ -14,6 +14,7 @@ from collections import OrderedDict # Local import methods import gles_builders +import scu_builders from platform_methods import run_in_subprocess # scan possible build platforms @@ -155,6 +156,7 @@ opts.Add(BoolVariable("disable_advanced_gui", "Disable advanced GUI nodes and be opts.Add(BoolVariable("no_editor_splash", "Don't use the custom splash screen for the editor", True)) opts.Add("system_certs_path", "Use this path as SSL certificates default for editor (for package maintainers)", "") opts.Add(BoolVariable("use_precise_math_checks", "Math checks use very precise epsilon (debug option)", False)) +opts.Add(BoolVariable("scu_build", "Use single compilation unit build", False)) opts.Add( EnumVariable( "rids", @@ -442,6 +444,10 @@ if selected_platform in platform_list: "for an optimized template with debug features)." ) + # Run SCU file generation script if in a SCU build. + if env["scu_build"]: + methods.set_scu_folders(scu_builders.generate_scu_files(env["verbose"], env_base["target"] != "debug")) + # Must happen after the flags' definition, as configure is when most flags # are actually handled to change compile options, etc. detect.configure(env) diff --git a/core/color_names.inc b/core/color_names.inc index b1a2b99616a..4bbd8bec812 100644 --- a/core/color_names.inc +++ b/core/color_names.inc @@ -1,4 +1,6 @@ // Names from https://en.wikipedia.org/wiki/X11_color_names +#pragma once + #include "core/map.h" static Map _named_colors; diff --git a/core/make_binders.py b/core/make_binders.py index ecc5fdd709d..50880f11b74 100644 --- a/core/make_binders.py +++ b/core/make_binders.py @@ -86,7 +86,8 @@ MethodBind* create_method_bind($ifret R$ $ifnoret void$ (T::*p_method)($arg, P@$ #endif """ -template = """ +template = """#pragma once + #ifndef TYPED_METHOD_BIND $iftempl template<$ $ifret class R$ $ifretargs ,$ $arg, class P@$ $iftempl >$ class MethodBind$argc$$ifret R$$ifconst C$ : public MethodBind { diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index c685deddabf..edc7130181f 100644 --- a/drivers/gles2/rasterizer_scene_gles2.cpp +++ b/drivers/gles2/rasterizer_scene_gles2.cpp @@ -53,7 +53,7 @@ #endif #endif -static const GLenum _cube_side_enum[6] = { +const GLenum RasterizerSceneGLES2::_cube_side_enum[6] = { GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_X, @@ -1332,7 +1332,7 @@ void RasterizerSceneGLES2::_fill_render_list(InstanceBase **p_cull_result, int p } } -static const GLenum gl_primitive[] = { +const GLenum RasterizerSceneGLES2::gl_primitive[] = { GL_POINTS, GL_LINES, GL_LINE_STRIP, diff --git a/drivers/gles2/rasterizer_scene_gles2.h b/drivers/gles2/rasterizer_scene_gles2.h index 7e5976d948b..3ab55c8ae96 100644 --- a/drivers/gles2/rasterizer_scene_gles2.h +++ b/drivers/gles2/rasterizer_scene_gles2.h @@ -89,6 +89,8 @@ public: private: uint32_t _light_counter; + static const GLenum gl_primitive[]; + static const GLenum _cube_side_enum[6]; public: RasterizerStorageGLES2 *storage; diff --git a/drivers/gles2/shader_gles2.cpp b/drivers/gles2/shader_gles2.cpp index 45a8d4bec98..82c1fb7e7b2 100644 --- a/drivers/gles2/shader_gles2.cpp +++ b/drivers/gles2/shader_gles2.cpp @@ -126,7 +126,7 @@ static void _display_error_with_code(const String &p_error, const Vector &p_sections, const char *const *const p_src[], const int p_flag_single_column = 0); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index ae4efaa6472..7e63a8bbecc 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -43,20 +43,6 @@ #include "scene/property_utils.h" #include "scene/resources/packed_scene.h" -static bool _property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style) { - if (p_property_path.findn(p_filter) != -1) { - return true; - } - - const Vector sections = p_property_path.split("/"); - for (int i = 0; i < sections.size(); i++) { - if (p_filter.is_subsequence_ofi(EditorPropertyNameProcessor::get_singleton()->process_name(sections[i], p_style))) { - return true; - } - } - return false; -} - Size2 EditorProperty::get_minimum_size() const { Size2 ms; Ref font = get_font("font", "Tree"); @@ -1232,6 +1218,20 @@ EditorInspectorSection::~EditorInspectorSection() { Ref EditorInspector::inspector_plugins[MAX_PLUGINS]; int EditorInspector::inspector_plugin_count = 0; +bool EditorInspector::_property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style) { + if (p_property_path.findn(p_filter) != -1) { + return true; + } + + const Vector sections = p_property_path.split("/"); + for (int i = 0; i < sections.size(); i++) { + if (p_filter.is_subsequence_ofi(EditorPropertyNameProcessor::get_singleton()->process_name(sections[i], p_style))) { + return true; + } + } + return false; +} + EditorProperty *EditorInspector::instantiate_property_editor(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage) { for (int i = inspector_plugin_count - 1; i >= 0; i--) { inspector_plugins[i]->parse_property(p_object, p_type, p_path, p_hint, p_hint_text, p_usage); diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index 8726e2cadae..f68dd240ff1 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -319,6 +319,7 @@ class EditorInspector : public ScrollContainer { void _property_keyed_with_value(const String &p_path, const Variant &p_value, bool p_advance); void _property_checked(const String &p_path, bool p_checked); void _property_pinned(const String &p_path, bool p_pinned); + bool _property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style); void _resource_selected(const String &p_path, RES p_resource); void _property_selected(const String &p_path, int p_focusable); diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp index 7fe772120b9..94d4776349c 100644 --- a/editor/editor_sectioned_inspector.cpp +++ b/editor/editor_sectioned_inspector.cpp @@ -34,20 +34,6 @@ #include "editor_scale.h" #include "editor_settings.h" -static bool _property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style) { - if (p_property_path.findn(p_filter) != -1) { - return true; - } - - const Vector sections = p_property_path.split("/"); - for (int i = 0; i < sections.size(); i++) { - if (p_filter.is_subsequence_ofi(EditorPropertyNameProcessor::get_singleton()->process_name(sections[i], p_style))) { - return true; - } - } - return false; -} - class SectionedInspectorFilter : public Object { GDCLASS(SectionedInspectorFilter, Object); @@ -145,6 +131,20 @@ public: } }; +bool SectionedInspector::_property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style) { + if (p_property_path.findn(p_filter) != -1) { + return true; + } + + const Vector sections = p_property_path.split("/"); + for (int i = 0; i < sections.size(); i++) { + if (p_filter.is_subsequence_ofi(EditorPropertyNameProcessor::get_singleton()->process_name(sections[i], p_style))) { + return true; + } + } + return false; +} + void SectionedInspector::_bind_methods() { ClassDB::bind_method("_section_selected", &SectionedInspector::_section_selected); ClassDB::bind_method("_search_changed", &SectionedInspector::_search_changed); diff --git a/editor/editor_sectioned_inspector.h b/editor/editor_sectioned_inspector.h index 8ddef7e9485..7ce1e810a52 100644 --- a/editor/editor_sectioned_inspector.h +++ b/editor/editor_sectioned_inspector.h @@ -55,6 +55,7 @@ class SectionedInspector : public HSplitContainer { void _section_selected(); void _search_changed(const String &p_what); + bool _property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style); protected: void _notification(int p_what); diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp index 0908ec1796d..b1844391658 100644 --- a/editor/plugins/text_editor.cpp +++ b/editor/plugins/text_editor.cpp @@ -494,7 +494,7 @@ void TextEditor::_bind_methods() { ClassDB::bind_method("_prepare_edit_menu", &TextEditor::_prepare_edit_menu); } -static ScriptEditorBase *create_editor(const RES &p_resource) { +ScriptEditorBase *TextEditor::create_editor(const RES &p_resource) { if (Object::cast_to(*p_resource)) { return memnew(TextEditor); } diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h index 02db16996c0..162a3c49fb4 100644 --- a/editor/plugins/text_editor.h +++ b/editor/plugins/text_editor.h @@ -96,6 +96,7 @@ private: BOOKMARK_GOTO_PREV, BOOKMARK_REMOVE_ALL, }; + static ScriptEditorBase *create_editor(const RES &p_resource); protected: static void _bind_methods(); diff --git a/main/tests/test_string.cpp b/main/tests/test_string.cpp index 814dfbb4af5..f773650752d 100644 --- a/main/tests/test_string.cpp +++ b/main/tests/test_string.cpp @@ -1330,3 +1330,5 @@ MainLoop *test() { return nullptr; } } // namespace TestString + +#undef CHECK diff --git a/main/tests/test_theme.cpp b/main/tests/test_theme.cpp index 8b624a05274..8af59a074a0 100644 --- a/main/tests/test_theme.cpp +++ b/main/tests/test_theme.cpp @@ -301,3 +301,5 @@ MainLoop *test() { return nullptr; } } // namespace TestTheme + +#undef CHECK diff --git a/methods.py b/methods.py index 2873b760b7d..394ba8a2795 100644 --- a/methods.py +++ b/methods.py @@ -13,8 +13,23 @@ from SCons.Script import ARGUMENTS from SCons.Script import Glob from SCons.Variables.BoolVariable import _text2bool +from pathlib import Path +from os.path import normpath, basename -def add_source_files(self, sources, files): +# Get the "Godot" folder name ahead of time +base_folder_path = str(os.path.abspath(Path(__file__).parent)) + "/" +base_folder_only = os.path.basename(os.path.normpath(base_folder_path)) +# Listing all the folders we have converted +# for SCU in scu_builders.py +_scu_folders = set() + + +def set_scu_folders(scu_folders): + global _scu_folders + _scu_folders = scu_folders + + +def add_source_files_orig(self, sources, files, allow_gen=False): # Convert string to list of absolute paths (including expanding wildcard) if isbasestring(files): # Keep SCons project-absolute path as they are (no wildcard support) @@ -29,7 +44,7 @@ def add_source_files(self, sources, files): skip_gen_cpp = "*" in files dir_path = self.Dir(".").abspath files = sorted(glob.glob(dir_path + "/" + files)) - if skip_gen_cpp: + if skip_gen_cpp and not allow_gen: files = [f for f in files if not f.endswith(".gen.cpp")] # Add each path as compiled Object following environment (self) configuration @@ -41,6 +56,71 @@ def add_source_files(self, sources, files): sources.append(obj) +# The section name is used for checking +# the hash table to see whether the folder +# is included in the SCU build. +# It will be something like "core/math". +def _find_scu_section_name(subdir): + section_path = os.path.abspath(subdir) + "/" + + folders = [] + folder = "" + + for i in range(8): + folder = os.path.dirname(section_path) + folder = os.path.basename(folder) + if folder == base_folder_only: + break + folders += [folder] + section_path += "../" + section_path = os.path.abspath(section_path) + "/" + + section_name = "" + for n in range(len(folders)): + section_name += folders[len(folders) - n - 1] + if n != (len(folders) - 1): + section_name += "/" + + return section_name + + +def add_source_files_scu(self, sources, files, allow_gen=False): + if self["scu_build"] and isinstance(files, str): + if "*." not in files: + return False + + # If the files are in a subdirectory, we want to create the scu gen + # files inside this subdirectory. + subdir = os.path.dirname(files) + if subdir != "": + subdir += "/" + + section_name = _find_scu_section_name(subdir) + # if the section name is in the hash table? + # i.e. is it part of the SCU build? + global _scu_folders + if section_name not in (_scu_folders): + return False + + if self["verbose"]: + print("SCU building " + section_name) + + # Add all the gen.cpp files in the SCU directory + add_source_files_orig(self, sources, subdir + ".scu/scu_*.gen.cpp", True) + return True + return False + + +# Either builds the folder using the SCU system, +# or reverts to regular build. +def add_source_files(self, sources, files, allow_gen=False): + if not add_source_files_scu(self, sources, files, allow_gen): + # Wraps the original function when scu build is not active. + add_source_files_orig(self, sources, files, allow_gen) + return False + return True + + def disable_warnings(self): # 'self' is the environment if self.msvc: diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index ec0e0bc1b55..5cb8ea0e659 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -2227,27 +2227,6 @@ bool VisualScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant & return false; } -static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref