meson: Improve detection of qsort_r().
authorXin LI <delphij@FreeBSD.org>
Fri, 23 Sep 2022 06:05:53 +0000 (23:05 -0700)
committerMarge Bot <emma+marge@anholt.net>
Fri, 23 Sep 2022 07:45:01 +0000 (07:45 +0000)
Instead of trying to guess the interface style by solely checking
the OS name, check if a fake test program can be built and linked.
This will give more accurate result when FreeBSD and other systems
moved to the interface based on GNU qsort_r().

Reviewed-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Eric Engestrom <eric@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18527>

meson.build
src/util/u_qsort.h

index 43d1435..e9d6b77 100644 (file)
@@ -1453,7 +1453,6 @@ functions_to_detect = {
   'flock': '',
   'strtok_r': '',
   'getrandom': '',
-  'qsort_r': '',
   'qsort_s': '',
 }
 
@@ -1463,6 +1462,37 @@ foreach f, prefix: functions_to_detect
   endif
 endforeach
 
+if cpp.links('''
+    #define _GNU_SOURCE
+    #include <stdlib.h>
+
+    static int dcomp(const void *l, const void *r, void *t) { return 0; }
+
+    int main(int ac, char **av) {
+      int arr[] = { 1 };
+      void *t = NULL;
+      qsort_r((void*)&arr[0], 1, 1, dcomp, t);
+      return (0);
+    }''',
+    args : pre_args,
+    name : 'GNU qsort_r')
+  pre_args += '-DHAVE_GNU_QSORT_R'
+elif cpp.links('''
+    #include <stdlib.h>
+
+    static int dcomp(void *t, const void *l, const void *r) { return 0; }
+
+    int main(int ac, char **av) {
+      int arr[] = { 1 };
+      void *t = NULL;
+      qsort_r((void*)&arr[0], 1, 1, t, dcomp);
+      return (0);
+    }''',
+    args : pre_args,
+    name : 'BSD qsort_r')
+  pre_args += '-DHAVE_BSD_QSORT_R'
+endif
+
 if cc.has_header_symbol('time.h', 'struct timespec')
    pre_args += '-DHAVE_STRUCT_TIMESPEC'
 endif
index 6ab9d49..454d383 100644 (file)
@@ -56,11 +56,10 @@ util_qsort_r(void *base, size_t nmemb, size_t size,
              int (*compar)(const void *, const void *, void *),
              void *arg)
 {
-#if HAVE_QSORT_R
-#  if defined(__GLIBC__)
+#if HAVE_GNU_QSORT_R
    /* GNU extension added in glibc 2.8 */
    qsort_r(base, nmemb, size, compar, arg);
-#  elif (DETECT_OS_APPLE || DETECT_OS_BSD)
+#elif HAVE_BSD_QSORT_R
    /* BSD/macOS qsort_r takes "arg" before the comparison function and it
     * pass the "arg" before the elements.
     */
@@ -69,7 +68,6 @@ util_qsort_r(void *base, size_t nmemb, size_t size,
       arg
    };
    qsort_r(base, nmemb, size, &data, util_qsort_adapter);
-#  endif
 #elif HAVE_QSORT_S
 #  ifdef _WIN32
    /* MSVC/MinGW qsort_s takes "arg" after the comparison function and it