summaryrefslogtreecommitdiff
path: root/modules/mono/mono_gd/gd_mono.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono/mono_gd/gd_mono.cpp')
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp125
1 files changed, 42 insertions, 83 deletions
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index 0532cc915b..3b87d9248a 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -43,12 +43,13 @@
#include "../utils/path_utils.h"
#include "gd_mono_cache.h"
+#include "../thirdparty/coreclr_delegates.h"
+#include "../thirdparty/hostfxr.h"
+
#ifdef TOOLS_ENABLED
-#include <nethost.h>
+#include "../editor/hostfxr_resolver.h"
#endif
-#include <coreclr_delegates.h>
-#include <hostfxr.h>
#ifdef UNIX_ENABLED
#include <dlfcn.h>
#endif
@@ -88,98 +89,56 @@ HostFxrCharString str_to_hostfxr(const String &p_str) {
#endif
}
-#ifdef TOOLS_ENABLED
-String str_from_hostfxr(const char_t *p_buffer) {
-#ifdef _WIN32
- return String::utf16((const char16_t *)p_buffer);
-#else
- return String::utf8((const char *)p_buffer);
-#endif
-}
-#endif
-
const char_t *get_data(const HostFxrCharString &p_char_str) {
return (const char_t *)p_char_str.get_data();
}
-#ifdef TOOLS_ENABLED
-String find_hostfxr(size_t p_known_buffet_size, get_hostfxr_parameters *p_get_hostfxr_params) {
- // Pre-allocate a large buffer for the path to hostfxr
- Vector<char_t> buffer;
- buffer.resize(p_known_buffet_size);
-
- int rc = get_hostfxr_path(buffer.ptrw(), &p_known_buffet_size, p_get_hostfxr_params);
-
- ERR_FAIL_COND_V_MSG(rc != 0, String(), "get_hostfxr_path failed with code: " + itos(rc));
-
- return str_from_hostfxr(buffer.ptr());
-}
-#endif
-
String find_hostfxr() {
#ifdef TOOLS_ENABLED
- const int CoreHostLibMissingFailure = 0x80008083;
- const int HostApiBufferTooSmall = 0x80008098;
-
- size_t buffer_size = 0;
- int rc = get_hostfxr_path(nullptr, &buffer_size, nullptr);
-
- if (rc == HostApiBufferTooSmall) {
- return find_hostfxr(buffer_size, nullptr);
+ String dotnet_root;
+ String fxr_path;
+ if (godotsharp::hostfxr_resolver::try_get_path(dotnet_root, fxr_path)) {
+ return fxr_path;
}
- if (rc == CoreHostLibMissingFailure) {
- // Apparently `get_hostfxr_path` doesn't look for dotnet in `PATH`? (I suppose it needs the
- // `DOTNET_ROOT` environment variable). If it fails, we try to find the dotnet executable
- // in `PATH` ourselves and pass its location as `dotnet_root` to `get_hostfxr_path`.
- String dotnet_exe = path::find_executable("dotnet");
-
- if (!dotnet_exe.is_empty()) {
- // The file found in PATH may be a symlink
- dotnet_exe = path::abspath(path::realpath(dotnet_exe));
-
- // TODO:
- // Sometimes, the symlink may not point to the dotnet executable in the dotnet root.
- // That's the case with snaps. The snap install should have been found with the
- // previous `get_hostfxr_path`, but it would still be better to do this properly
- // and use something like `dotnet --list-sdks/runtimes` to find the actual location.
- // This way we could also check if the proper sdk or runtime is installed. This would
- // allow us to fail gracefully and show some helpful information in the editor.
-
- HostFxrCharString dotnet_root = str_to_hostfxr(dotnet_exe.get_base_dir());
-
- get_hostfxr_parameters get_hostfxr_parameters = {
- sizeof(get_hostfxr_parameters),
- nullptr,
- get_data(dotnet_root)
- };
-
- buffer_size = 0;
- rc = get_hostfxr_path(nullptr, &buffer_size, &get_hostfxr_parameters);
- if (rc == HostApiBufferTooSmall) {
- return find_hostfxr(buffer_size, &get_hostfxr_parameters);
- }
+ // hostfxr_resolver doesn't look for dotnet in `PATH`. If it fails, we try to find the dotnet
+ // executable in `PATH` here and pass its location as `dotnet_root` to `get_hostfxr_path`.
+ String dotnet_exe = path::find_executable("dotnet");
+
+ if (!dotnet_exe.is_empty()) {
+ // The file found in PATH may be a symlink
+ dotnet_exe = path::abspath(path::realpath(dotnet_exe));
+
+ // TODO:
+ // Sometimes, the symlink may not point to the dotnet executable in the dotnet root.
+ // That's the case with snaps. The snap install should have been found with the
+ // previous `get_hostfxr_path`, but it would still be better to do this properly
+ // and use something like `dotnet --list-sdks/runtimes` to find the actual location.
+ // This way we could also check if the proper sdk or runtime is installed. This would
+ // allow us to fail gracefully and show some helpful information in the editor.
+
+ dotnet_root = dotnet_exe.get_base_dir();
+ if (godotsharp::hostfxr_resolver::try_get_path_from_dotnet_root(dotnet_root, fxr_path)) {
+ return fxr_path;
}
}
- if (rc == CoreHostLibMissingFailure) {
- ERR_PRINT(String() + ".NET: One of the dependent libraries is missing. " +
- "Typically when the `hostfxr`, `hostpolicy` or `coreclr` dynamic " +
- "libraries are not present in the expected locations.");
- }
+ ERR_PRINT(String() + ".NET: One of the dependent libraries is missing. " +
+ "Typically when the `hostfxr`, `hostpolicy` or `coreclr` dynamic " +
+ "libraries are not present in the expected locations.");
return String();
#else
#if defined(WINDOWS_ENABLED)
String probe_path = GodotSharpDirs::get_api_assemblies_dir()
- .plus_file("hostfxr.dll");
+ .path_join("hostfxr.dll");
#elif defined(MACOS_ENABLED)
String probe_path = GodotSharpDirs::get_api_assemblies_dir()
- .plus_file("libhostfxr.dylib");
+ .path_join("libhostfxr.dylib");
#elif defined(UNIX_ENABLED)
String probe_path = GodotSharpDirs::get_api_assemblies_dir()
- .plus_file("libhostfxr.so");
+ .path_join("libhostfxr.so");
#else
#error "Platform not supported (yet?)"
#endif
@@ -270,7 +229,7 @@ load_assembly_and_get_function_pointer_fn initialize_hostfxr_self_contained(
int i = 1;
for (const String &E : cmdline_args) {
HostFxrCharString &stored = argv_store.push_back(str_to_hostfxr(E))->get();
- argv.write[i] = stored.ptr();
+ argv.write[i] = get_data(stored);
i++;
}
@@ -305,10 +264,10 @@ godot_plugins_initialize_fn initialize_hostfxr_and_godot_plugins(bool &r_runtime
godot_plugins_initialize_fn godot_plugins_initialize = nullptr;
HostFxrCharString godot_plugins_path = str_to_hostfxr(
- GodotSharpDirs::get_api_assemblies_dir().plus_file("GodotPlugins.dll"));
+ GodotSharpDirs::get_api_assemblies_dir().path_join("GodotPlugins.dll"));
HostFxrCharString config_path = str_to_hostfxr(
- GodotSharpDirs::get_api_assemblies_dir().plus_file("GodotPlugins.runtimeconfig.json"));
+ GodotSharpDirs::get_api_assemblies_dir().path_join("GodotPlugins.runtimeconfig.json"));
load_assembly_and_get_function_pointer_fn load_assembly_and_get_function_pointer =
initialize_hostfxr_for_config(get_data(config_path));
@@ -345,7 +304,7 @@ godot_plugins_initialize_fn initialize_hostfxr_and_godot_plugins(bool &r_runtime
String assembly_name = get_assembly_name();
HostFxrCharString assembly_path = str_to_hostfxr(GodotSharpDirs::get_api_assemblies_dir()
- .plus_file(assembly_name + ".dll"));
+ .path_join(assembly_name + ".dll"));
load_assembly_and_get_function_pointer_fn load_assembly_and_get_function_pointer =
initialize_hostfxr_self_contained(get_data(assembly_path));
@@ -356,7 +315,7 @@ godot_plugins_initialize_fn initialize_hostfxr_and_godot_plugins(bool &r_runtime
print_verbose(".NET: hostfxr initialized");
int rc = load_assembly_and_get_function_pointer(get_data(assembly_path),
- str_to_hostfxr("GodotPlugins.Game.Main, " + assembly_name),
+ get_data(str_to_hostfxr("GodotPlugins.Game.Main, " + assembly_name)),
HOSTFXR_STR("InitializeFromGameProject"),
UNMANAGEDCALLERSONLY_METHOD,
nullptr,
@@ -370,11 +329,11 @@ godot_plugins_initialize_fn try_load_native_aot_library(void *&r_aot_dll_handle)
String assembly_name = get_assembly_name();
#if defined(WINDOWS_ENABLED)
- String native_aot_so_path = GodotSharpDirs::get_api_assemblies_dir().plus_file(assembly_name + ".dll");
+ String native_aot_so_path = GodotSharpDirs::get_api_assemblies_dir().path_join(assembly_name + ".dll");
#elif defined(MACOS_ENABLED)
- String native_aot_so_path = GodotSharpDirs::get_api_assemblies_dir().plus_file(assembly_name + ".dylib");
+ String native_aot_so_path = GodotSharpDirs::get_api_assemblies_dir().path_join(assembly_name + ".dylib");
#elif defined(UNIX_ENABLED)
- String native_aot_so_path = GodotSharpDirs::get_api_assemblies_dir().plus_file(assembly_name + ".so");
+ String native_aot_so_path = GodotSharpDirs::get_api_assemblies_dir().path_join(assembly_name + ".so");
#else
#error "Platform not supported (yet?)"
#endif
@@ -514,7 +473,7 @@ bool GDMono::_load_project_assembly() {
}
String assembly_path = GodotSharpDirs::get_res_temp_assemblies_dir()
- .plus_file(assembly_name + ".dll");
+ .path_join(assembly_name + ".dll");
assembly_path = ProjectSettings::get_singleton()->globalize_path(assembly_path);
if (!FileAccess::exists(assembly_path)) {