Skip to content

Commit

Permalink
Single Compilation Unit build.
Browse files Browse the repository at this point in the history
Adds support for simple SCU build (DEV_ENABLED only).
This speeds up compilation by compiling multiple cpp files within a single translation unit.
  • Loading branch information
lawnjelly committed Jun 6, 2023
1 parent 543750a commit b69c8b4
Show file tree
Hide file tree
Showing 29 changed files with 531 additions and 137 deletions.
12 changes: 12 additions & 0 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ _helper_module("modules.modules_builders", "modules/modules_builders.py")
import methods
import glsl_builders
import gles3_builders
import scu_builders
from platform_methods import architectures, architecture_aliases

if ARGUMENTS.get("target", "editor") == "editor":
Expand Down Expand Up @@ -223,6 +224,7 @@ opts.Add(
"",
)
opts.Add(BoolVariable("use_precise_math_checks", "Math checks use very precise epsilon (debug option)", False))
opts.Add(EnumVariable("scu_build", "Use single compilation unit build", "none", ("none", "dev", "all")))

# Thirdparty libraries
opts.Add(BoolVariable("builtin_certs", "Use the built-in SSL certificates bundles", True))
Expand Down Expand Up @@ -428,14 +430,20 @@ if env_base.debug_features:
# to give *users* extra debugging information for their game development.
env_base.Append(CPPDEFINES=["DEBUG_ENABLED"])


if env_base.dev_build:
# DEV_ENABLED enables *engine developer* code which should only be compiled for those
# working on the engine itself.
env_base.Append(CPPDEFINES=["DEV_ENABLED"])
env_base["use_scu"] = env_base["scu_build"] in ("dev", "all")
else:
# Disable assert() for production targets (only used in thirdparty code).
env_base.Append(CPPDEFINES=["NDEBUG"])

# SCU builds currently use a lot of compiler memory
# in release builds, so disallow outside of DEV builds unless "all" is set.
env_base["use_scu"] = env_base["scu_build"] == "all"

# SCons speed optimization controlled by the `fast_unsafe` option, which provide
# more than 10 s speed up for incremental rebuilds.
# Unsafe as they reduce the certainty of rebuilding all changed files, so it's
Expand Down Expand Up @@ -550,6 +558,10 @@ if selected_platform in platform_list:
# LTO "auto" means we handle the preferred option in each platform detect.py.
env["lto"] = ARGUMENTS.get("lto", "auto")

# Run SCU file generation script if in a SCU build.
if env["use_scu"]:
methods.set_scu_folders(scu_builders.generate_scu_files(env["verbose"], env_base.dev_build == False))

# Must happen after the flags' definition, as configure is when most flags
# are actually handled to change compile options, etc.
detect.configure(env)
Expand Down
5 changes: 2 additions & 3 deletions editor/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,8 @@ if env.editor_build:
reg_exporters_inc = '#include "register_exporters.h"\n\n'
reg_exporters = "void register_exporters() {\n"
for e in env.platform_exporters:
# Glob all .cpp files in export folder
files = Glob("#platform/" + e + "/export/" + "*.cpp")
env.add_source_files(env.editor_sources, files)
# 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'
Expand Down
2 changes: 1 addition & 1 deletion editor/editor_about.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
#include "core/version.h"

// The metadata key used to store and retrieve the version text to copy to the clipboard.
static const String META_TEXT_TO_COPY = "text_to_copy";
const String EditorAbout::META_TEXT_TO_COPY = "text_to_copy";

