diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp index 67b55db3db7..c3f84c2a150 100644 --- a/core/extension/gdextension.cpp +++ b/core/extension/gdextension.cpp @@ -485,6 +485,13 @@ void GDExtension::close_library() { ERR_FAIL_COND(library == nullptr); OS::get_singleton()->close_dynamic_library(library); +#if defined(TOOLS_ENABLED) && defined(WINDOWS_ENABLED) + // Delete temporary copy of library if it exists. + if (!temp_lib_path.is_empty() && Engine::get_singleton()->is_editor_hint()) { + DirAccess::remove_absolute(temp_lib_path); + } +#endif + library = nullptr; } @@ -640,6 +647,40 @@ Ref GDExtensionResourceLoader::load(const String &p_path, const String Ref lib; lib.instantiate(); String abs_path = ProjectSettings::get_singleton()->globalize_path(library_path); + +#if defined(WINDOWS_ENABLED) && defined(TOOLS_ENABLED) + // If running on the editor on Windows, we copy the library and open the copy. + // This is so the original file isn't locked and can be updated by a compiler. + if (Engine::get_singleton()->is_editor_hint()) { + if (!FileAccess::exists(abs_path)) { + if (r_error) { + *r_error = ERR_FILE_NOT_FOUND; + } + ERR_PRINT("GDExtension library not found: " + library_path); + return Ref(); + } + + // Copy the file to the same directory as the original with a prefix in the name. + // This is so relative path to dependencies are satisfied. + String copy_path = abs_path.get_base_dir().path_join("~" + abs_path.get_file()); + + Error copy_err = DirAccess::copy_absolute(abs_path, copy_path); + if (copy_err) { + if (r_error) { + *r_error = ERR_CANT_CREATE; + } + ERR_PRINT("Error copying GDExtension library: " + library_path); + return Ref(); + } + FileAccess::set_hidden_attribute(copy_path, true); + + // Save the copied path so it can be deleted later. + lib->set_temp_library_path(copy_path); + + // Use the copy to open the library. + abs_path = copy_path; + } +#endif err = lib->open_library(abs_path, entry_symbol); if (r_error) { diff --git a/core/extension/gdextension.h b/core/extension/gdextension.h index b935f8706f9..5a4dd3d5f59 100644 --- a/core/extension/gdextension.h +++ b/core/extension/gdextension.h @@ -43,6 +43,9 @@ class GDExtension : public Resource { void *library = nullptr; // pointer if valid, String library_path; +#if defined(WINDOWS_ENABLED) && defined(TOOLS_ENABLED) + String temp_lib_path; +#endif struct Extension { ObjectGDExtension gdextension; @@ -76,6 +79,10 @@ public: Error open_library(const String &p_path, const String &p_entry_symbol); void close_library(); +#if defined(WINDOWS_ENABLED) && defined(TOOLS_ENABLED) + void set_temp_library_path(const String &p_path) { temp_lib_path = p_path; } +#endif + enum InitializationLevel { INITIALIZATION_LEVEL_CORE = GDEXTENSION_INITIALIZATION_CORE, INITIALIZATION_LEVEL_SERVERS = GDEXTENSION_INITIALIZATION_SERVERS, diff --git a/main/main.cpp b/main/main.cpp index 220afda5def..1c047371e58 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1540,6 +1540,12 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } } +#ifdef TOOLS_ENABLED + if (editor) { + Engine::get_singleton()->set_editor_hint(true); + } +#endif + // Initialize user data dir. OS::get_singleton()->ensure_user_data_dir(); @@ -1567,7 +1573,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph #ifdef TOOLS_ENABLED if (editor) { packed_data->set_disabled(true); - Engine::get_singleton()->set_editor_hint(true); main_args.push_back("--editor"); if (!init_windowed) { init_maximized = true;