Paul Eggert wrote:
> > Is something wrong with the m4/time_h.m4 idioms? What was the recipe to
> > reproduce a bug here?
> 
> Here's a recipe:
> 
>    git clone https://git.savannah.gnu.org/git/diffutils.git
>    cd diffutils
>    git checkout 25594ef0d9cda37835499e637a8ec35126aecf72
>    ./bootstrap
>    ./configure
>    make
> 
> On Ubuntu 23.04 x86-64 this eventually fails with:
> 
>      CCLD     diff
>    /usr/bin/ld: context.o: in function `print_context_label':
>    .../src/context.c:56: undefined reference to `rpl_timespec_get'
>    collect2: error: ld returned 1 exit status

I reproduce it if and only if I allow this line in diffutils/configure.ac
to be effective:

  AC_DEFINE([GNULIB_PORTCHECK], [1], [enable some gnulib portability checks])

What happens is that m4/time_h.m4 does this:

  dnl If another module says to replace or to not replace, do that.
  dnl Otherwise, replace only if someone compiles with -DGNULIB_PORTCHECK;
  dnl this lets maintainers check for portability.
  ...
  REPLACE_TIMESPEC_GET=GNULIB_PORTCHECK; AC_SUBST([REPLACE_TIMESPEC_GET])

So, on the Ubuntu 23.04 system, which has the timespec_get() function in
libc, at the shell level, REPLACE_TIMESPEC_GET evaluates to GNULIB_PORTCHECK,
which by these lines of modules/timespec_get

  gl_CONDITIONAL([GL_COND_OBJ_TIMESPEC_GET],
                 [test $HAVE_TIMESPEC_GET = 0 || test $REPLACE_TIMESPEC_GET = 
1])
  ...

  Makefile.am:
  if GL_COND_OBJ_TIMESPEC_GET
  lib_SOURCES += timespec_get.c
  endif

causes timespec_get.c to *not* be compiled. On the C preprocessing level, on
the other hand, @REPLACE_TIMESPEC_GET@ expands to GNULIB_PORTCHECK, which
further expands to 1, thus by these lines of lib/time.in.h

  #  if @REPLACE_TIMESPEC_GET@
  #   if !(defined __cplusplus && defined GNULIB_NAMESPACE)
  #    undef timespec_get
  #    define timespec_get rpl_timespec_get
  #   endif

causes timespec_get to redirect to rpl_timespec_get. This explains the
link error.

A bit of background: When we developed the idioms for the function
replacement modules, around 2003-2007, I used one set of idioms for most
of the modules, whereas you used a slightly different set of idioms for
the time-h module. The difference is regarding how a user is supposed
to determine which gnulib modules he needs to request in his bootstrap.conf
or gnulib-tool invocation.

At that time, it wasn't completely clear how to do this, neither with
the idioms in most *.in.h files, nor with the idioms in time.in.h.

Meanwhile, in 2018, I completed the procedure for this, for the majority
of *.in.h files (by creating the module 'posixcheck') and documented it:
https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commitdiff;h=68bfa44c8f03e2f554f6fc6c42d637bb72b368fa

The question now is: Do you remember how the user was supposed to determine
which modules from time.in.h he needs to import? How did the GNULIB_PORTCHECK
macro help doing that (or was supposed to help doing that)?

I looked at the history of REPLACE_NANOSLEEP and could not find the answer.

If the procedure turns out to be simpler than what we have documented at
https://www.gnu.org/software/gnulib/manual/html_node/Finding-POSIX-substitutes.html
then we have room for improvement on these 44 *.in.h file.

If not, then I would suggest to align time.in.h with the other 44 *.in.h files.

Bruno




Reply via email to