diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2023-08-16 16:55:19 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2023-08-16 16:55:19 +0200 |
commit | 1e3b1a7137134fdab13d323405e4dc2b35405997 (patch) | |
tree | a637ccc5e130d01184eb94efddcfca3f75a50947 /core/extension | |
parent | e31cb25d506fd1844104cde1d750fdc3264a854e (diff) | |
parent | cff69b0612a4bfc002bd40080829c66e1bb463b7 (diff) | |
download | redot-engine-1e3b1a7137134fdab13d323405e4dc2b35405997.tar.gz |
Merge pull request #80188 from vnen/gdextension-copy-dll
GDExtension: Copy DLL to a temp file before opening
Diffstat (limited to 'core/extension')
-rw-r--r-- | core/extension/gdextension.cpp | 41 | ||||
-rw-r--r-- | core/extension/gdextension.h | 7 |
2 files changed, 48 insertions, 0 deletions
diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp index 9a735f5aa6..1e4cd81034 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; } @@ -641,6 +648,40 @@ Ref<Resource> GDExtensionResourceLoader::load(const String &p_path, const String Ref<GDExtension> 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<Resource>(); + } + + // 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<Resource>(); + } + 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 b935f8706f..5a4dd3d5f5 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, |