dot/emacs: Configuration for the winning (but secret) `rfcview' package.
[profile] / bin / mdw-build
index 7003964..69a6642 100755 (executable)
 ### along with this program; if not, write to the Free Software Foundation,
 ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
+###--------------------------------------------------------------------------
+### Conventions for build systems.
+###
+### This script is designed to work with a variety of `make'-based build
+### systems, but there are a number of conventions which must be followed if
+### this is going to work properly.
+###
+###   * There must be a `configure.ac', `configure.in', or `.links' file, or
+###    a `.git' directory in the project top-level, so that we can find it.
+###
+###   * The following `make' variables must be assigned in the top-level
+###    Makefile, after `mdw-build' has constructed it.
+###
+###    distdir         The name of the top-level project directory in the
+###                    source distribution, and the base name for
+###                    distribution archives; should be of the form
+###                    `PROJECT-VERSION'.
+###
+###    The following `make' targets must be available in the top-level
+###    Makefile.
+###
+###    dist            Write to $(distdir).tar.gz a source distribution of
+###                    the package.
+###
+###    distcheck       As for `dist', but also build and test the project.
+###
+###  * The source distribution constructed by `make dist' must contain a file
+###    $(distdir)/RELEASE containing the release name.  This isn't currently
+###    tested, but it might be later.
+
 set -e
 
 ###--------------------------------------------------------------------------
@@ -39,6 +69,7 @@ Build options:
   [no]debian
   [no]upload
   [no]clean
+  [no]vpath
 EOF
 }
 
@@ -62,6 +93,7 @@ distcheck=yes
 debian=yes
 upload=yes
 clean=yes
+vpath=yes
 for opt; do
   case "$opt" in
     checkout)  checkout=yes checkoutrev=HEAD ;;
@@ -70,10 +102,10 @@ for opt; do
     release)   build=release ;;
     norelease) build=test ;;
 
-    setup | distcheck | debian | upload | clean)
+    setup | distcheck | debian | upload | clean | vpath)
       eval "$opt=yes"
       ;;
-    nosetup | nodistcheck | nodebian | noupload | noclean)
+    nosetup | nodistcheck | nodebian | noupload | noclean | novpath)
       eval "${opt#no}=no"
       ;;
     *)
@@ -83,6 +115,18 @@ for opt; do
   esac
 done
 
+## Parse DEB_BUILD_OPTIONS.
+jobs=1
+set -- $DEB_BUILD_OPTIONS
+for opt; do
+  case "$opt" in
+    parallel=*) jobs=${opt#*=} ;;
+  esac
+done
+
+makeopts=""
+case $jobs in 1) ;; *) makeopts="$makeopts -j$jobs" ;; esac
+
 ###--------------------------------------------------------------------------
 ### Utility functions.
 
@@ -99,6 +143,13 @@ fail () {
   exit 1
 }
 
+warn () {
+  case $build in
+    release) fail "$*" ;;
+    *) notify 5 "??? $*" ;;
+  esac
+}
+
 info () {
   notify 6 "--- $*"
 }
@@ -130,7 +181,8 @@ yesno () {
 ### Do the building.
 
 ## Find the top-level package directory.
-while [ ! -f configure.ac -a ! -f configure.in -a ! -f .links ]; do
+while [ ! -f configure.ac -a ! -f configure.in -a \
+       ! -f .links -a ! -d .git ]; do
   case "$(pwd)" in
     /)
       fail "couldn't find top-level directory"
@@ -142,7 +194,7 @@ assign srcpath $(pwd)
 
 ## Construct the output directory.
 assign releasepath $srcpath/dist-$build
-chmod -R +w $releasepath 2>/dev/null|| :
+chmod -R +w $releasepath 2>/dev/null || :
 rm -rf $releasepath 2>/dev/null || :
 mkdir $releasepath
 case $verbose in
@@ -152,18 +204,46 @@ case $verbose in
     ;;
 esac
 
-## Maybe check out a copy of the source.
+## Do we have a Git repository?
 case "$checkout,$setup,$(yesno [ -d $srcpath/.git ])" in
   yes,no,*)
     fail "Inconsistent options: can't check out without setup."
     ;;
   yes,yes,no)
     info "No Git repository found."
