From c4b497e8d41d8eb343d744707d089753bb836f39 Mon Sep 17 00:00:00 2001 From: David McFarland Date: Sun, 18 May 2025 21:10:52 -0300 Subject: [PATCH] godot3-mono: fix compile error with mono 6.14 This was introduced with #401409. --- pkgs/development/tools/godot/3/default.nix | 3 + ...e-MonoGCHandle-into-gdmono-namespace.patch | 403 ++++++++++++++++++ 2 files changed, 406 insertions(+) create mode 100644 pkgs/development/tools/godot/3/patches/move-MonoGCHandle-into-gdmono-namespace.patch diff --git a/pkgs/development/tools/godot/3/default.nix b/pkgs/development/tools/godot/3/default.nix index 576422aed763..ca22c59c401a 100644 --- a/pkgs/development/tools/godot/3/default.nix +++ b/pkgs/development/tools/godot/3/default.nix @@ -83,6 +83,9 @@ stdenv.mkDerivation (self: { # of the OS. This isn't as surgical as just fixing the PATH, but it seems to work, and # seems to be the Nix community's current strategy when using Scons. /SConstruct/dontClobberEnvironment.patch + # Fix compile error with mono 6.14 + # https://github.com/godotengine/godot/pull/106578 + /move-MonoGCHandle-into-gdmono-namespace.patch ]; enableParallelBuilding = true; diff --git a/pkgs/development/tools/godot/3/patches/move-MonoGCHandle-into-gdmono-namespace.patch b/pkgs/development/tools/godot/3/patches/move-MonoGCHandle-into-gdmono-namespace.patch new file mode 100644 index 000000000000..6abfec210ea9 --- /dev/null +++ b/pkgs/development/tools/godot/3/patches/move-MonoGCHandle-into-gdmono-namespace.patch @@ -0,0 +1,403 @@ +From 7f90c622f5f04ad6aed5729913684a64827b751f Mon Sep 17 00:00:00 2001 +From: David McFarland +Date: Sun, 18 May 2025 20:56:50 -0300 +Subject: [PATCH] mono: move MonoGCHandle into gdmono namespace + +This conflicts with ::MonoGCHandle in mono 6.14 (maintained by winehq). +--- + modules/mono/csharp_script.cpp | 44 +++++++++++----------- + modules/mono/csharp_script.h | 10 ++--- + modules/mono/glue/base_object_glue.cpp | 4 +- + modules/mono/mono_gc_handle.cpp | 4 ++ + modules/mono/mono_gc_handle.h | 4 ++ + modules/mono/mono_gd/gd_mono_cache.cpp | 4 +- + modules/mono/mono_gd/gd_mono_cache.h | 2 +- + modules/mono/mono_gd/gd_mono_internals.cpp | 4 +- + modules/mono/mono_gd/gd_mono_utils.cpp | 4 +- + modules/mono/signal_awaiter_utils.cpp | 2 +- + modules/mono/signal_awaiter_utils.h | 4 +- + 11 files changed, 47 insertions(+), 39 deletions(-) + +diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp +index fa041f4cba..2ad9722eca 100644 +--- a/modules/mono/csharp_script.cpp ++++ b/modules/mono/csharp_script.cpp +@@ -653,7 +653,7 @@ void CSharpLanguage::pre_unsafe_unreference(Object *p_obj) { + + void CSharpLanguage::frame() { + if (gdmono && gdmono->is_runtime_initialized() && gdmono->get_core_api_assembly() != NULL) { +- const Ref &task_scheduler_handle = GDMonoCache::cached_data.task_scheduler_handle; ++ const Ref &task_scheduler_handle = GDMonoCache::cached_data.task_scheduler_handle; + + if (task_scheduler_handle.is_valid()) { + MonoObject *task_scheduler = task_scheduler_handle->get_target(); +@@ -1189,15 +1189,15 @@ void CSharpLanguage::set_language_index(int p_idx) { + lang_idx = p_idx; + } + +-void CSharpLanguage::release_script_gchandle(Ref &p_gchandle) { ++void CSharpLanguage::release_script_gchandle(Ref &p_gchandle) { + if (!p_gchandle->is_released()) { // Do not lock unnecessarily + MutexLock lock(get_singleton()->script_gchandle_release_mutex); + p_gchandle->release(); + } + } + +-void CSharpLanguage::release_script_gchandle(MonoObject *p_expected_obj, Ref &p_gchandle) { +- uint32_t pinned_gchandle = MonoGCHandle::new_strong_handle_pinned(p_expected_obj); // We might lock after this, so pin it ++void CSharpLanguage::release_script_gchandle(MonoObject *p_expected_obj, Ref &p_gchandle) { ++ uint32_t pinned_gchandle = gdmono::MonoGCHandle::new_strong_handle_pinned(p_expected_obj); // We might lock after this, so pin it + + if (!p_gchandle->is_released()) { // Do not lock unnecessarily + MutexLock lock(get_singleton()->script_gchandle_release_mutex); +@@ -1213,7 +1213,7 @@ void CSharpLanguage::release_script_gchandle(MonoObject *p_expected_obj, Ref::Element *)data)->get(); +- Ref &gchandle = script_binding.gchandle; ++ Ref &gchandle = script_binding.gchandle; + + if (!script_binding.inited) + return; +@@ -1368,9 +1368,9 @@ void CSharpLanguage::refcount_incremented_instance_binding(Object *p_object) { + return; // Called after the managed side was collected, so nothing to do here + + // Release the current weak handle and replace it with a strong handle. +- uint32_t strong_gchandle = MonoGCHandle::new_strong_handle(target); ++ uint32_t strong_gchandle = gdmono::MonoGCHandle::new_strong_handle(target); + gchandle->release(); +- gchandle->set_handle(strong_gchandle, MonoGCHandle::STRONG_HANDLE); ++ gchandle->set_handle(strong_gchandle, gdmono::MonoGCHandle::STRONG_HANDLE); + } + } + +@@ -1386,7 +1386,7 @@ bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) { + CRASH_COND(!data); + + CSharpScriptBinding &script_binding = ((Map::Element *)data)->get(); +- Ref &gchandle = script_binding.gchandle; ++ Ref &gchandle = script_binding.gchandle; + + int refcount = ref_owner->reference_get_count(); + +@@ -1404,9 +1404,9 @@ bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) { + return refcount == 0; // Called after the managed side was collected, so nothing to do here + + // Release the current strong handle and replace it with a weak handle. +- uint32_t weak_gchandle = MonoGCHandle::new_weak_handle(target); ++ uint32_t weak_gchandle = gdmono::MonoGCHandle::new_weak_handle(target); + gchandle->release(); +- gchandle->set_handle(weak_gchandle, MonoGCHandle::WEAK_HANDLE); ++ gchandle->set_handle(weak_gchandle, gdmono::MonoGCHandle::WEAK_HANDLE); + + return false; + } +@@ -1414,7 +1414,7 @@ bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) { + return refcount == 0; + } + +-CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpScript *p_script, const Ref &p_gchandle) { ++CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpScript *p_script, const Ref &p_gchandle) { + CSharpInstance *instance = memnew(CSharpInstance); + + Reference *ref = Object::cast_to(p_owner); +@@ -1832,7 +1832,7 @@ MonoObject *CSharpInstance::_internal_new_managed() { + } + + // Tie managed to unmanaged +- gchandle = MonoGCHandle::create_strong(mono_object); ++ gchandle = gdmono::MonoGCHandle::create_strong(mono_object); + + if (base_ref) + _reference_owner_unsafe(); // Here, after assigning the gchandle (for the refcount_incremented callback) +@@ -1902,9 +1902,9 @@ void CSharpInstance::refcount_incremented() { + // so the owner must hold the managed side alive again to avoid it from being GCed. + + // Release the current weak handle and replace it with a strong handle. +- uint32_t strong_gchandle = MonoGCHandle::new_strong_handle(gchandle->get_target()); ++ uint32_t strong_gchandle = gdmono::MonoGCHandle::new_strong_handle(gchandle->get_target()); + gchandle->release(); +- gchandle->set_handle(strong_gchandle, MonoGCHandle::STRONG_HANDLE); ++ gchandle->set_handle(strong_gchandle, gdmono::MonoGCHandle::STRONG_HANDLE); + } + } + +@@ -1925,9 +1925,9 @@ bool CSharpInstance::refcount_decremented() { + // the managed instance takes responsibility of deleting the owner when GCed. + + // Release the current strong handle and replace it with a weak handle. +- uint32_t weak_gchandle = MonoGCHandle::new_weak_handle(gchandle->get_target()); ++ uint32_t weak_gchandle = gdmono::MonoGCHandle::new_weak_handle(gchandle->get_target()); + gchandle->release(); +- gchandle->set_handle(weak_gchandle, MonoGCHandle::WEAK_HANDLE); ++ gchandle->set_handle(weak_gchandle, gdmono::MonoGCHandle::WEAK_HANDLE); + + return false; + } +@@ -2298,7 +2298,7 @@ bool CSharpScript::_update_exports(PlaceHolderScriptInstance *p_instance_to_upda + return false; + } + +- tmp_pinned_gchandle = MonoGCHandle::new_strong_handle_pinned(tmp_object); // pin it (not sure if needed) ++ tmp_pinned_gchandle = gdmono::MonoGCHandle::new_strong_handle_pinned(tmp_object); // pin it (not sure if needed) + + GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), 0); + +@@ -2313,7 +2313,7 @@ bool CSharpScript::_update_exports(PlaceHolderScriptInstance *p_instance_to_upda + if (ctor_exc) { + // TODO: Should we free 'tmp_native' if the exception was thrown after its creation? + +- MonoGCHandle::free_handle(tmp_pinned_gchandle); ++ gdmono::MonoGCHandle::free_handle(tmp_pinned_gchandle); + tmp_object = NULL; + + ERR_PRINT("Exception thrown from constructor of temporary MonoObject:"); +@@ -2409,7 +2409,7 @@ bool CSharpScript::_update_exports(PlaceHolderScriptInstance *p_instance_to_upda + GDMonoUtils::debug_print_unhandled_exception(exc); + } + +- MonoGCHandle::free_handle(tmp_pinned_gchandle); ++ gdmono::MonoGCHandle::free_handle(tmp_pinned_gchandle); + tmp_object = NULL; + + if (tmp_native && !base_ref) { +@@ -2970,7 +2970,7 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg + } + + // Tie managed to unmanaged +- instance->gchandle = MonoGCHandle::create_strong(mono_object); ++ instance->gchandle = gdmono::MonoGCHandle::create_strong(mono_object); + + if (instance->base_ref) + instance->_reference_owner_unsafe(); // Here, after assigning the gchandle (for the refcount_incremented callback) +diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h +index 3be55848d5..7b3981ef90 100644 +--- a/modules/mono/csharp_script.h ++++ b/modules/mono/csharp_script.h +@@ -220,7 +220,7 @@ class CSharpInstance : public ScriptInstance { + bool destructing_script_instance; + + Ref script; +- Ref gchandle; ++ Ref gchandle; + + bool _reference_owner_unsafe(); + +@@ -236,7 +236,7 @@ class CSharpInstance : public ScriptInstance { + + // Do not use unless you know what you are doing + friend void GDMonoInternals::tie_managed_to_unmanaged(MonoObject *, Object *); +- static CSharpInstance *create_for_managed_type(Object *p_owner, CSharpScript *p_script, const Ref &p_gchandle); ++ static CSharpInstance *create_for_managed_type(Object *p_owner, CSharpScript *p_script, const Ref &p_gchandle); + + void _call_multilevel(MonoObject *p_mono_object, const StringName &p_method, const Variant **p_args, int p_argcount); + +@@ -293,7 +293,7 @@ struct CSharpScriptBinding { + bool inited; + StringName type_name; + GDMonoClass *wrapper_class; +- Ref gchandle; ++ Ref gchandle; + Object *owner; + }; + +@@ -371,8 +371,8 @@ public: + _FORCE_INLINE_ EditorPlugin *get_godotsharp_editor() const { return godotsharp_editor; } + #endif + +- static void release_script_gchandle(Ref &p_gchandle); +- static void release_script_gchandle(MonoObject *p_expected_obj, Ref &p_gchandle); ++ static void release_script_gchandle(Ref &p_gchandle); ++ static void release_script_gchandle(MonoObject *p_expected_obj, Ref &p_gchandle); + + bool debug_break(const String &p_error, bool p_allow_continue = true); + bool debug_break_parse(const String &p_file, int p_line, const String &p_error); +diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp +index 7a3ec459de..4931583884 100644 +--- a/modules/mono/glue/base_object_glue.cpp ++++ b/modules/mono/glue/base_object_glue.cpp +@@ -70,7 +70,7 @@ void godot_icall_Object_Disposed(MonoObject *p_obj, Object *p_ptr) { + if (data) { + CSharpScriptBinding &script_binding = ((Map::Element *)data)->get(); + if (script_binding.inited) { +- Ref &gchandle = script_binding.gchandle; ++ Ref &gchandle = script_binding.gchandle; + if (gchandle.is_valid()) { + CSharpLanguage::release_script_gchandle(p_obj, gchandle); + } +@@ -117,7 +117,7 @@ void godot_icall_Reference_Disposed(MonoObject *p_obj, Object *p_ptr, MonoBoolea + if (data) { + CSharpScriptBinding &script_binding = ((Map::Element *)data)->get(); + if (script_binding.inited) { +- Ref &gchandle = script_binding.gchandle; ++ Ref &gchandle = script_binding.gchandle; + if (gchandle.is_valid()) { + CSharpLanguage::release_script_gchandle(p_obj, gchandle); + } +diff --git a/modules/mono/mono_gc_handle.cpp b/modules/mono/mono_gc_handle.cpp +index eb2227dd78..e70c701331 100644 +--- a/modules/mono/mono_gc_handle.cpp ++++ b/modules/mono/mono_gc_handle.cpp +@@ -32,6 +32,8 @@ + + #include "mono_gd/gd_mono.h" + ++namespace gdmono { ++ + uint32_t MonoGCHandle::new_strong_handle(MonoObject *p_object) { + return mono_gchandle_new(p_object, /* pinned: */ false); + } +@@ -76,3 +78,5 @@ MonoGCHandle::MonoGCHandle(uint32_t p_handle, HandleType p_handle_type) { + MonoGCHandle::~MonoGCHandle() { + release(); + } ++ ++} // namespace gdmono +diff --git a/modules/mono/mono_gc_handle.h b/modules/mono/mono_gc_handle.h +index 5f99a46479..28fcbd7a78 100644 +--- a/modules/mono/mono_gc_handle.h ++++ b/modules/mono/mono_gc_handle.h +@@ -35,6 +35,8 @@ + + #include "core/reference.h" + ++namespace gdmono { ++ + class MonoGCHandle : public Reference { + GDCLASS(MonoGCHandle, Reference); + +@@ -72,4 +74,6 @@ public: + ~MonoGCHandle(); + }; + ++} // namespace gdmono ++ + #endif // MONO_GC_HANDLE_H +diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp +index 2ece9d0f36..976a8f2ff2 100644 +--- a/modules/mono/mono_gd/gd_mono_cache.cpp ++++ b/modules/mono/mono_gd/gd_mono_cache.cpp +@@ -178,7 +178,7 @@ void CachedData::clear_godot_api_cache() { + + // End of MarshalUtils methods + +- task_scheduler_handle = Ref(); ++ task_scheduler_handle = Ref(); + } + + #define GODOT_API_CLASS(m_class) (GDMono::get_singleton()->get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, #m_class)) +@@ -300,7 +300,7 @@ void update_godot_api_cache() { + // TODO Move to CSharpLanguage::init() and do handle disposal + MonoObject *task_scheduler = mono_object_new(mono_domain_get(), GODOT_API_CLASS(GodotTaskScheduler)->get_mono_ptr()); + GDMonoUtils::runtime_object_init(task_scheduler, GODOT_API_CLASS(GodotTaskScheduler)); +- cached_data.task_scheduler_handle = MonoGCHandle::create_strong(task_scheduler); ++ cached_data.task_scheduler_handle = gdmono::MonoGCHandle::create_strong(task_scheduler); + + cached_data.godot_api_cache_updated = true; + } +diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h +index 2ed8482552..a4e05bbf5b 100644 +--- a/modules/mono/mono_gd/gd_mono_cache.h ++++ b/modules/mono/mono_gd/gd_mono_cache.h +@@ -149,7 +149,7 @@ struct CachedData { + + // End of MarshalUtils methods + +- Ref task_scheduler_handle; ++ Ref task_scheduler_handle; + + bool corlib_cache_updated; + bool godot_api_cache_updated; +diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp +index 4d2209ccec..a0102335b7 100644 +--- a/modules/mono/mono_gd/gd_mono_internals.cpp ++++ b/modules/mono/mono_gd/gd_mono_internals.cpp +@@ -71,7 +71,7 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) { + script_binding.inited = true; + script_binding.type_name = NATIVE_GDMONOCLASS_NAME(klass); + script_binding.wrapper_class = klass; +- script_binding.gchandle = ref ? MonoGCHandle::create_weak(managed) : MonoGCHandle::create_strong(managed); ++ script_binding.gchandle = ref ? gdmono::MonoGCHandle::create_weak(managed) : gdmono::MonoGCHandle::create_strong(managed); + script_binding.owner = unmanaged; + + if (ref) { +@@ -101,7 +101,7 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) { + return; + } + +- Ref gchandle = ref ? MonoGCHandle::create_weak(managed) : MonoGCHandle::create_strong(managed); ++ Ref gchandle = ref ? gdmono::MonoGCHandle::create_weak(managed) : gdmono::MonoGCHandle::create_strong(managed); + + Ref script = CSharpScript::create_for_managed_type(klass, native); + +diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp +index 4b6b0af21f..0f6545c6ef 100644 +--- a/modules/mono/mono_gd/gd_mono_utils.cpp ++++ b/modules/mono/mono_gd/gd_mono_utils.cpp +@@ -83,7 +83,7 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) { + } + } + +- Ref &gchandle = script_binding.gchandle; ++ Ref &gchandle = script_binding.gchandle; + ERR_FAIL_COND_V(gchandle.is_null(), NULL); + + MonoObject *target = gchandle->get_target(); +@@ -103,7 +103,7 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) { + MonoObject *mono_object = GDMonoUtils::create_managed_for_godot_object(script_binding.wrapper_class, script_binding.type_name, unmanaged); + ERR_FAIL_NULL_V(mono_object, NULL); + +- gchandle->set_handle(MonoGCHandle::new_strong_handle(mono_object), MonoGCHandle::STRONG_HANDLE); ++ gchandle->set_handle(gdmono::MonoGCHandle::new_strong_handle(mono_object), gdmono::MonoGCHandle::STRONG_HANDLE); + + // Tie managed to unmanaged + Reference *ref = Object::cast_to(unmanaged); +diff --git a/modules/mono/signal_awaiter_utils.cpp b/modules/mono/signal_awaiter_utils.cpp +index 6c7bb1028c..f3adf4cd77 100644 +--- a/modules/mono/signal_awaiter_utils.cpp ++++ b/modules/mono/signal_awaiter_utils.cpp +@@ -117,7 +117,7 @@ void SignalAwaiterHandle::_bind_methods() { + } + + SignalAwaiterHandle::SignalAwaiterHandle(MonoObject *p_managed) : +- MonoGCHandle(MonoGCHandle::new_strong_handle(p_managed), STRONG_HANDLE) { ++ gdmono::MonoGCHandle(gdmono::MonoGCHandle::new_strong_handle(p_managed), STRONG_HANDLE) { + #ifdef DEBUG_ENABLED + conn_target_id = 0; + #endif +diff --git a/modules/mono/signal_awaiter_utils.h b/modules/mono/signal_awaiter_utils.h +index 5a8154b001..8cf20e98fd 100644 +--- a/modules/mono/signal_awaiter_utils.h ++++ b/modules/mono/signal_awaiter_utils.h +@@ -39,8 +39,8 @@ namespace SignalAwaiterUtils { + Error connect_signal_awaiter(Object *p_source, const String &p_signal, Object *p_target, MonoObject *p_awaiter); + } + +-class SignalAwaiterHandle : public MonoGCHandle { +- GDCLASS(SignalAwaiterHandle, MonoGCHandle); ++class SignalAwaiterHandle : public gdmono::MonoGCHandle { ++ GDCLASS(SignalAwaiterHandle, gdmono::MonoGCHandle); + + bool completed; + +-- +2.49.0 +