void EditorAbout::_theme_changed() {
const Ref<Font> font = get_theme_font(SNAME("source"), SNAME("EditorFonts"));
Expand Down
2 changes: 2 additions & 0 deletions editor/editor_about.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
class EditorAbout : public AcceptDialog {
GDCLASS(EditorAbout, AcceptDialog);

static const String META_TEXT_TO_COPY;

private:
void _license_tree_selected();
void _version_button_pressed();
Expand Down
8 changes: 4 additions & 4 deletions editor/editor_inspector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,14 @@
#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) {
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<String> sections = p_property_path.split("/");
for (int i = 0; i < sections.size(); i++) {
if (p_filter.is_subsequence_ofn(EditorPropertyNameProcessor::get_singleton()->process_name(sections[i], p_style))) {
const Vector<String> prop_sections = p_property_path.split("/");
for (int i = 0; i < prop_sections.size(); i++) {
if (p_filter.is_subsequence_ofn(EditorPropertyNameProcessor::get_singleton()->process_name(prop_sections[i], p_style))) {
return true;
}
}
Expand Down
1 change: 1 addition & 0 deletions editor/editor_inspector.h
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,7 @@ class EditorInspector : public ScrollContainer {
void _property_deleted(const String &p_path);
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, Ref<Resource> p_resource);
void _property_selected(const String &p_path, int p_focusable);
Expand Down
16 changes: 8 additions & 8 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6760,28 +6760,28 @@ EditorNode::EditorNode() {
switch (display_scale) {
case 0:
// Try applying a suitable display scale automatically.
editor_set_scale(EditorSettings::get_singleton()->get_auto_display_scale());
EditorScale::set_scale(EditorSettings::get_singleton()->get_auto_display_scale());
break;
case 1:
editor_set_scale(0.75);
EditorScale::set_scale(0.75);
break;
case 2:
editor_set_scale(1.0);
EditorScale::set_scale(1.0);
break;
case 3:
editor_set_scale(1.25);
EditorScale::set_scale(1.25);
break;
case 4:
editor_set_scale(1.5);
EditorScale::set_scale(1.5);
break;
case 5:
editor_set_scale(1.75);
EditorScale::set_scale(1.75);
break;
case 6:
editor_set_scale(2.0);
EditorScale::set_scale(2.0);
break;
default:
editor_set_scale(EDITOR_GET("interface/editor/custom_display_scale"));
EditorScale::set_scale(EDITOR_GET("interface/editor/custom_display_scale"));
break;
}
}
Expand Down
4 changes: 2 additions & 2 deletions editor/editor_quick_open.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"

static Rect2i prev_rect = Rect2i();
static bool was_showed = false;
Rect2i EditorQuickOpen::prev_rect = Rect2i();
bool EditorQuickOpen::was_showed = false;

void EditorQuickOpen::popup_dialog(const String &p_base, bool p_enable_multi, bool p_dont_clear) {
base_type = p_base;
Expand Down
3 changes: 3 additions & 0 deletions editor/editor_quick_open.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
class EditorQuickOpen : public ConfirmationDialog {
GDCLASS(EditorQuickOpen, ConfirmationDialog);

static Rect2i prev_rect;
static bool was_showed;

LineEdit *search_box = nullptr;
Tree *search_options = nullptr;
String base_type;
Expand Down
12 changes: 5 additions & 7 deletions editor/editor_scale.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,12 @@

#include "editor_scale.h"

#include "core/os/os.h"
float EditorScale::_scale = 1.0f;

static float scale = 1.0;

void editor_set_scale(float p_scale) {
scale = p_scale;
void EditorScale::set_scale(float p_scale) {
_scale = p_scale;
}

float editor_get_scale() {
return scale;
float EditorScale::get_scale() {
return _scale;
}
11 changes: 8 additions & 3 deletions editor/editor_scale.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,14 @@
#ifndef EDITOR_SCALE_H
#define EDITOR_SCALE_H

void editor_set_scale(float p_scale);
float editor_get_scale();
class EditorScale {
static float _scale;

#define EDSCALE (editor_get_scale())
public:
static void set_scale(float p_scale);
static float get_scale();
};

#define EDSCALE (EditorScale::get_scale())

#endif // EDITOR_SCALE_H
2 changes: 1 addition & 1 deletion editor/plugins/text_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ void TextEditor::_convert_case(CodeTextEditor::CaseStyle p_case) {
code_editor->convert_case(p_case);
}

static ScriptEditorBase *create_editor(const Ref<Resource> &p_resource) {
ScriptEditorBase *TextEditor::create_editor(const Ref<Resource> &p_resource) {
if (Object::cast_to<TextFile>(*p_resource) || Object::cast_to<JSON>(*p_resource)) {
return memnew(TextEditor);
}
Expand Down
2 changes: 2 additions & 0 deletions editor/plugins/text_editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
class TextEditor : public ScriptEditorBase {
GDCLASS(TextEditor, ScriptEditorBase);

static ScriptEditorBase *create_editor(const Ref<Resource> &p_resource);

private:
CodeTextEditor *code_editor = nullptr;

Expand Down
4 changes: 2 additions & 2 deletions editor/plugins/visual_shader_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4982,7 +4982,7 @@ void VisualShaderEditor::_preview_size_changed() {
preview_vbox->set_custom_minimum_size(preview_window->get_size());
}

static ShaderLanguage::DataType _get_global_shader_uniform_type(const StringName &p_variable) {
static ShaderLanguage::DataType _visual_shader_editor_get_global_shader_uniform_type(const StringName &p_variable) {
RS::GlobalShaderParameterType gvt = RS::get_singleton()->global_shader_parameter_get_type(p_variable);
return (ShaderLanguage::DataType)RS::global_shader_uniform_type_get_shader_datatype(gvt);
}
Expand All @@ -5001,7 +5001,7 @@ void VisualShaderEditor::_update_preview() {
info.functions = ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(visual_shader->get_mode()));
info.render_modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(visual_shader->get_mode()));
info.shader_types = ShaderTypes::get_singleton()->get_types();
info.global_shader_uniform_type_func = _get_global_shader_uniform_type;
info.global_shader_uniform_type_func = _visual_shader_editor_get_global_shader_uniform_type;

ShaderLanguage sl;

Expand Down
16 changes: 8 additions & 8 deletions editor/project_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2763,28 +2763,28 @@ ProjectManager::ProjectManager() {
switch (display_scale) {
case 0:
// Try applying a suitable display scale automatically.
editor_set_scale(EditorSettings::get_singleton()->get_auto_display_scale());
EditorScale::set_scale(EditorSettings::get_singleton()->get_auto_display_scale());
break;
case 1:
editor_set_scale(0.75);
EditorScale::set_scale(0.75);
break;
case 2:
editor_set_scale(1.0);
EditorScale::set_scale(1.0);
break;
case 3:
editor_set_scale(1.25);
EditorScale::set_scale(1.25);
break;
case 4:
editor_set_scale(1.5);
EditorScale::set_scale(1.5);
break;
case 5:
editor_set_scale(1.75);
EditorScale::set_scale(1.75);
break;
case 6:
editor_set_scale(2.0);
EditorScale::set_scale(2.0);
break;
default:
editor_set_scale(EDITOR_GET("interface/editor/custom_display_scale"));
EditorScale::set_scale(EDITOR_GET("interface/editor/custom_display_scale"));
break;
}
EditorFileDialog::get_icon_func = &ProjectManager::_file_dialog_get_icon;
Expand Down
84 changes: 82 additions & 2 deletions methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,23 @@
from collections import OrderedDict
from collections.abc import Mapping
from typing import Iterator
from pathlib import Path
from os.path import normpath, basename

# 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 add_source_files(self, sources, files):

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 isinstance(files, (str, bytes)):
# Keep SCons project-absolute path as they are (no wildcard support)
Expand All @@ -23,7 +37,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
Expand All @@ -35,6 +49,72 @@ 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] + " "
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["use_scu"] 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:
Expand Down
2 changes: 1 addition & 1 deletion scene/animation/animation_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -941,7 +941,7 @@ void AnimationTree::_clear_playing_caches() {
playing_caches.clear();
}

static void _call_object(Object *p_object, const StringName &p_method, const Vector<Variant> &p_params, bool p_deferred) {
void AnimationTree::_call_object(Object *p_object, const StringName &p_method, const Vector<Variant> &p_params, bool p_deferred) {
// Separate function to use alloca() more efficiently
const Variant **argptrs = (const Variant **)alloca(sizeof(const Variant **) * p_params.size());
const Variant *args = p_params.ptr();
Expand Down
2 changes: 2 additions & 0 deletions scene/animation/animation_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ class AnimationNodeEndState : public AnimationRootNode {
class AnimationTree : public Node {
GDCLASS(AnimationTree, Node);

void _call_object(Object *p_object, const StringName &p_method, const Vector<Variant> &p_params, bool p_deferred);

public:
enum AnimationProcessCallback {
ANIMATION_PROCESS_PHYSICS,
Expand Down
Loading

0 comments on commit b69c8b4

Please sign in to comment.