autoconf
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

versioning config.cache


From: Dave Hart
Subject: versioning config.cache
Date: Fri, 1 May 2009 11:37:54 +0000

I added -Winit-self unwisely to NTP's configure.ac without a test,
resulting in spectacular failure for those with old-enough gcc [1].
For those users, invalid results were cached left and right if they
enabled config.cache.  At the time I repaired my mistake, I wanted a
version number to bump that would cause configure to ignore
config.cache results from prior versions.

I came up with a macro to be used immediately after AC_INIT has loaded
any config.cache which takes a version number and persists it in a
cache variable, clearing all other cache variables to flush the cache
if an incompatible cache is detected.  It seems to be working as
intended for me in NTP's main configure.ac as well as two child
configure.ac files.

I would like to hear your opinions, and I welcome pointers to refine
anything that jumps out at your eye.

Cheers,
Dave Hart

[1] http://bugs.ntp.org/1167  and
    https://support.ntp.org/bugs/show_bug.cgi?id=1160#c8

skeletal configure.ac:
------------------
AC_INIT([someprog])
NTP_CACHEVERSION([main], 1)
------------------

proposed NTP configure.ac:
------------------
m4_include([version.m4])
AC_INIT([ntp], [VERSION_NUMBER])

# Increment ntp_configure_cache_version by one for each change to
# configure.ac or .m4 files which invalidates cached values from
# previous versions.

# It is not necessary to bump the version in more than one
# configure.ac at the same time, as the cache is shared.
# Previously used values should never be used again.

ntp_configure_cache_version=0

# When the cache version of config.cache and configure do not
# match, NTP_CACHEVERSION will flush the cache.

NTP_CACHEVERSION([main], [$ntp_configure_cache_version])
------------------

ntp_cacheversion.m4:
------------------
# NTP_CACHEVERSION(component, version)
# ------------------------------------
# compare this configure script's cache version stamp with the stamp
# saved by the prior run in config.cache.  If they differ, clear all
# cache variables to avoid using results cached with a script that
# is known to differ in a cache-invalidating manner.
#
# Note: use immediately following AC_INIT in configure.ac, as clearing
# all _cv_ variables only makes sense immediately after loading, before
# use or modification.
#
# It is assumed that parent configure.ac files which use
# AC_CONFIG_SUBDIR to invoke child configure.ac files have used
# NTP_CACHEVERSION if any children do.  The top-level configure script
# will clear a previous cache lacking any saved cache version number,
# while children do not.  The reason is the children can rely on the
# parent having cleared any cache variables predating this mechanism.
# Therefore the child can rely on the config.cache generated by the
# parent on the first run despite not finding its version stamp
# previously saved.

AC_DEFUN_ONCE([NTP_CACHEVERSION], [
    AC_BEFORE([$0], [AM_INIT_AUTOMAKE])dnl
    AC_BEFORE([$0], [AM_CONFIG_HEADER])dnl
    AC_BEFORE([$0], [AC_PROG_CC])dnl

    ntp_cache_flush=1
    case "$ntp_cv_[$1]_cache_version" in
     [$2])
        # same version, good
        ntp_cache_flush=0
        ;;
     '')
        # No cache, predates ntp_cv_$1_cache_version, or is empty.
        case "$cache_file" in
         ../*)
            # Parent configure will have cleared cache once already.
            # This will misfire if a top-level configure is invoked
            # with --config-cache= value beginning with '../', is
            # there a better way to detect this configure was
            # invoked by a parent directory configure?
            ntp_cache_flush=0
            ;;
         /dev/null)
            ntp_cache_flush=0
        esac
        ;;
     *)
        # configure cache version mismatches config.cache version
    esac
    case "$ntp_cache_flush" in
     1)
        # Clear all *_cv_* variables except our various components'
        # ntp_cv_*_cache_version vars.
        
        c_varname_list=`set |
                        sed 's/=.*$//g' |
                        fgrep _cv_ |
                        grep -v 'ntp_cv_.*_cache_version'
                       `
        for c_varname in $c_varname_list
        do
            dnl use AS_UNSET([$c_varname]) eventually
            eval ${c_varname}=;
            $as_unset $c_varname
        done
        
        dnl use AS_UNSET([c_varname_list c_varname]) eventually
        c_varname_list=; $as_unset c_varname_list c_varname
        
        AC_MSG_NOTICE([$cache_file saved by another version, ignored.])
        AC_MSG_NOTICE([configure script cache version: [$2]])
        c_version="${ntp_cv_[$1]_cache_version:-(no version found)}"
        AC_MSG_NOTICE([$cache_file version: $c_version])
        $as_unset c_version
    esac

    # save configure version in config.cache for next time
    ntp_cv_[$1]_cache_version="[$2]"

    $as_unset ntp_cache_flush
])dnl
------------------




reply via email to

[Prev in Thread] Current Thread [Next in Thread]