#!/bin/sh
# Run this to generate all the initial makefiles, etc.
-set -e
+die()
+{
+ echo "error: $1" >&2
+ exit 1
+}
-srcdir=`dirname "$0"`
-test -z "$srcdir" && srcdir=.
+starting_point=$(pwd)
-THEDIR=`pwd`
-cd "$srcdir"
+srcdir=$(dirname "$0")
+test "$srcdir" || srcdir=.
-test -f src/libvirt.c || {
- echo "You must run this script in the top-level libvirt directory"
- exit 1
+cd "$srcdir" || {
+ die "Failed to cd into $srcdir"
}
+test -f src/libvirt.c || {
+ die "$0 must live in the top-level libvirt directory"
+}
-EXTRA_ARGS=
+dry_run=
no_git=
-if test "x$1" = "x--no-git"; then
- no_git=" $1"
- shift
- case "$1 $2" in
- --gnulib-srcdir=*) no_git="$no_git $1"; shift ;;
- --gnulib-srcdir\ *) no_git="$no_git $1=$2"; shift; shift;;
- esac
-fi
-if test -z "$NOCONFIGURE" ; then
- if test "x$1" = "x--system"; then
- shift
- prefix=/usr
- libdir=$prefix/lib
- sysconfdir=/etc
- localstatedir=/var
- if [ -d /usr/lib64 ]; then
- libdir=$prefix/lib64
- fi
- EXTRA_ARGS="--prefix=$prefix --sysconfdir=$sysconfdir --localstatedir=$localstatedir --libdir=$libdir"
- echo "Running ./configure with $EXTRA_ARGS $@"
- else
- if test -z "$*" && test ! -f "$THEDIR/config.status"; then
- echo "I am going to run ./configure with no arguments - if you wish"
- echo "to pass any to it, please specify them on the $0 command line."
- fi
- fi
-fi
+gnulib_srcdir=
+extra_args=
+while test "$#" -gt 0; do
+ case "$1" in
+ --dry-run)
+ # This variable will serve both as an indicator of the fact that
+ # a dry run has been requested, and to store the result of the
+ # dry run. It will be ultimately used as return code for the
+ # script: 0 means no action is necessary, 2 means that autogen.sh
+ # needs to be executed, and 1 is reserved for failures
+ dry_run=0
+ shift
+ ;;
+ --no-git)
+ no_git=" $1"
+ shift
+ ;;
+ --gnulib-srcdir=*)
+ gnulib_srcdir=" $1"
+ shift
+ ;;
+ --gnulib-srcdir)
+ gnulib_srcdir=" $1=$2"
+ shift
+ shift
+ ;;
+ --system)
+ prefix=/usr
+ sysconfdir=/etc
+ localstatedir=/var
+ if test -d $prefix/lib64; then
+ libdir=$prefix/lib64
+ else
+ libdir=$prefix/lib
+ fi
+ extra_args="--prefix=$prefix --localstatedir=$localstatedir"
+ extra_args="$extra_args --sysconfdir=$sysconfdir --libdir=$libdir"
+ shift
+ ;;
+ *)
+ # All remaining arguments will be passed to configure verbatim
+ break
+ ;;
+ esac
+done
+no_git="$no_git$gnulib_srcdir"
-# Compute the hash we'll use to determine whether rerunning bootstrap
-# is required. The first is just the SHA1 that selects a gnulib snapshot.
-# The second ensures that whenever we change the set of gnulib modules used
-# by this package, we rerun bootstrap to pull in the matching set of files.
-# The third ensures that whenever we change the set of local gnulib diffs,
-# we rerun bootstrap to pull in those diffs.
-bootstrap_hash()
+gnulib_hash()
{
+ local no_git=$1
+
if test "$no_git"; then
- echo no-git
+ echo "no-git"
return
fi
- git submodule status | sed 's/^[ +-]//;s/ .*//'
+
+ # Compute the hash we'll use to determine whether rerunning bootstrap
+ # is required. The first is just the SHA1 that selects a gnulib snapshot.
+ # The second ensures that whenever we change the set of gnulib modules used
+ # by this package, we rerun bootstrap to pull in the matching set of files.
+ # The third ensures that whenever we change the set of local gnulib diffs,
+ # we rerun bootstrap to pull in those diffs.
+ git submodule status .gnulib | awk '{ print $1 }'
git hash-object bootstrap.conf
- git ls-tree -d HEAD gnulib/local | awk '{print $3}'
+ git ls-tree -d HEAD gnulib/local | awk '{ print $3 }'
}
-# Ensure that whenever we pull in a gnulib update or otherwise change to a
-# different version (i.e., when switching branches), we also rerun ./bootstrap.
-# Also, running 'make rpm' tends to litter the po/ directory, and some people
-# like to run 'git clean -x -f po' to fix it; but only ./bootstrap regenerates
-# the required file po/Makevars.
-# Only run bootstrap from a git checkout, never from a tarball.
+# Only look into git submodules if we're in a git checkout
if test -d .git || test -f .git; then
- curr_status=.git-module-status t=
- if test "$no_git"; then
- t=no-git
- elif test -d .gnulib; then
- t=$(bootstrap_hash; git diff .gnulib)
+
+ # Check for dirty submodules
+ if test -z "$CLEAN_SUBMODULE"; then
+ for path in $(git submodule status | awk '{ print $2 }'); do
+ case "$(git diff "$path")" in
+ *-dirty*)
+ echo "error: $path is dirty, please investigate" >&2
+ echo "set CLEAN_SUBMODULE to discard submodule changes" >&2
+ exit 1
+ ;;
+ esac
+ done
fi
- case $t:${CLEAN_SUBMODULE+set} in
- *:set) ;;
- *-dirty*)
- echo "error: gnulib submodule is dirty, please investigate" 2>&1
- echo "set env-var CLEAN_SUBMODULE to discard gnulib changes" 2>&1
- exit 1 ;;
- esac
- # Keep this test in sync with cfg.mk:_update_required
- if test "$t" = "$(cat $curr_status 2>/dev/null)" \
- && test -f "po/Makevars" && test -f AUTHORS; then
- # good, it's up to date, all we need is autoreconf
- autoreconf -if
+ if test "$CLEAN_SUBMODULE" && test -z "$no_git"; then
+ if test -z "$dry_run"; then
+ echo "Cleaning up submodules..."
+ git submodule foreach 'git clean -dfqx && git reset --hard' || {
+ die "Cleaning up submodules failed"
+ }
+ fi
+ fi
+
+ # Update all submodules. If any of the submodules has not been
+ # initialized yet, it will be initialized now; moreover, any submodule
+ # with uncommitted changes will be returned to the expected state
+ echo "Updating submodules..."
+ git submodule update --init || {
+ die "Updating submodules failed"
+ }
+
+ # The expected hash, eg. the one computed after the last
+ # successful bootstrap run, is stored on disk
+ state_file=.git-module-status
+ expected_hash=$(cat "$state_file" 2>/dev/null)
+ actual_hash=$(gnulib_hash "$no_git")
+
+ if test "$actual_hash" = "$expected_hash" && \
+ test -f po/Makevars && test -f AUTHORS; then
+ # The gnulib hash matches our expectations, and all the files
+ # that can only be generated through bootstrap are present:
+ # we just need to run autoreconf. Unless we're performing a
+ # dry run, of course...
+ if test -z "$dry_run"; then
+ echo "Running autoreconf..."
+ autoreconf -if || {
+ die "autoreconf failed"
+ }
+ fi
else
- if test -z "$no_git" && test ${CLEAN_SUBMODULE+set}; then
- echo cleaning up submodules...
- git submodule foreach 'git clean -dfqx && git reset --hard'
+ # Whenever the gnulib submodule or any of the related bits
+ # has been changed in some way (see gnulib_hash) we need to
+ # run bootstrap again. If we're performing a dry run, we
+ # change the return code instead to signal our caller
+ if test "$dry_run"; then
+ dry_run=2
+ else
+ echo "Running bootstrap..."
+ ./bootstrap$no_git --bootstrap-sync || {
+ die "bootstrap failed"
+ }
+ gnulib_hash >"$state_file"
fi
- echo running bootstrap$no_git...
- ./bootstrap$no_git --bootstrap-sync && bootstrap_hash > $curr_status \
- || { echo "Failed to bootstrap, please investigate."; exit 1; }
fi
fi
-test -n "$NOCONFIGURE" && exit 0
+# When performing a dry run, we can stop here
+test "$dry_run" && exit "$dry_run"
-cd "$THEDIR"
+# If asked not to run configure, we can stop here
+test "$NOCONFIGURE" && exit 0
-if test "x$OBJ_DIR" != x; then
- mkdir -p "$OBJ_DIR"
- cd "$OBJ_DIR"
+cd "$starting_point" || {
+ die "Failed to cd into $starting_point"
+}
+
+if test "$OBJ_DIR"; then
+ mkdir -p "$OBJ_DIR" || {
+ die "Failed to create $OBJ_DIR"
+ }
+ cd "$OBJ_DIR" || {
+ die "Failed to cd into $OBJ_DIR"
+ }
fi
-if test -z "$*" && test -z "$EXTRA_ARGS" && test -f config.status; then
- ./config.status --recheck
+if test -z "$*" && test -z "$extra_args" && test -f config.status; then
+ echo "Running config.status..."
+ ./config.status --recheck || {
+ die "config.status failed"
+ }
else
- $srcdir/configure $EXTRA_ARGS "$@"
-fi && {
- echo
- echo "Now type 'make' to compile libvirt."
-}
+ if test -z "$*" && test -z "$extra_args"; then
+ echo "I am going to run configure with no arguments - if you wish"
+ echo "to pass any to it, please specify them on the $0 command line."
+ else
+ echo "Running configure with $extra_args $@"
+ fi
+ "$srcdir/configure" $extra_args "$@" || {
+ die "configure failed"
+ }
+fi
+
+echo
+echo "Now type 'make' to compile libvirt."
ifneq ($(_gl-Makefile),)
ifeq (0,$(MAKELEVEL))
- _curr_status = .git-module-status
- # The sed filter accommodates those who check out on a commit from which
- # no tag is reachable. In that case, git submodule status prints a "-"
- # in column 1 and does not print a "git describe"-style string after the
- # submodule name. Contrast these:
- # -b653eda3ac4864de205419d9f41eec267cb89eeb .gnulib
- # b653eda3ac4864de205419d9f41eec267cb89eeb .gnulib (v0.0-2286-gb653eda)
- # $ cat .git-module-status
- # b653eda3ac4864de205419d9f41eec267cb89eeb
- #
- # Keep this logic in sync with autogen.sh.
- _submodule_hash = $(SED) 's/^[ +-]//;s/ .*//'
- _update_required := $(shell \
- cd '$(srcdir)'; \
- test -d .git || { echo 0; exit; }; \
- test -f po/Makevars || { echo 1; exit; }; \
- test -f AUTHORS || { echo 1; exit; }; \
- test "no-git" = "$$(cat $(_curr_status))" && { echo 0; exit; }; \
- actual=$$(git submodule status | $(_submodule_hash); \
- git hash-object bootstrap.conf; \
- git ls-tree -d HEAD gnulib/local | awk '{print $$3}'; \
- git diff .gnulib); \
- stamp="$$($(_submodule_hash) $(_curr_status) 2>/dev/null)"; \
- test "$$stamp" = "$$actual"; echo $$?)
+ _dry_run_result := $(shell \
+ cd '$(srcdir)'; \
+ test -d .git || test -f .git || { echo 0; exit; }; \
+ $(srcdir)/autogen.sh --dry-run >/dev/null 2>&1; \
+ echo $$?; \
+ )
_clean_requested = $(filter %clean,$(MAKECMDGOALS))
- ifeq (1,$(_update_required)$(_clean_requested))
- $(info INFO: gnulib update required; running ./autogen.sh first)
+
+ # A return value of 0 means no action is required
+
+ # A return value of 1 means a genuine error has occurred while
+ # performing the dry run, and it should be reported so it can
+ # be investigated
+ ifeq (1,$(_dry_run_result))
+ $(info INFO: autogen.sh error, running again to show details)
+maint.mk Makefile: _autogen_error
+ endif
+
+ # A return value of 2 means that autogen.sh needs to be executed
+ # in earnest before building, probably because of gnulib updates.
+ # We don't run autogen.sh if the clean target has been invoked,
+ # though, as it would be quite pointless
+ ifeq (2,$(_dry_run_result)$(_clean_requested))
+ $(info INFO: running autogen.sh is required, running it now...)
$(shell touch $(srcdir)/AUTHORS $(srcdir)/ChangeLog)
maint.mk Makefile: _autogen
endif
$(srcdir)/autogen.sh
./config.status
+.PHONY: _autogen_error
+_autogen_error:
+ $(srcdir)/autogen.sh --dry-run
+
# regenerate HACKING as part of the syntax-check
ifneq ($(_gl-Makefile),)
syntax-check: $(top_srcdir)/HACKING spacing-check test-wrap-argv \