[mono] Fix iOS/tvOS build with Xcode 14 (#76433)
authorAlexander Köplinger <alex.koeplinger@outlook.com>
Fri, 30 Sep 2022 14:11:13 +0000 (16:11 +0200)
committerGitHub <noreply@github.com>
Fri, 30 Sep 2022 14:11:13 +0000 (16:11 +0200)
Before Xcode 14 the `objc_super` struct definition in the SDK headers looked like this:

```
#if !defined(__cplusplus)  &&  !__OBJC2__
    /* For compatibility with old objc-runtime.h header */
    __unsafe_unretained _Nonnull Class class;
#else
    __unsafe_unretained _Nonnull Class super_class;
#endif
```

With Xcode 14 however the iOS/tvOS SDK header was changed to only define `super_class`, but the MacOSX SDK stayed the same.

Added CMake detection of this case so we can compile both on older and newer Xcode SDKs across platforms.

src/mono/cmake/config.h.in
src/mono/cmake/configure.cmake
src/mono/mono/utils/mono-threads-mach-helper.c

index 4ac722c..71753f1 100644 (file)
 /* Define to 1 if `st_atimespec' is a member of `struct stat'. */
 #cmakedefine HAVE_STRUCT_STAT_ST_ATIMESPEC 1
 
+/* Define to 1 if `super_class' is a member of `struct objc_super'. */
+#cmakedefine HAVE_OBJC_SUPER_SUPER_CLASS 1
+
 /* Define to 1 if you have the <sys/time.h> header file. */
 #cmakedefine HAVE_SYS_TIME_H 1
 
index 51cb315..ae55fd1 100644 (file)
@@ -129,6 +129,10 @@ check_struct_has_member("struct sockaddr_in6" sin6_len "netinet/in.h" HAVE_SOCKA
 check_struct_has_member("struct stat" st_atim "sys/types.h;sys/stat.h;unistd.h" HAVE_STRUCT_STAT_ST_ATIM)
 check_struct_has_member("struct stat" st_atimespec "sys/types.h;sys/stat.h;unistd.h" HAVE_STRUCT_STAT_ST_ATIMESPEC)
 
+if (HOST_DARWIN)
+  check_struct_has_member("struct objc_super" super_class "objc/runtime.h;objc/message.h" HAVE_OBJC_SUPER_SUPER_CLASS)
+endif()
+
 check_type_size("int" SIZEOF_INT)
 check_type_size("void*" SIZEOF_VOID_P)
 check_type_size("long" SIZEOF_LONG)
index 0efe506..64b49ce 100644 (file)
@@ -59,10 +59,10 @@ mono_dead_letter_dealloc (id self, SEL _cmd)
 {
        struct objc_super super;
        super.receiver = self;
-#if !defined(__cplusplus) && !__OBJC2__
-       super.class = nsobject;
-#else
+#if defined(__cplusplus) || defined(HAVE_OBJC_SUPER_SUPER_CLASS)
        super.super_class = nsobject;
+#else
+       super.class = nsobject;
 #endif
        void (*objc_msgSendSuper_op)(struct objc_super *, SEL) = (void (*)(struct objc_super *, SEL)) objc_msgSendSuper;
        objc_msgSendSuper_op (&super, dealloc);