Eric Blake wrote on 2026-02-04: > I still got the error while importing just > obstack-printf-posix, but it went away once I also added > obstack-printf to the list of modules to include.
Indeed, I reproduce the issue by taking the current m4-branch-1.6 and removing the 'obstack-printf' module from bootstrap.conf. > Which may mean that > obstack-printf-posix should be depending on obstack-printf module so I > don't have to list both by hand No, the bug is not in the module descriptions. The bug is in the associated Autoconf macros. In detail: When configure runs, these statements from modules/obstack-printf-posix if test $ac_cv_func_obstack_printf = no || test $REPLACE_OBSTACK_PRINTF = 1; then AC_LIBOBJ([obstack_printf]) fi are executed with ac_cv_func_obstack_printf = yes REPLACE_OBSTACK_PRINTF = 0 and thus obstack_printf.o is *not* being added to the LIBOBJS variable, and thus lib/libm4_a-obstack_printf.o will *not* get compiled. But later, due to a chain of module dependencies among tests modules obstack-printf-posix-tests -> obstack-printf-tests -> obstack-printf REPLACE_OBSTACK_PRINTF gets set to 1 (bug fix from 2025-07-12). Thus the generated stdio.h does #define obstack_printf rpl_obstack_printf and since there is no lib/libm4_a-obstack_printf.o, a link error ensues. The fix is to set REPLACE_OBSTACK_PRINTF before it gets used in the module descriptions. 2026-02-14 Bruno Haible <[email protected]> obstack-printf-{posix,gnu}: Fix broken configuration result. Reported by Eric Blake in <https://lists.gnu.org/archive/html/bug-gnulib/2026-02/msg00028.html>. * m4/obstack-printf.m4 (gl_FUNC_OBSTACK_PRINTF_REPLACE): New macro, extracted from gl_FUNC_OBSTACK_PRINTF. (gl_FUNC_OBSTACK_PRINTF): Invoke it. * m4/obstack-printf-posix.m4 (gl_FUNC_OBSTACK_PRINTF_POSIX_REPLACE): New macro, extracted from gl_FUNC_OBSTACK_PRINTF_POSIX. (gl_FUNC_OBSTACK_PRINTF_POSIX): Require gl_FUNC_OBSTACK_PRINTF_REPLACE. * m4/obstack-printf-gnu.m4 (gl_FUNC_OBSTACK_PRINTF_GNU_REPLACE): New macro, extracted from gl_FUNC_OBSTACK_PRINTF_GNU. (gl_FUNC_OBSTACK_PRINTF_GNU): Require gl_FUNC_OBSTACK_PRINTF_REPLACE. diff --git a/m4/obstack-printf-gnu.m4 b/m4/obstack-printf-gnu.m4 index 1d35dd79f6..bfd1501db3 100644 --- a/m4/obstack-printf-gnu.m4 +++ b/m4/obstack-printf-gnu.m4 @@ -1,12 +1,14 @@ # obstack-printf-gnu.m4 -# serial 1 +# serial 2 dnl Copyright (C) 2023-2026 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl This file is offered as-is, without any warranty. -AC_DEFUN([gl_FUNC_OBSTACK_PRINTF_GNU], +dnl Part 1 of gl_FUNC_OBSTACK_PRINTF_GNU: +dnl Sets REPLACE_OBSTACK_PRINTF if needed. +AC_DEFUN_ONCE([gl_FUNC_OBSTACK_PRINTF_GNU_REPLACE], [ AC_REQUIRE([gl_FUNC_OBSTACK_PRINTF_IS_POSIX]) AC_REQUIRE([gl_PRINTF_DIRECTIVE_UPPERCASE_B]) @@ -19,10 +21,18 @@ AC_DEFUN([gl_FUNC_OBSTACK_PRINTF_GNU] ;; esac fi + if test $gl_cv_func_obstack_printf_gnu = no; then + gl_REPLACE_OBSTACK_PRINTF + fi +]) + +AC_DEFUN([gl_FUNC_OBSTACK_PRINTF_GNU], +[ + gl_FUNC_OBSTACK_PRINTF_REPLACE if test $gl_cv_func_obstack_printf_gnu = no; then gl_PREREQ_VASNPRINTF_WITH_GNU_EXTRAS gl_REPLACE_VASNPRINTF - gl_REPLACE_OBSTACK_PRINTF fi + gl_DECL_OBSTACK_PRINTF ]) diff --git a/m4/obstack-printf-posix.m4 b/m4/obstack-printf-posix.m4 index 8baeef34a7..1b0007994a 100644 --- a/m4/obstack-printf-posix.m4 +++ b/m4/obstack-printf-posix.m4 @@ -1,19 +1,29 @@ # obstack-printf-posix.m4 -# serial 13 +# serial 14 dnl Copyright (C) 2008-2026 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl This file is offered as-is, without any warranty. -AC_DEFUN([gl_FUNC_OBSTACK_PRINTF_POSIX], +dnl Part 1 of gl_FUNC_OBSTACK_PRINTF_POSIX: +dnl Sets REPLACE_OBSTACK_PRINTF if needed. +AC_DEFUN_ONCE([gl_FUNC_OBSTACK_PRINTF_POSIX_REPLACE], [ AC_REQUIRE([gl_FUNC_OBSTACK_PRINTF_IS_POSIX]) + if test $gl_cv_func_obstack_printf_posix = no; then + gl_REPLACE_OBSTACK_PRINTF + fi +]) + +AC_DEFUN([gl_FUNC_OBSTACK_PRINTF_POSIX], +[ + gl_FUNC_OBSTACK_PRINTF_REPLACE if test $gl_cv_func_obstack_printf_posix = no; then gl_PREREQ_VASNPRINTF_WITH_POSIX_EXTRAS gl_REPLACE_VASNPRINTF - gl_REPLACE_OBSTACK_PRINTF fi + gl_DECL_OBSTACK_PRINTF ]) diff --git a/m4/obstack-printf.m4 b/m4/obstack-printf.m4 index 0341dd16a7..adbc223c48 100644 --- a/m4/obstack-printf.m4 +++ b/m4/obstack-printf.m4 @@ -1,5 +1,5 @@ # obstack-printf.m4 -# serial 5 +# serial 6 dnl Copyright (C) 2008-2026 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -7,10 +7,9 @@ dnl This file is offered as-is, without any warranty. dnl From Eric Blake. -dnl Test whether obstack_printf() exists. For now, we assume that -dnl obstack_vprintf behaves identically, so we only test for one. -AC_DEFUN([gl_FUNC_OBSTACK_PRINTF], +dnl Sets REPLACE_OBSTACK_PRINTF if needed. +AC_DEFUN_ONCE([gl_FUNC_OBSTACK_PRINTF_REPLACE], [ AC_REQUIRE([gl_STDIO_H_DEFAULTS]) AC_REQUIRE([gl_FUNC_OBSTACK]) @@ -18,6 +17,8 @@ AC_DEFUN([gl_FUNC_OBSTACK_PRINTF] dnl Persuade glibc <stdio.h> to declare obstack_printf(), obstack_vprintf(). AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + dnl Test whether obstack_printf() exists. For now, we assume that + dnl obstack_vprintf behaves identically, so we only test for one. AC_CHECK_FUNCS_ONCE([obstack_printf]) dnl The obstack_printf function from glibc does not work with the dnl 'struct obstack' defined in gnulib's <obstack.h>. Therefore, when @@ -26,6 +27,17 @@ AC_DEFUN([gl_FUNC_OBSTACK_PRINTF] gl_REPLACE_OBSTACK_PRINTF fi + m4_ifdef([gl_FUNC_OBSTACK_PRINTF_POSIX_REPLACE], + [gl_FUNC_OBSTACK_PRINTF_POSIX_REPLACE]) + + m4_ifdef([gl_FUNC_OBSTACK_PRINTF_GNU_REPLACE], + [gl_FUNC_OBSTACK_PRINTF_GNU_REPLACE]) +]) + +AC_DEFUN([gl_FUNC_OBSTACK_PRINTF], +[ + gl_FUNC_OBSTACK_PRINTF_REPLACE + gl_DECL_OBSTACK_PRINTF ])
