Merge pull request #33982 from neikeq/issue-29349
Mono/C#: Add option to export assemblies outside of PCK
This commit is contained in:
commit
fa0e682027
@ -120,9 +120,9 @@ def configure(env, env_mono):
|
|||||||
env.Append(LIBPATH=mono_lib_path)
|
env.Append(LIBPATH=mono_lib_path)
|
||||||
env_mono.Prepend(CPPPATH=os.path.join(mono_root, 'include', 'mono-2.0'))
|
env_mono.Prepend(CPPPATH=os.path.join(mono_root, 'include', 'mono-2.0'))
|
||||||
|
|
||||||
if mono_static:
|
lib_suffix = Environment()['LIBSUFFIX']
|
||||||
lib_suffix = Environment()['LIBSUFFIX']
|
|
||||||
|
|
||||||
|
if mono_static:
|
||||||
if env.msvc:
|
if env.msvc:
|
||||||
mono_static_lib_name = 'libmono-static-sgen'
|
mono_static_lib_name = 'libmono-static-sgen'
|
||||||
else:
|
else:
|
||||||
@ -144,13 +144,13 @@ def configure(env, env_mono):
|
|||||||
env.Append(LIBS=['psapi'])
|
env.Append(LIBS=['psapi'])
|
||||||
env.Append(LIBS=['version'])
|
env.Append(LIBS=['version'])
|
||||||
else:
|
else:
|
||||||
mono_lib_name = find_file_in_dir(mono_lib_path, mono_lib_names, extension='.lib')
|
mono_lib_name = find_file_in_dir(mono_lib_path, mono_lib_names, extension=lib_suffix)
|
||||||
|
|
||||||
if not mono_lib_name:
|
if not mono_lib_name:
|
||||||
raise RuntimeError('Could not find mono library in: ' + mono_lib_path)
|
raise RuntimeError('Could not find mono library in: ' + mono_lib_path)
|
||||||
|
|
||||||
if env.msvc:
|
if env.msvc:
|
||||||
env.Append(LINKFLAGS=mono_lib_name + Environment()['LIBSUFFIX'])
|
env.Append(LINKFLAGS=mono_lib_name + lib_suffix)
|
||||||
else:
|
else:
|
||||||
env.Append(LIBS=[mono_lib_name])
|
env.Append(LIBS=[mono_lib_name])
|
||||||
|
|
||||||
@ -426,15 +426,17 @@ def copy_mono_shared_libs(env, mono_root, target_mono_root_dir):
|
|||||||
platform = env['platform']
|
platform = env['platform']
|
||||||
|
|
||||||
if platform == 'windows':
|
if platform == 'windows':
|
||||||
|
src_mono_bin_dir = os.path.join(mono_root, 'bin')
|
||||||
target_mono_bin_dir = os.path.join(target_mono_root_dir, 'bin')
|
target_mono_bin_dir = os.path.join(target_mono_root_dir, 'bin')
|
||||||
|
|
||||||
if not os.path.isdir(target_mono_bin_dir):
|
if not os.path.isdir(target_mono_bin_dir):
|
||||||
os.makedirs(target_mono_bin_dir)
|
os.makedirs(target_mono_bin_dir)
|
||||||
|
|
||||||
copy(os.path.join(mono_root, 'bin', 'MonoPosixHelper.dll'), target_mono_bin_dir)
|
mono_posix_helper_name = find_file_in_dir(src_mono_bin_dir, ['MonoPosixHelper', 'libMonoPosixHelper'], extension='.dll')
|
||||||
|
copy(os.path.join(src_mono_bin_dir, mono_posix_helper_name + '.dll'), os.path.join(target_mono_bin_dir, 'MonoPosixHelper.dll'))
|
||||||
|
|
||||||
# For newer versions
|
# For newer versions
|
||||||
btls_dll_path = os.path.join(mono_root, 'bin', 'libmono-btls-shared.dll')
|
btls_dll_path = os.path.join(src_mono_bin_dir, 'libmono-btls-shared.dll')
|
||||||
if os.path.isfile(btls_dll_path):
|
if os.path.isfile(btls_dll_path):
|
||||||
copy(btls_dll_path, target_mono_bin_dir)
|
copy(btls_dll_path, target_mono_bin_dir)
|
||||||
else:
|
else:
|
||||||
|
@ -22,6 +22,7 @@ namespace GodotTools.Export
|
|||||||
// TODO: These would be better as export preset options, but that doesn't seem to be supported yet
|
// TODO: These would be better as export preset options, but that doesn't seem to be supported yet
|
||||||
|
|
||||||
GlobalDef("mono/export/include_scripts_content", false);
|
GlobalDef("mono/export/include_scripts_content", false);
|
||||||
|
GlobalDef("mono/export/export_assemblies_inside_pck", true);
|
||||||
|
|
||||||
GlobalDef("mono/export/aot/enabled", false);
|
GlobalDef("mono/export/aot/enabled", false);
|
||||||
GlobalDef("mono/export/aot/full_aot", false);
|
GlobalDef("mono/export/aot/full_aot", false);
|
||||||
@ -130,22 +131,39 @@ namespace GodotTools.Export
|
|||||||
internal_GetExportedAssemblyDependencies(projectDllName, projectDllSrcPath, buildConfig, platformBclDir, dependencies);
|
internal_GetExportedAssemblyDependencies(projectDllName, projectDllSrcPath, buildConfig, platformBclDir, dependencies);
|
||||||
}
|
}
|
||||||
|
|
||||||
string apiConfig = isDebug ? "Debug" : "Release";
|
|
||||||
string resAssembliesDir = Path.Combine(GodotSharpDirs.ResAssembliesBaseDir, apiConfig);
|
|
||||||
|
|
||||||
foreach (var dependency in dependencies)
|
|
||||||
{
|
|
||||||
string dependSrcPath = dependency.Value;
|
|
||||||
string dependDstPath = Path.Combine(resAssembliesDir, dependSrcPath.GetFile());
|
|
||||||
AddFile(dependSrcPath, dependDstPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mono specific export template extras (data dir)
|
|
||||||
string outputDataDir = null;
|
string outputDataDir = null;
|
||||||
|
|
||||||
if (PlatformHasTemplateDir(platform))
|
if (PlatformHasTemplateDir(platform))
|
||||||
outputDataDir = ExportDataDirectory(features, platform, isDebug, outputDir);
|
outputDataDir = ExportDataDirectory(features, platform, isDebug, outputDir);
|
||||||
|
|
||||||
|
string apiConfig = isDebug ? "Debug" : "Release";
|
||||||
|
string resAssembliesDir = Path.Combine(GodotSharpDirs.ResAssembliesBaseDir, apiConfig);
|
||||||
|
|
||||||
|
bool assembliesInsidePck = (bool) ProjectSettings.GetSetting("mono/export/export_assemblies_inside_pck") || outputDataDir == null;
|
||||||
|
|
||||||
|
if (!assembliesInsidePck)
|
||||||
|
{
|
||||||
|
string outputDataGameAssembliesDir = Path.Combine(outputDataDir, "Assemblies");
|
||||||
|
if (!Directory.Exists(outputDataGameAssembliesDir))
|
||||||
|
Directory.CreateDirectory(outputDataGameAssembliesDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var dependency in dependencies)
|
||||||
|
{
|
||||||
|
string dependSrcPath = dependency.Value;
|
||||||
|
|
||||||
|
if (assembliesInsidePck)
|
||||||
|
{
|
||||||
|
string dependDstPath = Path.Combine(resAssembliesDir, dependSrcPath.GetFile());
|
||||||
|
AddFile(dependSrcPath, dependDstPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string dependDstPath = Path.Combine(outputDataDir, "Assemblies", dependSrcPath.GetFile());
|
||||||
|
File.Copy(dependSrcPath, dependDstPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// AOT
|
// AOT
|
||||||
|
|
||||||
if ((bool) ProjectSettings.GetSetting("mono/export/aot/enabled"))
|
if ((bool) ProjectSettings.GetSetting("mono/export/aot/enabled"))
|
||||||
|
@ -108,6 +108,10 @@ public:
|
|||||||
|
|
||||||
String data_editor_tools_dir;
|
String data_editor_tools_dir;
|
||||||
String data_editor_prebuilt_api_dir;
|
String data_editor_prebuilt_api_dir;
|
||||||
|
#else
|
||||||
|
// Equivalent of res_assemblies_dir, but in the data directory rather than in 'res://'.
|
||||||
|
// Only defined on export templates. Used when exporting assemblies outside of PCKs.
|
||||||
|
String data_game_assemblies_dir;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
String data_mono_etc_dir;
|
String data_mono_etc_dir;
|
||||||
@ -205,6 +209,7 @@ private:
|
|||||||
data_mono_lib_dir = GDMonoAndroid::get_app_native_lib_dir();
|
data_mono_lib_dir = GDMonoAndroid::get_app_native_lib_dir();
|
||||||
#else
|
#else
|
||||||
data_mono_lib_dir = data_mono_root_dir.plus_file("lib");
|
data_mono_lib_dir = data_mono_root_dir.plus_file("lib");
|
||||||
|
data_game_assemblies_dir = data_dir_root.plus_file("Assemblies");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WINDOWS_ENABLED
|
#ifdef WINDOWS_ENABLED
|
||||||
@ -216,6 +221,10 @@ private:
|
|||||||
data_mono_etc_dir = exe_dir.plus_file("../Resources/GodotSharp/Mono/etc");
|
data_mono_etc_dir = exe_dir.plus_file("../Resources/GodotSharp/Mono/etc");
|
||||||
data_mono_lib_dir = exe_dir.plus_file("../Frameworks/GodotSharp/Mono/lib");
|
data_mono_lib_dir = exe_dir.plus_file("../Frameworks/GodotSharp/Mono/lib");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!DirAccess::exists(data_game_assemblies_dir)) {
|
||||||
|
data_game_assemblies_dir = exe_dir.plus_file("../Frameworks/GodotSharp/Assemblies");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -295,6 +304,10 @@ String get_data_editor_tools_dir() {
|
|||||||
String get_data_editor_prebuilt_api_dir() {
|
String get_data_editor_prebuilt_api_dir() {
|
||||||
return _GodotSharpDirs::get_singleton().data_editor_prebuilt_api_dir;
|
return _GodotSharpDirs::get_singleton().data_editor_prebuilt_api_dir;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
String get_data_game_assemblies_dir() {
|
||||||
|
return _GodotSharpDirs::get_singleton().data_game_assemblies_dir;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
String get_data_mono_etc_dir() {
|
String get_data_mono_etc_dir() {
|
||||||
|
@ -56,6 +56,8 @@ String get_project_csproj_path();
|
|||||||
|
|
||||||
String get_data_editor_tools_dir();
|
String get_data_editor_tools_dir();
|
||||||
String get_data_editor_prebuilt_api_dir();
|
String get_data_editor_prebuilt_api_dir();
|
||||||
|
#else
|
||||||
|
String get_data_game_assemblies_dir();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
String get_data_mono_etc_dir();
|
String get_data_mono_etc_dir();
|
||||||
|
@ -239,35 +239,22 @@ void GDMono::add_mono_shared_libs_dir_to_path() {
|
|||||||
#endif // WINDOWS_ENABLED || UNIX_ENABLED
|
#endif // WINDOWS_ENABLED || UNIX_ENABLED
|
||||||
}
|
}
|
||||||
|
|
||||||
void GDMono::initialize() {
|
void GDMono::determine_mono_dirs(String &r_assembly_rootdir, String &r_config_dir) {
|
||||||
|
|
||||||
ERR_FAIL_NULL(Engine::get_singleton());
|
String bundled_assembly_rootdir = GodotSharpDirs::get_data_mono_lib_dir();
|
||||||
|
String bundled_config_dir = GodotSharpDirs::get_data_mono_etc_dir();
|
||||||
print_verbose("Mono: Initializing module...");
|
|
||||||
|
|
||||||
char *runtime_build_info = mono_get_runtime_build_info();
|
|
||||||
print_verbose("Mono JIT compiler version " + String(runtime_build_info));
|
|
||||||
mono_free(runtime_build_info);
|
|
||||||
|
|
||||||
#ifdef DEBUG_METHODS_ENABLED
|
|
||||||
_initialize_and_check_api_hashes();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GDMonoLog::get_singleton()->initialize();
|
|
||||||
|
|
||||||
String assembly_rootdir;
|
|
||||||
String config_dir;
|
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
|
|
||||||
#if defined(WINDOWS_ENABLED)
|
#if defined(WINDOWS_ENABLED)
|
||||||
mono_reg_info = MonoRegUtils::find_mono();
|
mono_reg_info = MonoRegUtils::find_mono();
|
||||||
|
|
||||||
if (mono_reg_info.assembly_dir.length() && DirAccess::exists(mono_reg_info.assembly_dir)) {
|
if (mono_reg_info.assembly_dir.length() && DirAccess::exists(mono_reg_info.assembly_dir)) {
|
||||||
assembly_rootdir = mono_reg_info.assembly_dir;
|
r_assembly_rootdir = mono_reg_info.assembly_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mono_reg_info.config_dir.length() && DirAccess::exists(mono_reg_info.config_dir)) {
|
if (mono_reg_info.config_dir.length() && DirAccess::exists(mono_reg_info.config_dir)) {
|
||||||
config_dir = mono_reg_info.config_dir;
|
r_config_dir = mono_reg_info.config_dir;
|
||||||
}
|
}
|
||||||
#elif defined(OSX_ENABLED)
|
#elif defined(OSX_ENABLED)
|
||||||
const char *c_assembly_rootdir = mono_assembly_getrootdir();
|
const char *c_assembly_rootdir = mono_assembly_getrootdir();
|
||||||
@ -284,29 +271,24 @@ void GDMono::initialize() {
|
|||||||
String hint_config_dir = path::join(locations[i], "etc");
|
String hint_config_dir = path::join(locations[i], "etc");
|
||||||
|
|
||||||
if (FileAccess::exists(hint_mscorlib_path) && DirAccess::exists(hint_config_dir)) {
|
if (FileAccess::exists(hint_mscorlib_path) && DirAccess::exists(hint_config_dir)) {
|
||||||
assembly_rootdir = hint_assembly_rootdir;
|
r_assembly_rootdir = hint_assembly_rootdir;
|
||||||
config_dir = hint_config_dir;
|
r_config_dir = hint_config_dir;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif // TOOLS_ENABLED
|
|
||||||
|
|
||||||
String bundled_assembly_rootdir = GodotSharpDirs::get_data_mono_lib_dir();
|
|
||||||
String bundled_config_dir = GodotSharpDirs::get_data_mono_etc_dir();
|
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
|
||||||
if (DirAccess::exists(bundled_assembly_rootdir)) {
|
if (DirAccess::exists(bundled_assembly_rootdir)) {
|
||||||
assembly_rootdir = bundled_assembly_rootdir;
|
r_assembly_rootdir = bundled_assembly_rootdir;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DirAccess::exists(bundled_config_dir)) {
|
if (DirAccess::exists(bundled_config_dir)) {
|
||||||
config_dir = bundled_config_dir;
|
r_config_dir = bundled_config_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WINDOWS_ENABLED
|
#ifdef WINDOWS_ENABLED
|
||||||
if (assembly_rootdir.empty() || config_dir.empty()) {
|
if (r_assembly_rootdir.empty() || r_config_dir.empty()) {
|
||||||
ERR_PRINT("Cannot find Mono in the registry.");
|
ERR_PRINT("Cannot find Mono in the registry.");
|
||||||
// Assertion: if they are not set, then they weren't found in the registry
|
// Assertion: if they are not set, then they weren't found in the registry
|
||||||
CRASH_COND(mono_reg_info.assembly_dir.length() > 0 || mono_reg_info.config_dir.length() > 0);
|
CRASH_COND(mono_reg_info.assembly_dir.length() > 0 || mono_reg_info.config_dir.length() > 0);
|
||||||
@ -314,12 +296,32 @@ void GDMono::initialize() {
|
|||||||
#endif // WINDOWS_ENABLED
|
#endif // WINDOWS_ENABLED
|
||||||
|
|
||||||
#else
|
#else
|
||||||
// These are always the directories in export templates
|
// Export templates always use the bundled directories
|
||||||
assembly_rootdir = bundled_assembly_rootdir;
|
r_assembly_rootdir = bundled_assembly_rootdir;
|
||||||
config_dir = bundled_config_dir;
|
r_config_dir = bundled_config_dir;
|
||||||
#endif // TOOLS_ENABLED
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDMono::initialize() {
|
||||||
|
|
||||||
|
ERR_FAIL_NULL(Engine::get_singleton());
|
||||||
|
|
||||||
|
print_verbose("Mono: Initializing module...");
|
||||||
|
|
||||||
|
char *runtime_build_info = mono_get_runtime_build_info();
|
||||||
|
print_verbose("Mono JIT compiler version " + String(runtime_build_info));
|
||||||
|
mono_free(runtime_build_info);
|
||||||
|
|
||||||
|
_init_godot_api_hashes();
|
||||||
|
_init_exception_policy();
|
||||||
|
|
||||||
|
GDMonoLog::get_singleton()->initialize();
|
||||||
|
|
||||||
#if !defined(JAVASCRIPT_ENABLED)
|
#if !defined(JAVASCRIPT_ENABLED)
|
||||||
|
String assembly_rootdir;
|
||||||
|
String config_dir;
|
||||||
|
determine_mono_dirs(assembly_rootdir, config_dir);
|
||||||
|
|
||||||
// Leak if we call mono_set_dirs more than once
|
// Leak if we call mono_set_dirs more than once
|
||||||
mono_set_dirs(assembly_rootdir.length() ? assembly_rootdir.utf8().get_data() : NULL,
|
mono_set_dirs(assembly_rootdir.length() ? assembly_rootdir.utf8().get_data() : NULL,
|
||||||
config_dir.length() ? config_dir.utf8().get_data() : NULL);
|
config_dir.length() ? config_dir.utf8().get_data() : NULL);
|
||||||
@ -331,18 +333,6 @@ void GDMono::initialize() {
|
|||||||
GDMonoAndroid::register_android_dl_fallback();
|
GDMonoAndroid::register_android_dl_fallback();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{
|
|
||||||
PropertyInfo exc_policy_prop = PropertyInfo(Variant::INT, "mono/unhandled_exception_policy", PROPERTY_HINT_ENUM,
|
|
||||||
vformat("Terminate Application:%s,Log Error:%s", (int)POLICY_TERMINATE_APP, (int)POLICY_LOG_ERROR));
|
|
||||||
unhandled_exception_policy = (UnhandledExceptionPolicy)(int)GLOBAL_DEF(exc_policy_prop.name, (int)POLICY_TERMINATE_APP);
|
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info(exc_policy_prop.name, exc_policy_prop);
|
|
||||||
|
|
||||||
if (Engine::get_singleton()->is_editor_hint()) {
|
|
||||||
// Unhandled exceptions should not terminate the editor
|
|
||||||
unhandled_exception_policy = POLICY_LOG_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GDMonoAssembly::initialize();
|
GDMonoAssembly::initialize();
|
||||||
|
|
||||||
#if !defined(JAVASCRIPT_ENABLED)
|
#if !defined(JAVASCRIPT_ENABLED)
|
||||||
@ -358,9 +348,12 @@ void GDMono::initialize() {
|
|||||||
mono_install_unhandled_exception_hook(&unhandled_exception_hook, NULL);
|
mono_install_unhandled_exception_hook(&unhandled_exception_hook, NULL);
|
||||||
|
|
||||||
#ifndef TOOLS_ENABLED
|
#ifndef TOOLS_ENABLED
|
||||||
// Export templates only load the Mono runtime if the project uses it
|
// Exported games that don't use C# must still work. They likely don't ship with mscorlib.
|
||||||
if (!DirAccess::exists("res://.mono"))
|
// We only initialize the Mono runtime if we can find mscorlib. Otherwise it would crash.
|
||||||
|
if (GDMonoAssembly::find_assembly("mscorlib.dll").empty()) {
|
||||||
|
print_verbose("Mono: Skipping runtime initialization because 'mscorlib.dll' could not be found");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(WINDOWS_ENABLED) && !defined(NO_MONO_THREADS_SUSPEND_WORKAROUND)
|
#if !defined(WINDOWS_ENABLED) && !defined(NO_MONO_THREADS_SUSPEND_WORKAROUND)
|
||||||
@ -475,9 +468,8 @@ void GDMono::_register_internal_calls() {
|
|||||||
GodotSharpBindings::register_generated_icalls();
|
GodotSharpBindings::register_generated_icalls();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GDMono::_initialize_and_check_api_hashes() {
|
void GDMono::_init_godot_api_hashes() {
|
||||||
#ifdef MONO_GLUE_ENABLED
|
#if defined(MONO_GLUE_ENABLED) && defined(DEBUG_METHODS_ENABLED)
|
||||||
#ifdef DEBUG_METHODS_ENABLED
|
|
||||||
if (get_api_core_hash() != GodotSharpBindings::get_core_api_hash()) {
|
if (get_api_core_hash() != GodotSharpBindings::get_core_api_hash()) {
|
||||||
ERR_PRINT("Mono: Core API hash mismatch.");
|
ERR_PRINT("Mono: Core API hash mismatch.");
|
||||||
}
|
}
|
||||||
@ -487,8 +479,19 @@ void GDMono::_initialize_and_check_api_hashes() {
|
|||||||
ERR_PRINT("Mono: Editor API hash mismatch.");
|
ERR_PRINT("Mono: Editor API hash mismatch.");
|
||||||
}
|
}
|
||||||
#endif // TOOLS_ENABLED
|
#endif // TOOLS_ENABLED
|
||||||
#endif // DEBUG_METHODS_ENABLED
|
#endif // MONO_GLUE_ENABLED && DEBUG_METHODS_ENABLED
|
||||||
#endif // MONO_GLUE_ENABLED
|
}
|
||||||
|
|
||||||
|
void GDMono::_init_exception_policy() {
|
||||||
|
PropertyInfo exc_policy_prop = PropertyInfo(Variant::INT, "mono/unhandled_exception_policy", PROPERTY_HINT_ENUM,
|
||||||
|
vformat("Terminate Application:%s,Log Error:%s", (int)POLICY_TERMINATE_APP, (int)POLICY_LOG_ERROR));
|
||||||
|
unhandled_exception_policy = (UnhandledExceptionPolicy)(int)GLOBAL_DEF(exc_policy_prop.name, (int)POLICY_TERMINATE_APP);
|
||||||
|
ProjectSettings::get_singleton()->set_custom_property_info(exc_policy_prop.name, exc_policy_prop);
|
||||||
|
|
||||||
|
if (Engine::get_singleton()->is_editor_hint()) {
|
||||||
|
// Unhandled exceptions should not terminate the editor
|
||||||
|
unhandled_exception_policy = POLICY_LOG_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GDMono::add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly) {
|
void GDMono::add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly) {
|
||||||
|
@ -153,7 +153,8 @@ private:
|
|||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
uint64_t api_editor_hash;
|
uint64_t api_editor_hash;
|
||||||
#endif
|
#endif
|
||||||
void _initialize_and_check_api_hashes();
|
void _init_godot_api_hashes();
|
||||||
|
void _init_exception_policy();
|
||||||
|
|
||||||
GDMonoLog *gdmono_log;
|
GDMonoLog *gdmono_log;
|
||||||
|
|
||||||
@ -162,6 +163,7 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void add_mono_shared_libs_dir_to_path();
|
void add_mono_shared_libs_dir_to_path();
|
||||||
|
void determine_mono_dirs(String &r_assembly_rootdir, String &r_config_dir);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static GDMono *singleton;
|
static GDMono *singleton;
|
||||||
|
@ -62,6 +62,13 @@ void GDMonoAssembly::fill_search_dirs(Vector<String> &r_search_dirs, const Strin
|
|||||||
r_search_dirs.push_back(framework_dir.plus_file("Facades"));
|
r_search_dirs.push_back(framework_dir.plus_file("Facades"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(TOOLS_ENABLED)
|
||||||
|
String data_game_assemblies_dir = GodotSharpDirs::get_data_game_assemblies_dir();
|
||||||
|
if (!data_game_assemblies_dir.empty()) {
|
||||||
|
r_search_dirs.push_back(data_game_assemblies_dir);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (p_custom_config.length()) {
|
if (p_custom_config.length()) {
|
||||||
r_search_dirs.push_back(GodotSharpDirs::get_res_temp_assemblies_base_dir().plus_file(p_custom_config));
|
r_search_dirs.push_back(GodotSharpDirs::get_res_temp_assemblies_base_dir().plus_file(p_custom_config));
|
||||||
} else {
|
} else {
|
||||||
@ -147,10 +154,6 @@ MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **, vo
|
|||||||
|
|
||||||
(void)user_data; // UNUSED
|
(void)user_data; // UNUSED
|
||||||
|
|
||||||
if (search_dirs.empty()) {
|
|
||||||
fill_search_dirs(search_dirs);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// If we find the assembly here, we load it with 'mono_assembly_load_from_full',
|
// If we find the assembly here, we load it with 'mono_assembly_load_from_full',
|
||||||
// which in turn invokes load hooks before returning the MonoAssembly to us.
|
// which in turn invokes load hooks before returning the MonoAssembly to us.
|
||||||
@ -228,6 +231,33 @@ GDMonoAssembly *GDMonoAssembly::_load_assembly_search(const String &p_name, cons
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String GDMonoAssembly::find_assembly(const String &p_name) {
|
||||||
|
|
||||||
|
String path;
|
||||||
|
|
||||||
|
bool has_extension = p_name.ends_with(".dll") || p_name.ends_with(".exe");
|
||||||
|
|
||||||
|
for (int i = 0; i < search_dirs.size(); i++) {
|
||||||
|
const String &search_dir = search_dirs[i];
|
||||||
|
|
||||||
|
if (has_extension) {
|
||||||
|
path = search_dir.plus_file(p_name);
|
||||||
|
if (FileAccess::exists(path))
|
||||||
|
return path;
|
||||||
|
} else {
|
||||||
|
path = search_dir.plus_file(p_name + ".dll");
|
||||||
|
if (FileAccess::exists(path))
|
||||||
|
return path;
|
||||||
|
|
||||||
|
path = search_dir.plus_file(p_name + ".exe");
|
||||||
|
if (FileAccess::exists(path))
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return String();
|
||||||
|
}
|
||||||
|
|
||||||
GDMonoAssembly *GDMonoAssembly::_load_assembly_from(const String &p_name, const String &p_path, bool p_refonly) {
|
GDMonoAssembly *GDMonoAssembly::_load_assembly_from(const String &p_name, const String &p_path, bool p_refonly) {
|
||||||
|
|
||||||
GDMonoAssembly *assembly = memnew(GDMonoAssembly(p_name, p_path));
|
GDMonoAssembly *assembly = memnew(GDMonoAssembly(p_name, p_path));
|
||||||
@ -264,6 +294,8 @@ void GDMonoAssembly::_wrap_mono_assembly(MonoAssembly *assembly) {
|
|||||||
|
|
||||||
void GDMonoAssembly::initialize() {
|
void GDMonoAssembly::initialize() {
|
||||||
|
|
||||||
|
fill_search_dirs(search_dirs);
|
||||||
|
|
||||||
mono_install_assembly_search_hook(&assembly_search_hook, NULL);
|
mono_install_assembly_search_hook(&assembly_search_hook, NULL);
|
||||||
mono_install_assembly_refonly_search_hook(&assembly_refonly_search_hook, NULL);
|
mono_install_assembly_refonly_search_hook(&assembly_refonly_search_hook, NULL);
|
||||||
mono_install_assembly_preload_hook(&assembly_preload_hook, NULL);
|
mono_install_assembly_preload_hook(&assembly_preload_hook, NULL);
|
||||||
|
@ -122,6 +122,8 @@ public:
|
|||||||
|
|
||||||
GDMonoClass *get_object_derived_class(const StringName &p_class);
|
GDMonoClass *get_object_derived_class(const StringName &p_class);
|
||||||
|
|
||||||
|
static String find_assembly(const String &p_name);
|
||||||
|
|
||||||
static void fill_search_dirs(Vector<String> &r_search_dirs, const String &p_custom_config = String(), const String &p_custom_bcl_dir = String());
|
static void fill_search_dirs(Vector<String> &r_search_dirs, const String &p_custom_config = String(), const String &p_custom_bcl_dir = String());
|
||||||
|
|
||||||
static GDMonoAssembly *load_from(const String &p_name, const String &p_path, bool p_refonly);
|
static GDMonoAssembly *load_from(const String &p_name, const String &p_path, bool p_refonly);
|
||||||
|
Loading…
Reference in New Issue
Block a user