meson: Improve detection of qsort_r().

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>
This commit is contained in:
Xin LI 2022-09-22 23:05:53 -07:00 committed by Marge Bot
parent 6be7c2ef51
commit 2905dd7951
2 changed files with 33 additions and 5 deletions

View 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

View 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