Merge pull request #80188 from vnen/gdextension-copy-dll

GDExtension: Copy DLL to a temp file before opening
This commit is contained in:
Rémi Verschelde 2023-08-16 16:55:19 +02:00
commit 1e3b1a7137
No known key found for this signature in database
GPG Key ID: C3336907360768E1
3 changed files with 54 additions and 1 deletions

View File

@ -485,6 +485,13 @@ void GDExtension::close_library() {
ERR_FAIL_COND(library == nullptr); ERR_FAIL_COND(library == nullptr);
OS::get_singleton()->close_dynamic_library(library); 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; library = nullptr;
} }
@ -641,6 +648,40 @@ Ref<Resource> GDExtensionResourceLoader::load(const String &p_path, const String
Ref<GDExtension> lib; Ref<GDExtension> lib;
lib.instantiate(); lib.instantiate();
String abs_path = ProjectSettings::get_singleton()->globalize_path(library_path); 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); err = lib->open_library(abs_path, entry_symbol);
if (r_error) { if (r_error) {

View File

@ -43,6 +43,9 @@ class GDExtension : public Resource {
void *library = nullptr; // pointer if valid, void *library = nullptr; // pointer if valid,
String library_path; String library_path;
#if defined(WINDOWS_ENABLED) && defined(TOOLS_ENABLED)
String temp_lib_path;
#endif
struct Extension { struct Extension {
ObjectGDExtension gdextension; ObjectGDExtension gdextension;
@ -76,6 +79,10 @@ public:
Error open_library(const String &p_path, const String &p_entry_symbol); Error open_library(const String &p_path, const String &p_entry_symbol);
void close_library(); 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 { enum InitializationLevel {
INITIALIZATION_LEVEL_CORE = GDEXTENSION_INITIALIZATION_CORE, INITIALIZATION_LEVEL_CORE = GDEXTENSION_INITIALIZATION_CORE,
INITIALIZATION_LEVEL_SERVERS = GDEXTENSION_INITIALIZATION_SERVERS, INITIALIZATION_LEVEL_SERVERS = GDEXTENSION_INITIALIZATION_SERVERS,

View File

@ -1543,6 +1543,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. // Initialize user data dir.
OS::get_singleton()->ensure_user_data_dir(); OS::get_singleton()->ensure_user_data_dir();
@ -1570,7 +1576,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
if (editor) { if (editor) {
packed_data->set_disabled(true); packed_data->set_disabled(true);
Engine::get_singleton()->set_editor_hint(true);
main_args.push_back("--editor"); main_args.push_back("--editor");
if (!init_windowed) { if (!init_windowed) {
init_maximized = true; init_maximized = true;