Fix annoying unneeded recompilations.

runtime/Mmakefile:
    Some time ago, autoconf seems to have changed the text it puts
    into the files it generates, including mercury_conf.h.
    This broke the old code we had in this file that looked for
    the old text. Fix this by updating the pattern we look for.

    Document updates to autoconf as possible reasons for any future
    reoccurrence of this bug.

    Document the reason why we "standardize" the autoconfigured contents
    of mercury_conf.h.

    Fix programming style.

configure.ac:
    The changes in this file are only stylistic; they made it easier
    to track down the above bug.

    Put a comment about "order matters" *before* the lists whose order
    matters. Define the first of two lists being concatenated first
    (since order matters not just for code correctness, but also for
    reading comprehension :-().

    Fix misleading indentation.

    Add an XXX about some (seemingly) unneeded code.
This commit is contained in:
Zoltan Somogyi
2026-03-09 04:01:31 +11:00
parent 3aca14b385
commit 821e03d8be
2 changed files with 135 additions and 91 deletions

View File

@@ -5471,28 +5471,21 @@ fi
export conf_h_copy
export had_old_conf_h
executable_output_files='
scripts/mmc
scripts/mercury
scripts/mercury.bat
scripts/mprof
scripts/mprof.bat
scripts/mercury_update_interface
scripts/mgnuc
scripts/ml
scripts/c2init
scripts/mmake
scripts/mdb
scripts/mdb.bat
scripts/mdprof
scripts/mtags
scripts/canonical_grade
scripts/mkfifo_using_mknod
scripts/mercury_config
scripts/prepare_install_dir
tools/lmc
tools/dotime
'
# IMPORTANT NOTES
# --------------
#
# Any new entries in the following two lists may need to be handled by
# scripts/mercury_config.in. Failing to do this correctly may break
# the binary distributions. This is especially true of files in the runtime
# or java directories; if you add new .in files to either of those
# you *must* update scripts/mercury_config.in.
#
# Also note that the order in which we output files matters, because
# in some cases, one of the non-executable files we output (such as
# scripts/parse_ml_options.sh-subr) will be bodily included in other files
# we output (including scripts/ml, scripts/c2init, and so on). If we
# attempted to create the latter files first, the bodily inclusion
# would include the empty file instead.
nonexecutable_output_files='
Mmake.common
@@ -5518,28 +5511,38 @@ tests/DEFNS_FOR_TESTS
tests/TESTS_FLAGS
'
# The order in which we output files matters, because in some cases, one of the
# non-executable files we output (e.g. scripts/parse_ml_options.sh-subr)
# will be bodily included in other files we output (e.g. scripts/ml,
# scripts/c2init etc). If we attempted to create the latter files first,
# the bodily inclusion would include the empty file instead.
executable_output_files='
scripts/mmc
scripts/mercury
scripts/mercury.bat
scripts/mprof
scripts/mprof.bat
scripts/mercury_update_interface
scripts/mgnuc
scripts/ml
scripts/c2init
scripts/mmake
scripts/mdb
scripts/mdb.bat
scripts/mdprof
scripts/mtags
scripts/canonical_grade
scripts/mkfifo_using_mknod
scripts/mercury_config
scripts/prepare_install_dir
tools/lmc
tools/dotime
'
output_files="$nonexecutable_output_files $executable_output_files"
# IMPORTANT NOTE
# --------------
# Any new entries in the lists above may need to be handled by
# scripts/mercury_config.in. Failing to do this correctly may break
# the binary distributions. This is especially true of files in the runtime
# or java directories; if you add new .in files to either of those
# you *must* update scripts/mercury_config.in.
AC_CONFIG_FILES($output_files)
AC_CONFIG_COMMANDS([default],
AC_CONFIG_COMMANDS([default],
# NOTE If you add any options to scripts/Mercury.config.in that are not
# understood by the installed compiler, then change this to something like
#
# grep -v NEWOPTION < scripts/Mercury.config > scripts/Mercury.config.bootstrap
# grep -v NEWOPTION < scripts/Mercury.config \
# > scripts/Mercury.config.bootstrap
#
# You should then make the same change to the rule in scripts/Mmakefile
# that builds Mercury.config.bootstrap.
@@ -5551,16 +5554,22 @@ cp scripts/Mercury.config scripts/Mercury.config.bootstrap
[
# Only do this when compiling the source, not when reconfiguring
# an installation.
case $reconfiguring in no)
case $reconfiguring in
no)
# XXX What is the point of this loop, given that it processes
# - only one element of the list,
# - that we KNOW will be there?
for header in $CONFIG_HEADERS ; do
if test "$header" = "runtime/mercury_conf.h"; then
if $had_old_conf_h && \
cmp runtime/mercury_conf.h "$conf_h_copy" > /dev/null && \
cmp runtime/mercury_conf.h "$conf_h_copy" \
> /dev/null && \
test -f runtime/mercury_conf.h.date
then
# The date file does need not be updated, so do not update it,
# since doing so would lead to the unnecessary rebuilding
# of all the files that depend on it.
# The date file does need not be updated, so
# do not update it, since doing so would lead to
# the unnecessary rebuilding of all the files
# that depend on it.
true
else
touch runtime/mercury_conf.h.date
@@ -5575,9 +5584,10 @@ case $reconfiguring in no)
rm -f conftest.junk
# The --prefix is hard-coded in the scripts, which are regenerated
# every time you run configure, and also (unfortunately) in the .so files.
# every time you run configure, and also (unfortunately) in the
# .so files.
# The following rm commands are here to ensure that things will work
# correctly if you rerun configure with a new --prefix and then
# correctly if you rerun configure with a new --prefix, and then
# do not do a `make clean' before running `make'.
rm -f runtime/libmer_rt.so library/libmer_std.so
rm -f trace/libmer_trace.so browser/libmer_browser.so

View File

@@ -400,19 +400,53 @@ endif
$(RT_LIB_NAME).init: $(CFILES)
cat `vpath_find $(CFILES)` | grep '^INIT ' > $(RT_LIB_NAME).init
# The point of the code adds the "runtime/" prefix to "mercury.conf.h" is that
# whether the "runtime/" prefix gets added to that comment line depends on
# whether mercury_conf.h was created
#
# (a) by invoking the main configure script in the *parent* directory,
# which add the prefix, or
# (b) by the invocation of config.status in the rule below, which, being
# invoked from *this* directory, does not.
#
# We standardize on one version in order to avoid unnecessary rebuilds
# of many object files that would follow a rebuild of mercury_conf.h
# that either adds or deletes the prefix. Note that which version we pick
# as the standard does not matter; we just happened to pick the version
# *with* the prefix.
#
# IMPORTANT NOTE If you ever see that the object files are unnecessarily
# rebuilt after an invocation of the configure script in the parent directory
# due to a change in the modification time of mercury_conf.h, know that
# one possible cause of this is a change in new versions of autoconf
# that changes the text that it puts into the top comment line in
# mercury_conf.h. If the new text does not fit the pattern that the
# sed invocation below looks for, then
#
# - the standardization of the first line will not work,
# - which will result in a fight between the (a) and (b) kinds of rebuilds
# described above,
# - which in turn will result lots of unnecessary recompilations of C files.
#
# This has already happened. Autoconf used to generate something like
# "Generated by configure from mercury_conf.h.in", but (as of 2026 mar 8)
# generates "Generated from mercury_conf.h.in by configure". This change
# of course was a huge improvement :-(
mercury_conf.h.date: $(MERCURY_DIR)/config.status mercury_conf.h.in
if test -f mercury_conf.h ; then \
mv mercury_conf.h mercury_conf.h.was ; fi
mv mercury_conf.h mercury_conf.h.was ; \
fi
$(MERCURY_DIR)/config.status --header=mercury_conf.h
@mv mercury_conf.h mercury_conf.h.tmp
@sed -e '/Generated by configure/s:mercury_conf:runtime/mercury_conf:' \
@sed -e '/by configure/s:mercury_conf:runtime/mercury_conf:' \
< mercury_conf.h.tmp > mercury_conf.h
# Check to ensure there were no misspelt autoconf variable names.
if grep -n '[^$$]@' mercury_conf.h; then false; else true; fi
# Check if we need to update the file, and if yes, do so.
if test -f mercury_conf.h.was -a -f mercury_conf.h.date && \
cmp mercury_conf.h.was mercury_conf.h > /dev/null ; \
then mv mercury_conf.h.was mercury_conf.h ; \
then \
mv mercury_conf.h.was mercury_conf.h ; \
fi
# Update the datestamp to show that mercury_conf.h is now current,
# even if its modification date is old.