> On 1 Sep 2026, at 02:07, Jeff Law <[email protected]> wrote:
> 
> 
> 
> 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.

Thanks. Iain, Rainer, did you get a chance to try it out?

> 
> 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?


The old trap was st=$?; rm -f ...; trap - 0; exit $st. It re-raised the exit 
status. The patch deletes that because trap - 0 and $? are both broken on 
Solaris 10 /bin/sh.

Deleting it makes the recipe depend on the pending status surviving the trap. 
bash before 3.1, run as sh -c, does not preserve it when the trap body is a 
single external command: the shell exits with rm's status, so exit 1 becomes 
exit 0.

:; makes the body two commands, which restores that. It is the Autoconf 
manual's documented workaround:
("Limitations of Shell Builtins", trap): "older implementations of bash failed 
to preserve $? across an exit trap consisting of a single cleanup command". 
make runs every recipe as $(SHELL) -c, and the new trap body is one external 
command, so this is that case exactly. Removing the : reintroduces the 
silent-success bug the patch fixes.

Kyrill

> 
> jeff


Reply via email to