1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-12 13:20:55 +00:00

Make build profile project detection also set build options

This commit is contained in:
Michael Alexsander
2025-03-06 15:42:10 -03:00
parent e45cc68092
commit 454e4f817c
28 changed files with 786 additions and 82 deletions

View File

@@ -30,6 +30,7 @@
#include "editor_build_profile.h"
#include "core/config/project_settings.h"
#include "core/io/json.h"
#include "editor/editor_file_system.h"
#include "editor/editor_node.h"
@@ -41,36 +42,60 @@
#include "scene/gui/line_edit.h"
#include "scene/gui/separator.h"
#include "modules/modules_enabled.gen.h" // For mono.
const char *EditorBuildProfile::build_option_identifiers[BUILD_OPTION_MAX] = {
// This maps to SCons build options.
"disable_3d",
"disable_2d_physics",
"disable_3d_physics",
"disable_navigation",
"disable_navigation_2d",
"disable_navigation_3d",
"disable_xr",
"rendering_device", // FIXME: there's no scons option to disable rendering device
"opengl3",
"module_openxr_enabled",
"wayland",
"x11",
"rendering_device", // FIXME: There's no scons option to disable rendering device.
"forward_plus_renderer",
"forward_mobile_renderer",
"vulkan",
"d3d12",
"metal",
"opengl3",
"disable_physics_2d",
"module_godot_physics_2d_enabled",
"disable_physics_3d",
"module_godot_physics_3d_enabled",
"module_jolt_physics_enabled",
"module_text_server_fb_enabled",
"module_text_server_adv_enabled",
"module_freetype_enabled",
"brotli",
"graphite",
"module_msdfgen_enabled"
"module_msdfgen_enabled",
};
const bool EditorBuildProfile::build_option_disabled_by_default[BUILD_OPTION_MAX] = {
// This maps to SCons build options.
false, // 3D
false, // PHYSICS_2D
false, // PHYSICS_3D
false, // NAVIGATION
false, // NAVIGATION_2D
false, // NAVIGATION_3D
false, // XR
false, // OPENXR
false, // WAYLAND
false, // X11
false, // RENDERING_DEVICE
false, // OPENGL
false, // FORWARD_RENDERER
false, // MOBILE_RENDERER
false, // VULKAN
false, // D3D12
false, // METAL
false, // OPENGL
false, // PHYSICS_2D
false, // PHYSICS_GODOT_2D
false, // PHYSICS_3D
false, // PHYSICS_GODOT_3D
false, // PHYSICS_JOLT
true, // TEXT_SERVER_FALLBACK
false, // TEXT_SERVER_COMPLEX
false, // TEXT_SERVER_ADVANCED
false, // DYNAMIC_FONTS
false, // WOFF2_FONTS
false, // GRAPHITE_FONTS
@@ -80,38 +105,215 @@ const bool EditorBuildProfile::build_option_disabled_by_default[BUILD_OPTION_MAX
const bool EditorBuildProfile::build_option_disable_values[BUILD_OPTION_MAX] = {
// This maps to SCons build options.
true, // 3D
true, // PHYSICS_2D
true, // PHYSICS_3D
true, // NAVIGATION
true, // NAVIGATION_2D
true, // NAVIGATION_3D
true, // XR
false, // OPENXR
false, // WAYLAND
false, // X11
false, // RENDERING_DEVICE
false, // OPENGL
false, // FORWARD_RENDERER
false, // MOBILE_RENDERER
false, // VULKAN
false, // D3D12
false, // METAL
false, // OPENGL
true, // PHYSICS_2D
false, // PHYSICS_GODOT_2D
true, // PHYSICS_3D
false, // PHYSICS_GODOT_3D
false, // PHYSICS_JOLT
false, // TEXT_SERVER_FALLBACK
false, // TEXT_SERVER_COMPLEX
false, // TEXT_SERVER_ADVANCED
false, // DYNAMIC_FONTS
false, // WOFF2_FONTS
false, // GRAPHITE_FONTS
false, // MSDFGEN
};
// Options that require some resource explicitly asking for them when detecting from the project.
const bool EditorBuildProfile::build_option_explicit_use[BUILD_OPTION_MAX] = {
false, // 3D
false, // NAVIGATION_2D
false, // NAVIGATION_3D
false, // XR
false, // OPENXR
false, // WAYLAND
false, // X11
false, // RENDERING_DEVICE
false, // FORWARD_RENDERER
false, // MOBILE_RENDERER
false, // VULKAN
false, // D3D12
false, // METAL
false, // OPENGL
false, // PHYSICS_2D
false, // PHYSICS_GODOT_2D
false, // PHYSICS_3D
false, // PHYSICS_GODOT_3D
false, // PHYSICS_JOLT
false, // TEXT_SERVER_FALLBACK
false, // TEXT_SERVER_ADVANCED
false, // DYNAMIC_FONTS
false, // WOFF2_FONTS
false, // GRAPHITE_FONTS
true, // MSDFGEN
};
const EditorBuildProfile::BuildOptionCategory EditorBuildProfile::build_option_category[BUILD_OPTION_MAX] = {
BUILD_OPTION_CATEGORY_GENERAL, // 3D
BUILD_OPTION_CATEGORY_GENERAL, // PHYSICS_2D
BUILD_OPTION_CATEGORY_GENERAL, // PHYSICS_3D
BUILD_OPTION_CATEGORY_GENERAL, // NAVIGATION
BUILD_OPTION_CATEGORY_GENERAL, // NAVIGATION_2D
BUILD_OPTION_CATEGORY_GENERAL, // NAVIGATION_3D
BUILD_OPTION_CATEGORY_GENERAL, // XR
BUILD_OPTION_CATEGORY_GENERAL, // RENDERING_DEVICE
BUILD_OPTION_CATEGORY_GENERAL, // OPENGL
BUILD_OPTION_CATEGORY_GENERAL, // VULKAN
BUILD_OPTION_CATEGORY_GENERAL, // OPENXR
BUILD_OPTION_CATEGORY_GENERAL, // WAYLAND
BUILD_OPTION_CATEGORY_GENERAL, // X11
BUILD_OPTION_CATEGORY_GRAPHICS, // RENDERING_DEVICE
BUILD_OPTION_CATEGORY_GRAPHICS, // FORWARD_RENDERER
BUILD_OPTION_CATEGORY_GRAPHICS, // MOBILE_RENDERER
BUILD_OPTION_CATEGORY_GRAPHICS, // VULKAN
BUILD_OPTION_CATEGORY_GRAPHICS, // D3D12
BUILD_OPTION_CATEGORY_GRAPHICS, // METAL
BUILD_OPTION_CATEGORY_GRAPHICS, // OPENGL
BUILD_OPTION_CATEGORY_PHYSICS, // PHYSICS_2D
BUILD_OPTION_CATEGORY_PHYSICS, // PHYSICS_GODOT_2D
BUILD_OPTION_CATEGORY_PHYSICS, // PHYSICS_3D
BUILD_OPTION_CATEGORY_PHYSICS, // PHYSICS_GODOT_3D
BUILD_OPTION_CATEGORY_PHYSICS, // PHYSICS_JOLT
BUILD_OPTION_CATEGORY_TEXT_SERVER, // TEXT_SERVER_FALLBACK
BUILD_OPTION_CATEGORY_TEXT_SERVER, // TEXT_SERVER_COMPLEX
BUILD_OPTION_CATEGORY_TEXT_SERVER, // TEXT_SERVER_ADVANCED
BUILD_OPTION_CATEGORY_TEXT_SERVER, // DYNAMIC_FONTS
BUILD_OPTION_CATEGORY_TEXT_SERVER, // WOFF2_FONTS
BUILD_OPTION_CATEGORY_TEXT_SERVER, // GRAPHITE_FONTS
BUILD_OPTION_CATEGORY_TEXT_SERVER, // MSDFGEN
};
// Can't assign HashMaps to a HashMap at declaration, so do it in the class' constructor.
HashMap<EditorBuildProfile::BuildOption, HashMap<String, LocalVector<Variant>>> EditorBuildProfile::build_option_settings = {};
/* clang-format off */
const HashMap<EditorBuildProfile::BuildOption, LocalVector<EditorBuildProfile::BuildOption>> EditorBuildProfile::build_option_dependencies = {
{ BUILD_OPTION_OPENXR, {
BUILD_OPTION_XR,
} },
{ BUILD_OPTION_FORWARD_RENDERER, {
BUILD_OPTION_RENDERING_DEVICE,
} },
{ BUILD_OPTION_MOBILE_RENDERER, {
BUILD_OPTION_RENDERING_DEVICE,
} },
{ BUILD_OPTION_VULKAN, {
BUILD_OPTION_FORWARD_RENDERER,
BUILD_OPTION_MOBILE_RENDERER,
} },
{ BUILD_OPTION_D3D12, {
BUILD_OPTION_FORWARD_RENDERER,
BUILD_OPTION_MOBILE_RENDERER,
} },
{ BUILD_OPTION_METAL, {
BUILD_OPTION_FORWARD_RENDERER,
BUILD_OPTION_MOBILE_RENDERER,
} },
{ BUILD_OPTION_PHYSICS_GODOT_2D, {
BUILD_OPTION_PHYSICS_2D,
} },
{ BUILD_OPTION_PHYSICS_GODOT_3D, {
BUILD_OPTION_PHYSICS_3D,
} },
{ BUILD_OPTION_PHYSICS_JOLT, {
BUILD_OPTION_PHYSICS_3D,
} },
{ BUILD_OPTION_DYNAMIC_FONTS, {
BUILD_OPTION_TEXT_SERVER_ADVANCED,
} },
{ BUILD_OPTION_WOFF2_FONTS, {
BUILD_OPTION_TEXT_SERVER_ADVANCED,
} },
{ BUILD_OPTION_GRAPHITE_FONTS, {
BUILD_OPTION_TEXT_SERVER_ADVANCED,
} },
};
const HashMap<EditorBuildProfile::BuildOption, LocalVector<String>> EditorBuildProfile::build_option_classes = {
{ BUILD_OPTION_3D, {
"Node3D",
} },
{ BUILD_OPTION_NAVIGATION_2D, {
"NavigationAgent2D",
"NavigationLink2D",
"NavigationMeshSourceGeometryData2D",
"NavigationObstacle2D"
"NavigationPolygon",
"NavigationRegion2D",
} },
{ BUILD_OPTION_NAVIGATION_3D, {
"NavigationAgent3D",
"NavigationLink3D",
"NavigationMeshSourceGeometryData3D",
"NavigationObstacle3D",
"NavigationRegion3D",
} },
{ BUILD_OPTION_XR, {
"XRBodyModifier3D",
"XRBodyTracker",
"XRControllerTracker",
"XRFaceModifier3D",
"XRFaceTracker",
"XRHandModifier3D",
"XRHandTracker",
"XRInterface",
"XRInterfaceExtension",
"XRNode3D",
"XROrigin3D",
"XRPose",
"XRPositionalTracker",
"XRServer",
"XRTracker",
"XRVRS",
} },
{ BUILD_OPTION_RENDERING_DEVICE, {
"RenderingDevice",
} },
{ BUILD_OPTION_PHYSICS_2D, {
"CollisionObject2D",
"CollisionPolygon2D",
"CollisionShape2D",
"Joint2D",
"PhysicsServer2D",
"PhysicsServer2DManager",
"ShapeCast2D",
"RayCast2D",
"TouchScreenButton",
} },
{ BUILD_OPTION_PHYSICS_3D, {
"CollisionObject3D",
"CollisionPolygon3D",
"CollisionShape3D",
"CSGShape3D",
"GPUParticlesAttractor3D",
"GPUParticlesCollision3D",
"Joint3D",
"PhysicalBoneSimulator3D",
"PhysicsServer3D",
"PhysicsServer3DManager",
"PhysicsServer3DRenderingServerHandler",
"RayCast3D",
"SoftBody3D",
"SpringArm3D",
"SpringBoneCollision3D",
"SpringBoneSimulator3D",
"VehicleWheel3D",
} },
{ BUILD_OPTION_TEXT_SERVER_ADVANCED, {
"CanvasItem",
"Label3D",
"TextServerAdvanced",
} },
};
/* clang-format on */
void EditorBuildProfile::set_disable_class(const StringName &p_class, bool p_disabled) {
if (p_disabled) {
disabled_classes.insert(p_class);
@@ -159,6 +361,17 @@ bool EditorBuildProfile::get_build_option_disable_value(BuildOption p_build_opti
return build_option_disable_values[p_build_option];
}
bool EditorBuildProfile::get_build_option_explicit_use(BuildOption p_build_option) {
ERR_FAIL_INDEX_V(p_build_option, BUILD_OPTION_MAX, false);
return build_option_explicit_use[p_build_option];
}
void EditorBuildProfile::reset_build_options() {
for (int i = 0; i < EditorBuildProfile::BUILD_OPTION_MAX; i++) {
build_options_disabled[i] = build_option_disabled_by_default[i];
}
}
void EditorBuildProfile::set_force_detect_classes(const String &p_classes) {
force_detect_classes = p_classes;
}
@@ -171,13 +384,24 @@ String EditorBuildProfile::get_build_option_name(BuildOption p_build_option) {
ERR_FAIL_INDEX_V(p_build_option, BUILD_OPTION_MAX, String());
const char *build_option_names[BUILD_OPTION_MAX] = {
TTRC("3D Engine"),
TTRC("2D Physics"),
TTRC("3D Physics"),
TTRC("Navigation"),
TTRC("Navigation (2D)"),
TTRC("Navigation (3D)"),
TTRC("XR"),
TTRC("OpenXR"),
TTRC("Wayland"),
TTRC("X11"),
TTRC("RenderingDevice"),
TTRC("OpenGL"),
TTRC("Forward+ Renderer"),
TTRC("Mobile Renderer"),
TTRC("Vulkan"),
TTRC("D3D12"),
TTRC("Metal"),
TTRC("OpenGL"),
TTRC("Physics Server (2D)"),
TTRC("Godot Physics (2D)"),
TTRC("Physics Server (3D)"),
TTRC("Godot Physics (3D)"),
TTRC("Jolt Physics"),
TTRC("Text Server: Fallback"),
TTRC("Text Server: Advanced"),
TTRC("TTF, OTF, Type 1, WOFF1 Fonts"),
@@ -193,13 +417,24 @@ String EditorBuildProfile::get_build_option_description(BuildOption p_build_opti
const char *build_option_descriptions[BUILD_OPTION_MAX] = {
TTRC("3D Nodes as well as RenderingServer access to 3D features."),
TTRC("2D Physics nodes and PhysicsServer2D."),
TTRC("3D Physics nodes and PhysicsServer3D."),
TTRC("Navigation, both 2D and 3D."),
TTRC("Navigation Server and capabilities for 2D."),
TTRC("Navigation Server and capabilities for 3D."),
TTRC("XR (AR and VR)."),
TTRC("RenderingDevice based rendering (if disabled, the OpenGL back-end is required)."),
TTRC("OpenGL back-end (if disabled, the RenderingDevice back-end is required)."),
TTRC("Vulkan back-end of RenderingDevice."),
TTRC("OpenXR standard implementation (requires XR to be enabled)."),
TTRC("Wayland display (Linux only)."),
TTRC("X11 display (Linux only)."),
TTRC("RenderingDevice based rendering (if disabled, the OpenGL backend is required)."),
TTRC("Forward+ renderer for advanced 3D graphics."),
TTRC("Mobile renderer for less advanced 3D graphics."),
TTRC("Vulkan backend of RenderingDevice."),
TTRC("Direct3D 12 backend of RenderingDevice."),
TTRC("Metal backend of RenderingDevice (Apple arm64 only)."),
TTRC("OpenGL backend (if disabled, the RenderingDevice backend is required)."),
TTRC("Physics Server and capabilities for 2D."),
TTRC("Godot Physics backend (2D)."),
TTRC("Physics Server and capabilities for 3D."),
TTRC("Godot Physics backend (3D)."),
TTRC("Jolt Physics backend (3D only)."),
TTRC("Fallback implementation of Text Server\nSupports basic text layouts."),
TTRC("Text Server implementation powered by ICU and HarfBuzz libraries.\nSupports complex text layouts, BiDi, and contextual OpenType font features."),
TTRC("TrueType, OpenType, Type 1, and WOFF1 font format support using FreeType library (if disabled, WOFF2 support is also disabled)."),
@@ -211,16 +446,38 @@ String EditorBuildProfile::get_build_option_description(BuildOption p_build_opti
return TTRGET(build_option_descriptions[p_build_option]);
}
String EditorBuildProfile::get_build_option_identifier(BuildOption p_build_option) {
ERR_FAIL_INDEX_V(p_build_option, BUILD_OPTION_MAX, String());
return build_option_identifiers[p_build_option];
}
EditorBuildProfile::BuildOptionCategory EditorBuildProfile::get_build_option_category(BuildOption p_build_option) {
ERR_FAIL_INDEX_V(p_build_option, BUILD_OPTION_MAX, BUILD_OPTION_CATEGORY_GENERAL);
return build_option_category[p_build_option];
}
LocalVector<EditorBuildProfile::BuildOption> EditorBuildProfile::get_build_option_dependencies(BuildOption p_build_option) {
ERR_FAIL_INDEX_V(p_build_option, BUILD_OPTION_MAX, LocalVector<EditorBuildProfile::BuildOption>());
return build_option_dependencies.has(p_build_option) ? build_option_dependencies[p_build_option] : LocalVector<EditorBuildProfile::BuildOption>();
}
HashMap<String, LocalVector<Variant>> EditorBuildProfile::get_build_option_settings(BuildOption p_build_option) {
ERR_FAIL_INDEX_V(p_build_option, BUILD_OPTION_MAX, (HashMap<String, LocalVector<Variant>>()));
return build_option_settings.has(p_build_option) ? build_option_settings[p_build_option] : HashMap<String, LocalVector<Variant>>();
}
LocalVector<String> EditorBuildProfile::get_build_option_classes(BuildOption p_build_option) {
ERR_FAIL_INDEX_V(p_build_option, BUILD_OPTION_MAX, LocalVector<String>());
return build_option_classes.has(p_build_option) ? build_option_classes[p_build_option] : LocalVector<String>();
}
String EditorBuildProfile::get_build_option_category_name(BuildOptionCategory p_build_option_category) {
ERR_FAIL_INDEX_V(p_build_option_category, BUILD_OPTION_CATEGORY_MAX, String());
const char *build_option_subcategories[BUILD_OPTION_CATEGORY_MAX]{
TTRC("General Features:"),
TTRC("Graphics and Rendering:"),
TTRC("Physics Systems:"),
TTRC("Text Rendering and Font Options:"),
};
@@ -332,13 +589,24 @@ void EditorBuildProfile::_bind_methods() {
ClassDB::bind_method(D_METHOD("load_from_file", "path"), &EditorBuildProfile::load_from_file);
BIND_ENUM_CONSTANT(BUILD_OPTION_3D);
BIND_ENUM_CONSTANT(BUILD_OPTION_PHYSICS_2D);
BIND_ENUM_CONSTANT(BUILD_OPTION_PHYSICS_3D);
BIND_ENUM_CONSTANT(BUILD_OPTION_NAVIGATION);
BIND_ENUM_CONSTANT(BUILD_OPTION_NAVIGATION_2D);
BIND_ENUM_CONSTANT(BUILD_OPTION_NAVIGATION_3D);
BIND_ENUM_CONSTANT(BUILD_OPTION_XR);
BIND_ENUM_CONSTANT(BUILD_OPTION_OPENXR);
BIND_ENUM_CONSTANT(BUILD_OPTION_WAYLAND);
BIND_ENUM_CONSTANT(BUILD_OPTION_X11);
BIND_ENUM_CONSTANT(BUILD_OPTION_RENDERING_DEVICE);
BIND_ENUM_CONSTANT(BUILD_OPTION_OPENGL);
BIND_ENUM_CONSTANT(BUILD_OPTION_FORWARD_RENDERER);
BIND_ENUM_CONSTANT(BUILD_OPTION_MOBILE_RENDERER);
BIND_ENUM_CONSTANT(BUILD_OPTION_VULKAN);
BIND_ENUM_CONSTANT(BUILD_OPTION_D3D12);
BIND_ENUM_CONSTANT(BUILD_OPTION_METAL);
BIND_ENUM_CONSTANT(BUILD_OPTION_OPENGL);
BIND_ENUM_CONSTANT(BUILD_OPTION_PHYSICS_2D);
BIND_ENUM_CONSTANT(BUILD_OPTION_PHYSICS_GODOT_2D);
BIND_ENUM_CONSTANT(BUILD_OPTION_PHYSICS_3D);
BIND_ENUM_CONSTANT(BUILD_OPTION_PHYSICS_GODOT_3D);
BIND_ENUM_CONSTANT(BUILD_OPTION_PHYSICS_JOLT);
BIND_ENUM_CONSTANT(BUILD_OPTION_TEXT_SERVER_FALLBACK);
BIND_ENUM_CONSTANT(BUILD_OPTION_TEXT_SERVER_ADVANCED);
BIND_ENUM_CONSTANT(BUILD_OPTION_DYNAMIC_FONTS);
@@ -348,14 +616,78 @@ void EditorBuildProfile::_bind_methods() {
BIND_ENUM_CONSTANT(BUILD_OPTION_MAX);
BIND_ENUM_CONSTANT(BUILD_OPTION_CATEGORY_GENERAL);
BIND_ENUM_CONSTANT(BUILD_OPTION_CATEGORY_GRAPHICS);
BIND_ENUM_CONSTANT(BUILD_OPTION_CATEGORY_PHYSICS);
BIND_ENUM_CONSTANT(BUILD_OPTION_CATEGORY_TEXT_SERVER);
BIND_ENUM_CONSTANT(BUILD_OPTION_CATEGORY_MAX);
}
EditorBuildProfile::EditorBuildProfile() {
for (int i = 0; i < EditorBuildProfile::BUILD_OPTION_MAX; i++) {
build_options_disabled[i] = build_option_disabled_by_default[i];
}
reset_build_options();
HashMap<String, LocalVector<Variant>> settings_openxr = {
{ "xr/openxr/enabled", { true } },
};
build_option_settings.insert(BUILD_OPTION_OPENXR, settings_openxr);
HashMap<String, LocalVector<Variant>> settings_wayland = {
{ "display/display_server/driver.linuxbsd", { "default", "wayland" } },
};
build_option_settings.insert(BUILD_OPTION_OPENXR, settings_wayland);
HashMap<String, LocalVector<Variant>> settings_x11 = {
{ "display/display_server/driver.linuxbsd", { "default", "x11" } },
};
build_option_settings.insert(BUILD_OPTION_OPENXR, settings_x11);
HashMap<String, LocalVector<Variant>> settings_rd = {
{ "rendering/renderer/rendering_method", { "forward_plus", "mobile" } },
{ "rendering/renderer/rendering_method.mobile", { "forward_plus", "mobile" } },
{ "rendering/renderer/rendering_method.web", { "forward_plus", "mobile" } },
};
build_option_settings.insert(BUILD_OPTION_RENDERING_DEVICE, settings_rd);
HashMap<String, LocalVector<Variant>> settings_vulkan = {
{ "rendering/rendering_device/driver", { "vulkan" } },
{ "rendering/rendering_device/driver.windows", { "vulkan" } },
{ "rendering/rendering_device/driver.linuxbsd", { "vulkan" } },
{ "rendering/rendering_device/driver.android", { "vulkan" } },
{ "rendering/rendering_device/driver.ios", { "vulkan" } },
{ "rendering/rendering_device/driver.macos", { "vulkan" } },
{ "rendering/rendering_device/fallback_to_vulkan", { true } },
};
build_option_settings.insert(BUILD_OPTION_VULKAN, settings_vulkan);
HashMap<String, LocalVector<Variant>> settings_d3d12 = {
{ "rendering/rendering_device/driver", { "d3d12" } },
{ "rendering/rendering_device/driver.windows", { "d3d12" } },
{ "rendering/rendering_device/driver.linuxbsd", { "d3d12" } },
{ "rendering/rendering_device/driver.android", { "d3d12" } },
{ "rendering/rendering_device/driver.ios", { "d3d12" } },
{ "rendering/rendering_device/driver.macos", { "d3d12" } },
{ "rendering/rendering_device/fallback_to_d3d12", { true } },
};
build_option_settings.insert(BUILD_OPTION_VULKAN, settings_vulkan);
HashMap<String, LocalVector<Variant>> settings_metal = {
{ "rendering/rendering_device/driver", { "metal" } },
{ "rendering/rendering_device/driver.ios", { "metal" } },
{ "rendering/rendering_device/driver.macos", { "metal" } },
};
build_option_settings.insert(BUILD_OPTION_METAL, settings_metal);
HashMap<String, LocalVector<Variant>> settings_opengl = {
{ "rendering/renderer/rendering_method", { "gl_compatibility" } },
{ "rendering/renderer/rendering_method.mobile", { "gl_compatibility" } },
{ "rendering/renderer/rendering_method.web", { "gl_compatibility" } },
{ "rendering/rendering_device/fallback_to_opengl3", { true } },
};
build_option_settings.insert(BUILD_OPTION_OPENGL, settings_opengl);
HashMap<String, LocalVector<Variant>> settings_phy_godot_3d = {
{ "physics/3d/physics_engine", { "DEFAULT", "GodotPhysics3D" } },
};
build_option_settings.insert(BUILD_OPTION_PHYSICS_GODOT_3D, settings_phy_godot_3d);
HashMap<String, LocalVector<Variant>> settings_jolt = {
{ "physics/3d/physics_engine", { "Jolt Physics" } },
};
build_option_settings.insert(BUILD_OPTION_PHYSICS_JOLT, settings_jolt);
HashMap<String, LocalVector<Variant>> settings_msdfgen = {
{ "gui/theme/default_font_multichannel_signed_distance_field", { true } },
};
build_option_settings.insert(BUILD_OPTION_MSDFGEN, settings_msdfgen);
}
//////////////////////////
@@ -406,7 +738,11 @@ void EditorBuildProfileManager::_profile_action(int p_action) {
confirm_dialog->popup_centered();
} break;
case ACTION_DETECT: {
confirm_dialog->set_text(TTR("This will scan all files in the current project to detect used classes."));
String text = TTR("This will scan all files in the current project to detect used classes.\nNote that the first scan may take a while, specially in larger projects.");
#ifdef MODULE_MONO_ENABLED
text += "\n\n" + TTR("Warning: Class detection for C# scripts is not currently available, and such files will be ignored.");
#endif // MODULE_MONO_ENABLED
confirm_dialog->set_text(text);
confirm_dialog->popup_centered();
} break;
case ACTION_MAX: {
@@ -415,23 +751,35 @@ void EditorBuildProfileManager::_profile_action(int p_action) {
}
void EditorBuildProfileManager::_find_files(EditorFileSystemDirectory *p_dir, const HashMap<String, DetectedFile> &p_cache, HashMap<String, DetectedFile> &r_detected) {
if (p_dir == nullptr) {
if (p_dir == nullptr || p_dir->get_path().get_file().begins_with(".")) {
return;
}
for (int i = 0; i < p_dir->get_file_count(); i++) {
String p = p_dir->get_file_path(i);
if (EditorNode::get_singleton()->progress_task_step("detect_classes_from_project", p, 1)) {
project_scan_canceled = true;
return;
}
String p_check = p;
// Make so that the import file is the one checked if available,
// so the cache can be updated when it changes.
if (ResourceFormatImporter::get_singleton()->exists(p_check)) {
p_check += ".import";
}
uint64_t timestamp = 0;
String md5;
if (p_cache.has(p)) {
const DetectedFile &cache = p_cache[p];
// Check if timestamp and MD5 match.
timestamp = FileAccess::get_modified_time(p);
timestamp = FileAccess::get_modified_time(p_check);
bool cache_valid = true;
if (cache.timestamp != timestamp) {
md5 = FileAccess::get_md5(p);
md5 = FileAccess::get_md5(p_check);
if (md5 != cache.md5) {
cache_valid = false;
}
@@ -449,14 +797,19 @@ void EditorBuildProfileManager::_find_files(EditorFileSystemDirectory *p_dir, co
HashSet<StringName> classes;
ResourceLoader::get_classes_used(p, &classes);
for (const StringName &E : classes) {
cache.classes.push_back(E);
}
HashSet<String> build_deps;
ResourceFormatImporter::get_singleton()->get_build_dependencies(p, &build_deps);
for (const String &E : build_deps) {
cache.build_deps.push_back(E);
}
if (md5.is_empty()) {
cache.timestamp = FileAccess::get_modified_time(p);
cache.md5 = FileAccess::get_md5(p);
cache.timestamp = FileAccess::get_modified_time(p_check);
cache.md5 = FileAccess::get_md5(p_check);
} else {
cache.timestamp = timestamp;
cache.md5 = md5;
@@ -470,7 +823,9 @@ void EditorBuildProfileManager::_find_files(EditorFileSystemDirectory *p_dir, co
}
}
void EditorBuildProfileManager::_detect_classes() {
void EditorBuildProfileManager::_detect_from_project() {
EditorNode::get_singleton()->progress_add_task("detect_classes_from_project", TTRC("Scanning Project for Used Classes"), 3, true);
HashMap<String, DetectedFile> previous_file_cache;
Ref<FileAccess> f = FileAccess::open(EditorPaths::get_singleton()->get_project_settings_dir().path_join("used_class_cache"), FileAccess::READ);
@@ -478,12 +833,13 @@ void EditorBuildProfileManager::_detect_classes() {
while (!f->eof_reached()) {
String l = f->get_line();
Vector<String> fields = l.split("::");
if (fields.size() == 4) {
if (fields.size() == 5) {
const String &path = fields[0];
DetectedFile df;
df.timestamp = fields[1].to_int();
df.md5 = fields[2];
df.classes = fields[3].split(",");
df.classes = fields[3].split(",", false);
df.build_deps = fields[4].split(",", false);
previous_file_cache.insert(path, df);
}
}
@@ -494,7 +850,17 @@ void EditorBuildProfileManager::_detect_classes() {
_find_files(EditorFileSystem::get_singleton()->get_filesystem(), previous_file_cache, updated_file_cache);
if (project_scan_canceled) {
project_scan_canceled = false;
EditorNode::get_singleton()->progress_end_task("detect_classes_from_project");
return;
}
EditorNode::get_singleton()->progress_task_step("detect_classes_from_project", TTRC("Processing Classes Found"), 2);
HashSet<StringName> used_classes;
LocalVector<String> used_build_deps;
// Find classes and update the disk cache in the process.
f = FileAccess::open(EditorPaths::get_singleton()->get_project_settings_dir().path_join("used_class_cache"), FileAccess::WRITE);
@@ -509,20 +875,41 @@ void EditorBuildProfileManager::_detect_classes() {
l += c;
used_classes.insert(c);
}
l += "::";
for (int i = 0; i < E.value.build_deps.size(); i++) {
String c = E.value.build_deps[i];
if (i > 0) {
l += ",";
}
l += c;
used_build_deps.push_back(c);
}
f->store_line(l);
}
f.unref();
// Add forced ones.
// Add classes that are either necessary for the engine to work properly, or there isn't a way to infer their use.
Vector<String> force_detect = edited->get_force_detect_classes().split(",");
for (int i = 0; i < force_detect.size(); i++) {
String c = force_detect[i].strip_edges();
if (c.is_empty()) {
continue;
const LocalVector<String> hardcoded_classes = { "InputEvent", "MainLoop", "StyleBox" };
for (const String &hc_class : hardcoded_classes) {
used_classes.insert(hc_class);
LocalVector<StringName> inheriters;
ClassDB::get_inheriters_from_class(hc_class, inheriters);
for (const StringName &inheriter : inheriters) {
used_classes.insert(inheriter);
}
}
// Add forced classes typed by the user.
const Vector<String> force_detect = edited->get_force_detect_classes().split(",");
for (const String &class_name : force_detect) {
const String class_stripped = class_name.strip_edges();
if (!class_stripped.is_empty()) {
used_classes.insert(class_stripped);
}
used_classes.insert(c);
}
// Filter all classes to discard inherited ones.
@@ -532,13 +919,23 @@ void EditorBuildProfileManager::_detect_classes() {
for (const StringName &E : used_classes) {
StringName c = E;
if (!ClassDB::class_exists(c)) {
// Maybe this is an old class that got replaced? try getting compat class.
// Maybe this is an old class that got replaced? Try getting compat class.
c = ClassDB::get_compatibility_class(c);
if (!c) {
// No luck, skip.
continue;
}
}
List<StringName> dependencies;
ClassDB::get_class_dependencies(E, &dependencies);
for (const StringName &dep : dependencies) {
if (!all_used_classes.has(dep)) {
// Add classes which this class depends upon.
all_used_classes.insert(dep);
}
}
while (c) {
all_used_classes.insert(c);
c = ClassDB::get_parent_class(c);
@@ -551,8 +948,8 @@ void EditorBuildProfileManager::_detect_classes() {
ClassDB::get_class_list(&all_classes);
for (const StringName &E : all_classes) {
if (all_used_classes.has(E)) {
// This class is valid, do nothing.
if (String(E).begins_with("Editor") || ClassDB::get_api_type(E) != ClassDB::API_CORE || all_used_classes.has(E)) {
// This class is valid or editor-only, do nothing.
continue;
}
@@ -563,6 +960,88 @@ void EditorBuildProfileManager::_detect_classes() {
edited->set_disable_class(E, true);
}
}
edited->reset_build_options();
for (int i = 0; i < EditorBuildProfile::BUILD_OPTION_MAX; i++) {
// Check if the build option requires other options that are currently disabled.
LocalVector<EditorBuildProfile::BuildOption> dependencies = EditorBuildProfile::get_build_option_dependencies(EditorBuildProfile::BuildOption(i));
if (!dependencies.is_empty()) {
bool disable = true;
for (EditorBuildProfile::BuildOption dependency : dependencies) {
if (!edited->is_build_option_disabled(dependency)) {
disable = false;
break;
}
}
if (disable) {
edited->set_disable_build_option(EditorBuildProfile::BuildOption(i), true);
continue;
}
}
bool skip = false;
bool ignore = true;
// Check if the build option has enabled classes using it.
const LocalVector<String> classes = EditorBuildProfile::get_build_option_classes(EditorBuildProfile::BuildOption(i));
if (!classes.is_empty()) {
for (StringName class_name : classes) {
if (!edited->is_class_disabled(class_name)) {
skip = true;
break;
}
}
if (skip) {
continue;
}
ignore = false;
}
// Check if there's project settings requiring it.
const HashMap<String, LocalVector<Variant>> settings_list = EditorBuildProfile::get_build_option_settings(EditorBuildProfile::BuildOption(i));
if (!settings_list.is_empty()) {
for (KeyValue<String, LocalVector<Variant>> KV : settings_list) {
Variant proj_value = GLOBAL_GET(KV.key);
for (Variant value : KV.value) {
if (proj_value == value) {
skip = true;
break;
}
}
if (skip) {
break;
}
}
if (skip) {
continue;
}
ignore = false;
}
// Check if a resource setting depends on it.
if (used_build_deps.has(EditorBuildProfile::get_build_option_identifier(EditorBuildProfile::BuildOption(i)))) {
continue;
} else if (EditorBuildProfile::get_build_option_explicit_use(EditorBuildProfile::BuildOption(i))) {
ignore = false;
}
if (!skip && !ignore) {
edited->set_disable_build_option(EditorBuildProfile::BuildOption(i), true);
}
}
if (edited->is_build_option_disabled(EditorBuildProfile::BUILD_OPTION_TEXT_SERVER_ADVANCED)) {
edited->set_disable_build_option(EditorBuildProfile::BUILD_OPTION_TEXT_SERVER_FALLBACK, false);
}
EditorNode::get_singleton()->progress_end_task("detect_classes_from_project");
}
void EditorBuildProfileManager::_action_confirm() {
@@ -583,7 +1062,7 @@ void EditorBuildProfileManager::_action_confirm() {
_update_edited_profile();
} break;
case ACTION_DETECT: {
_detect_classes();
_detect_from_project();
_update_edited_profile();
} break;
case ACTION_MAX: {
@@ -869,7 +1348,7 @@ EditorBuildProfileManager::EditorBuildProfileManager() {
add_child(import_profile);
import_profile->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
import_profile->add_filter("*.gdbuild,*.build", TTR("Engine Compilation Profile"));
import_profile->connect("files_selected", callable_mp(this, &EditorBuildProfileManager::_import_profile));
import_profile->connect("file_selected", callable_mp(this, &EditorBuildProfileManager::_import_profile));
import_profile->set_title(TTR("Load Profile"));
import_profile->set_access(EditorFileDialog::ACCESS_FILESYSTEM);