On 8/21/26 5:50 AM, [email protected] wrote:
From: Kyrylo Tkachov <[email protected]>

This is an attempt to fix bootstrap comparison on Darwin and Solaris.
Rainer, Iain, could you help with testing it?

The comparison writes a makefile and runs it under $(MAKE).  Building and
running that makefile assumed GNU sed, and assumed more of the shell than
several hosts provide.  Four defects, all from 54c3bdc8ad6.

The comparison command was escaped for the generated makefile with

   printf '%s' "$cmp_raw" | sed 's,\$,$$,g'

whose input carries no trailing newline.  GNU sed passes that through
unchanged, a POSIX sed terminates the last line, and Solaris /usr/bin/sed
drops it.  The first splits the recipe in two, and the sub-make stops with

   compare.42895.mk:5: *** missing separator.  Stop.

The second leaves a bare redirection where the comparison should be, so every
object is judged equal and the bootstrap reports "Comparison successful"
having compared nothing.  Double the '$' characters with $(subst), which make
can do on its own.

The exit traps use "trap - 0", which Solaris 10 /bin/sh takes for a command
named '-', and recover the status with "$?", which Zsh and Solaris 10 /bin/sh
answer with the status of the command before the "exit" rather than its
argument.  The recipe reports a comparison failure with "exit 1" right after
a successful "mv", so on those shells the trap recovers zero and lets the
failure through as success.  A trap that only removes files needs neither.
Let the shell exit with the status it already has.

The comparator fallback installs its trap in a subshell that ends in "cmp",
and several shells do not run an exit trap from a subshell whose last command
is not a builtin.  Now that the temporaries are process specific, a trap that
does not run leaks a pair of files per object.  End the subshell with a
builtin.

The generated makefile did not name the shell.  make neither exports SHELL
nor lets a sub-make inherit it, so the comparisons ran under /bin/sh rather
than the shell configure chose.

The serial comparison removed .bad_compare before starting.  That file is now
written only by a comparison that completes and finds a difference, so a
sub-make that fails first leaves the previous run's result in place, still
named in the failure message.  Shards from a run killed with SIGKILL survive
too, keyed on a pid a later comparison can draw.  Remove both up front.

Ok for trunk?
Thanks,
Kyrill

ChangeLog:

        PR bootstrap/126875
        * Makefile.tpl ([+compare-target+]): Escape the comparison command
        with $(subst) rather than a sed pipe.  Clean up from the exit trap
        without resetting it or re-deriving the exit status.  Name the shell
        in the generated makefile.  Remove any previous result file and
        result shards before comparing.
        * Makefile.in: Regenerate.
        * configure: Regenerate.

config/ChangeLog:

        PR other/126875
        * acx.m4 (ACX_PROG_CMP_IGNORE_INITIAL): Clean up from the exit trap
        without resetting it, and end the fallback subshell with a builtin so
        that the trap runs.

Signed-off-by: Kyrylo Tkachov <[email protected]>
OK once you get a confirmation that this avoids the problems seen on those platforms.

It does look like you've got an extraneous ':' below (and in the other copy a bit later)
+       trap ':; rm -f "$$compare_makefile" "$$bad_compare" \
+         "$$bad_compare".*' 0; \
Or is that : doing something non-obvious here?

jeff

Reply via email to