+    checkout=no gitver=none
     ;;
   yes,yes,yes)
     cd $srcpath
     [ "$(git ls-files -m)" = "" ] ||
-      fail "working tree has uncommitted changes"
+      warn "working tree has uncommitted changes"
+    gitver=$(git describe)
+esac
+
+## Is there Debian build equipment?
+case "$debian,$(yesno [ -d $srcpath/debian ])" in
+  yes,no)
+    info "No debian directory found."
+    debian=no debver=none
+    ;;
+  yes,yes)
+    debver=$(dpkg-parsechangelog | sed -n 's/^Version: //p')
+    ;;
+esac
+
+## Check the version number.
+case "$gitver,$debver" in
+  none,* | *,none)
+    ;;
+  *)
+    [ "$gitver" = "$debver" ] ||
+      warn "Git version $gitver doesn't match Debian version $debver"
+    ;;
+esac
+
+## Maybe check out a copy of the source.
+case "$checkout" in
+  yes)
     cd $releasepath
     run git clone -sn $srcpath/.git _source
     assign srcpath $releasepath/_source
@@ -180,50 +260,57 @@ case "$setup" in
 esac
 
 ## Initialize the build directory.
-if [ -e $srcpath/configure ]; then
-  assign buildpath $releasepath/_build
-  mkdir $buildpath
-  cd $buildpath
-  run $srcpath/configure
-else
-  info "no configure script"
-  assign buildpath $srcpath
-  cd $srcpath
-fi
+case "$vpath,$(yesno [ -e $srcpath/configure ])" in
+  yes,yes)
+    assign buildpath $releasepath/_build
+    mkdir $buildpath
+    cd $buildpath
+    run $srcpath/configure
+    ;;
+  no,yes)
+    info "VPATH build disabled"
+    assign buildpath $srcpath
+    distcheck=no
+    cd $srcpath
+    run ./configure
+    ;;
+  *,no)
+    info "no configure script"
+    assign buildpath $srcpath
+    cd $srcpath
+    ;;
+esac
 
 ## Discover the release name.
 cat >find-distdir.mk <<'EOF'
 include Makefile
 print-distdir:
-       @echo $(distdir)
+       @echo >&3 $(distdir)
 EOF
-assign distdir $(make -f find-distdir.mk print-distdir)
+assign distdir \
+       $({ make -f find-distdir.mk print-distdir >/dev/null 2>&1; } 3>&1)
 
 ## Get a tarball distribution.
 case "$distcheck" in
   yes)
-    run make distcheck
+    run make $makeopts distcheck
     ;;
   no)
-    run make dist
+    run make $makeopts dist
     ;;
 esac
 
 cd $releasepath
 
-if ! tar tfz $buildpath/$distdir.tar.gz | grep -q RELEASE; then
+if ! tar tf $buildpath/$distdir.tar.gz 2>/dev/null | grep -q RELEASE; then
   fail "missing RELEASE file in distribution"
 fi
 
 run mv $buildpath/$distdir.tar.gz .
 
 ## Maybe build the Debian packages.
-case "$debian,$(yesno [ -d $srcpath/debian ])" in
-  yes,no)
-    info "No debian directory found."
-    debian=no
-    ;;
-  yes,yes)
+case "$debian" in
+  yes)
     run tar xvfz $distdir.tar.gz
     cd $distdir
     run dpkg-buildpackage -k$(mdw-conf releasekey)
@@ -238,10 +325,10 @@ case "$upload,$build" in
     ;;
   yes,release)
     run rsync $distdir.tar.gz \
-      $(mdw-conf upload-target metalzone.distorted.org.uk:/home/ftp/pub/mdw/)
+      $(mdw-conf upload-target ftp.distorted.org.uk:~ftp/pub/mdw/)
     case "$debian" in
       yes)
-       run dput -f $(mdw-conf dput-target metalzone) *.changes
+       run dput -f $(mdw-conf dput-target distorted) *.changes
        ;;
     esac
 esac