Hello Branden,

i just tested rc2 for the first time.  As far as my testing in rc1 went
previously (i never completed testing rc1), i see no further
regressions in rc2 beyond what i already reported for rc1.

It appears parallel building now works (at least it did when i
tested it once, which is admittedly not conclusive evidence because
for parallel build errors, intermittent failures are typical).
For now, i will do test builds in serial mode anyway because
that makes diff(1)ing build logs easier.  Thoroughly testing
parallel builds is not a priority at this point.


Here is the next crash on OpenBSD, present in both rc1 and rc2.

Groff uses the gnulib putenv module.  That module tests putenv(3)
in a bogus way, which causes my OpenBSD build to crash:

  c++ -O2 -pipe -o grops src/devices/grops/ps.o src/devices/grops/psrm.o \
      -lm libdriver.a  libgroff.a  lib/libgnu.a
  ld: error: undefined symbol: rpl_putenv
  >>> referenced by psrm.cpp
  >>>   src/devices/grops/psrm.o:(resource_manager::output_prolog(ps_output&))
  >>> referenced by ps.cpp
  >>>   src/devices/grops/ps.o:(main)
  c++: error: linker command failed with exit code 1 (use -v to see invocation)
  *** Error 1 in . (Makefile:8416 'grops')


The gnulib putenv module insists that

  putenv("VARIABLE_NAME")

should delete the variable VARIABLE_NAME from the environment
and return 0.  However, POSIX explicitely says

  If the _string_ argument points to a string containing a valid name,
  the putenv() function shall either remove the environment variable
  with that name (if it exists) from the environment or fail
  with _errno_ set to [EINVAL].

  Source:
  https://pubs.opengroup.org/onlinepubs/9799919799/functions/putenv.html

OpenBSD implements and documents the latter behaviour.

GNU roff does *not* require either of the non-portable options
permitted by POSIX.

Here is an exhaustive list of the files in groff that use putenv(3):

  src/devices/grops/ps.cpp
  src/devices/grops/psrm.cpp
  src/roff/groff/groff.cpp
  src/roff/troff/input.cpp

All putenv(3) calls in these files only use putenv() in the portable
way where the argument contains a '=' character, so using the gnulib
putenv module is bogus.

A possible short-term fix might be to use a different gnulib module
that only tests for the portable features that groff actually needs
instead of the bogus putenv module.

The proper mid-term solution would be to stop using the deprecated
putenv(3) function at all, because POSIX says:

  The setenv() function is preferred over this function.
  One reason is that putenv() is optional and therefore less portable.
  Another is that using putenv() can slow down environment searches,
  as explained in the RATIONALE section for getenv().
  
  Source:
  https://pubs.opengroup.org/onlinepubs/9799919799/functions/putenv.html

Let me add that not only is setenv(3) more portable, but also better
designed (passing strings of different semantic purpose in different
arguments rather than concatenating them in a single string argument,
requiring the library implementation to *parse* the argument - and both
assembling and parsing combined strings is generally error-prone),
less error-prone and easier and safer to use.  Using it will simplify
and shorten the code in all four files listed about.

With the workaround appended below, i now managed for the first time
to get groff to build on OpenBSD.  I do not think it is building
correctly just yet, but at least the build now finishes without
crashing.  There are significant amounts of warnings in the build log
that smell like incorrect behaviour and that i did not investigate
yet (no, i'm not talking about the many linker warnings about insecure
library functions - those merely smell like error-prone code, not
necessarily like incorrect behaviour).

Yours,
  Ingo


commit a98ea5e5f0f25c0507592bd205c01d1b093eec70
Author: Ingo Schwarze <[email protected]>
Date:   Thu Feb 5 03:42:09 2026 +0100

    disable bogus test in the gnulib putenv module
    
    This gets groff to build for the first time, likely not building
    correctly just yet, but at least the build no longer crashes.

diff --git a/Makefile b/Makefile
index 0037c6f..6c98fc8 100644
--- a/Makefile
+++ b/Makefile
@@ -87,6 +87,11 @@ CONFIGURE_ENV +=     ac_cv_func_vasnprintf=yes \
 # gnulib enables them by default.  Get rid of them.
 MAKE_FLAGS +=          lib_libgnu_a_OBJECTS=
 
+# Disable bogus test in the gnulib putenv module.
+# It complains about behaviour that groff does not need
+# and that is explicitely permitted by POSIX.
+CONFIGURE_ENV +=       gl_cv_func_svid_putenv=yes
+
 TEST_TARGET =          check
 
 pre-configure:

Reply via email to