Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tzdzQ-004g9i-Vo for pgsql-hackers@arkaria.postgresql.org; Tue, 01 Apr 2025 15:57:25 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1tzdzP-0041tA-MC for pgsql-hackers@arkaria.postgresql.org; Tue, 01 Apr 2025 15:57:23 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tzdzP-0041t2-8P for pgsql-hackers@lists.postgresql.org; Tue, 01 Apr 2025 15:57:23 +0000 Received: from sss.pgh.pa.us ([68.162.161.243]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tzdzM-002Myi-3D for pgsql-hackers@lists.postgresql.org; Tue, 01 Apr 2025 15:57:22 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.15.2/8.15.2) with ESMTP id 531FvI02385135; Tue, 1 Apr 2025 11:57:18 -0400 From: Tom Lane To: pgsql-hackers@lists.postgresql.org cc: Peter Eisentraut Subject: macOS 15.4 versus strchrnul() MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0" Content-ID: <385058.1743522980.0@sss.pgh.pa.us> Date: Tue, 01 Apr 2025 11:57:18 -0400 Message-ID: <385134.1743523038@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="us-ascii" Content-ID: <385058.1743522980.1@sss.pgh.pa.us> Content-Transfer-Encoding: quoted-printable Last night I updated the machine that hosts sifaka and indri to spankin' new macOS Sequoia 15.4, and that promptly broke the build on both animals: snprintf.c:350:1: error: static declaration of 'strchrnul' follows non-sta= tic declaration 350 | strchrnul(const char *s, int c) | ^ /Library/Developer/CommandLineTools/SDKs/MacOSX15.4.sdk/usr/include/_strin= g.h:198:9: note: previous declaration is here 198 | strchrnul(const char *__s, int __c); | ^ snprintf.c:414:27: error: 'strchrnul' is only available on macOS 15.4 or n= ewer [-Werror,-Wunguarded-availability-new] 414 | const char *next_pct =3D strchrnul(format = + 1, '%'); | ^~~~~~~~~ /Library/Developer/CommandLineTools/SDKs/MacOSX15.4.sdk/usr/include/_strin= g.h:198:9: note: 'strchrnul' has been marked as being introduced in macOS = 15.4 here, but the deployment target is macOS 15.0.0 198 | strchrnul(const char *__s, int __c); | ^ snprintf.c:414:27: note: enclose 'strchrnul' in a __builtin_available chec= k to silence this warning That is, the function exists now in macOS' libc, and so configure's does-it-link test for HAVE_STRCHRNUL finds it, but will not let you use it unless you monkey around with export MACOSX_DEPLOYMENT_TARGET=3D15.4 or similar. I don't think we want to require people to do that, so we need to fix things so that the code works with or without a deployment target that satisfies . This is pretty reminiscent of a problem that we faced a couple years ago with preadv and pwritev, and solved in commit f014b1b9b by depending on AC_CHECK_DECLS instead of AC_CHECK_FUNCS. I made a patch (attached) to solve this similarly. Interestingly, this actually makes the one usage in snprintf.c simpler, since we no longer need to special-case the situation where GNU doesn't agree with the does-it-link test. However ... testing this here shows that it fixes the autoconf build as desired, with or without MACOSX_DEPLOYMENT_TARGET. But the meson version *does not work*: it will set HAVE_DECL_STRCHRNUL to 1 with or without MACOSX_DEPLOYMENT_TARGET, and in the "without" case the build then blows up. I speculate that the meson test for preadv/pwritev has never worked for macOS either, and we haven't noticed because nobody has tried to build with meson on a machine with low enough default deployment target to not have preadv/pwritev. I do not know nearly enough about meson to fix that test; can anyone help? regards, tom lane ------- =_aaaaaaaaaa0 Content-Type: text/x-diff; name="wip-fix-configure-strchrnul-check.patch"; charset="us-ascii" Content-ID: <385058.1743522980.2@sss.pgh.pa.us> Content-Description: wip-fix-configure-strchrnul-check.patch Content-Transfer-Encoding: quoted-printable diff --git a/configure b/configure index 30d949c3c46..3d0e701c745 100755 --- a/configure +++ b/configure @@ -15401,7 +15401,7 @@ fi LIBS_including_readline=3D"$LIBS" LIBS=3D`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'` = -for ac_func in backtrace_symbols copyfile copy_file_range elf_aux_info ge= tauxval getifaddrs getpeerucred inet_pton kqueue localeconv_l mbstowcs_l m= emset_s posix_fallocate ppoll pthread_is_threaded_np setproctitle setproct= itle_fast strchrnul strsignal syncfs sync_file_range uselocale wcstombs_l +for ac_func in backtrace_symbols copyfile copy_file_range elf_aux_info ge= tauxval getifaddrs getpeerucred inet_pton kqueue localeconv_l mbstowcs_l m= emset_s posix_fallocate ppoll pthread_is_threaded_np setproctitle setproct= itle_fast strsignal syncfs sync_file_range uselocale wcstombs_l do : as_ac_var=3D`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -15955,6 +15955,18 @@ cat >>confdefs.h <<_ACEOF #define HAVE_DECL_PWRITEV $ac_have_decl _ACEOF = +ac_fn_c_check_decl "$LINENO" "strchrnul" "ac_cv_have_decl_strchrnul" "#in= clude +" +if test "x$ac_cv_have_decl_strchrnul" =3D xyes; then : + ac_have_decl=3D1 +else + ac_have_decl=3D0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRCHRNUL $ac_have_decl +_ACEOF + = # This is probably only present on macOS, but may as well check always ac_fn_c_check_decl "$LINENO" "F_FULLFSYNC" "ac_cv_have_decl_F_FULLFSYNC" = "#include diff --git a/configure.ac b/configure.ac index 25cdfcf65af..47a287926bc 100644 --- a/configure.ac +++ b/configure.ac @@ -1772,7 +1772,6 @@ AC_CHECK_FUNCS(m4_normalize([ pthread_is_threaded_np setproctitle setproctitle_fast - strchrnul strsignal syncfs sync_file_range @@ -1812,6 +1811,7 @@ AC_CHECK_DECLS([strlcat, strlcpy, strnlen, strsep]) # won't handle deployment target restrictions on macOS AC_CHECK_DECLS([preadv], [], [], [#include ]) AC_CHECK_DECLS([pwritev], [], [], [#include ]) +AC_CHECK_DECLS([strchrnul], [], [], [#include ]) = # This is probably only present on macOS, but may as well check always AC_CHECK_DECLS(F_FULLFSYNC, [], [], [#include ]) diff --git a/meson.build b/meson.build index b8da4966297..6932a0f00f7 100644 --- a/meson.build +++ b/meson.build @@ -2577,6 +2577,7 @@ decl_checks =3D [ decl_checks +=3D [ ['preadv', 'sys/uio.h'], ['pwritev', 'sys/uio.h'], + ['strchrnul', 'string.h'], ] = # Check presence of some optional LLVM functions. @@ -2802,7 +2803,6 @@ func_checks =3D [ ['shm_unlink', {'dependencies': [rt_dep], 'define': false}], ['shmget', {'dependencies': [cygipc_dep], 'define': false}], ['socket', {'dependencies': [socket_dep], 'define': false}], - ['strchrnul'], ['strerror_r', {'dependencies': [thread_dep]}], ['strlcat'], ['strlcpy'], diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 92f0616c400..2ac61575883 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -103,6 +103,10 @@ don't. */ #undef HAVE_DECL_PWRITEV = +/* Define to 1 if you have the declaration of `strchrnul', and to 0 if yo= u + don't. */ +#undef HAVE_DECL_STRCHRNUL + /* Define to 1 if you have the declaration of `strlcat', and to 0 if you don't. */ #undef HAVE_DECL_STRLCAT @@ -373,9 +377,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H = -/* Define to 1 if you have the `strchrnul' function. */ -#undef HAVE_STRCHRNUL - /* Define to 1 if you have the `strerror_r' function. */ #undef HAVE_STRERROR_R = diff --git a/src/port/snprintf.c b/src/port/snprintf.c index f8f2018ea0c..d0e99fdb072 100644 --- a/src/port/snprintf.c +++ b/src/port/snprintf.c @@ -343,8 +343,15 @@ static void trailing_pad(int padlen, PrintfTarget *ta= rget); * * Note: glibc declares this as returning "char *", but that would requir= e * casting away const internally, so we don't follow that detail. + * + * Note: macOS has this too as of Sequoia 15.4, but it's hidden behind + * a deployment-target check that causes compile errors if the deployment + * target isn't high enough. To work around that, use a macro to redefin= e + * what "strchrnul" means. */ -#ifndef HAVE_STRCHRNUL +#if !HAVE_DECL_STRCHRNUL + +#define strchrnul pg_strchrnul = static inline const char * strchrnul(const char *s, int c) @@ -354,19 +361,7 @@ strchrnul(const char *s, int c) return s; } = -#else - -/* - * glibc's declares strchrnul only if _GNU_SOURCE is defined. - * While we typically use that on glibc platforms, configure will set - * HAVE_STRCHRNUL whether it's used or not. Fill in the missing declarat= ion - * so that this file will compile cleanly with or without _GNU_SOURCE. - */ -#ifndef _GNU_SOURCE -extern char *strchrnul(const char *s, int c); -#endif - -#endif /* HAVE_STRCHRNUL */ +#endif /* !HAVE_DECL_STRCHRNUL */ = = /* ------- =_aaaaaaaaaa0--