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
 ])
 




Reply via email to