mirror of
https://github.com/godotengine/godot.git
synced 2024-11-27 09:16:35 +08:00
GDExtension: Copy DLL to a temp file before opening
This is done only in the editor and only on Windows, to avoid a file lock that prevents the original library being updated (e.g. by a compiler). When the game runs it will load the original DLL and pick up any changes, only the editor will stay with the copy (until it is restarted and create a new copy). The copy is done in place by prepending a `~` to the original file name, so dependencies that are loaded with a relative file path still work. When the library is unloaded the copy file is deleted. The copy is also marked as hidden to not show up in explorer.
This commit is contained in:
parent
4714e95896
commit
cff69b0612
@ -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<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) {
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user