### 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
+###--------------------------------------------------------------------------
+### Configuration.
+
+unset checkout checkoutrev
+unset setup setupcmd
+unset sign signkey
+unset sbuild sbuildsrv
+unset upload uploadpath
+unset dput dputtarget
+unset build distcheck debian clean vpath native
+for i in \
+ "/etc/mdw-build.conf" \
+ "${XDG_CONFIG_HOME-$HOME/.config}/mdw-build.conf" \
+ "./.mdw-build.conf"
+do
+ if [ -f "$i" ]; then . "$i"; fi
+done
+default_depends () {
+ var=$1 want=$2
+ eval "p=\${$var+t} q=\${$want+t}"
+ case $p,$q in t,*) ;; *,t) eval "$var=yes" ;; *) eval "$var=no" ;; esac
+}
+: ${checkout=yes} ${checkoutrev=HEAD}
+: ${build=test}
+: ${setup=yes} ${setupcmd=mdw-setup}
+: ${distcheck=yes}
+: ${debian=yes}
+: ${clean=yes}
+: ${vpath=yes}
+: ${native=yes}
+default_depends sbuild sbuildsrv
+default_depends sign signkey
+default_depends upload uploadpath
+default_depends dput dputtarget
+: ${DEB_BUILD_OPTIONS=parallel=4}; export DEB_BUILD_OPTIONS
+
###--------------------------------------------------------------------------
### Parse options.
+prog=${0##*/}
+
usage () {
cat <<EOF
-Usage: $0 [-vr] BUILDOPT
+Usage: $prog [-vr] BUILDOPT
Build options:
[no]checkout[=REV]
[no]release
- [no]setup
+ [no]setup[=RUNE]
[no]distcheck
[no]debian
- [no]upload
+ [no]upload[=SERVER:PATH]
+ [no]dput[=TARGET]
[no]clean
+ [no]vpath
+ [no]sbuild[=SERVER]
+ [no]sign[=KEYID]
+ [no]native
EOF
}
shift $((OPTIND - 1))
## Parse the build options.
-checkout=yes
-checkoutrev=HEAD
-build=test
-setup=yes
-distcheck=yes
-debian=yes
-upload=yes
-clean=yes
+maybe_set () {
+ var=$1 want=$2
+ eval "p=\${$want+t}\${$want-nil}"
+ case $p in
+ t) eval $var=yes ;;
+ nil) echo >&2 "$prog: $want not set"; exit 1 ;;
+ esac
+}
for opt; do
case "$opt" in
checkout) checkout=yes checkoutrev=HEAD ;;
checkout=*) checkout=yes checkoutrev=${opt#*=} ;;
- nocheckout) checkout=no ;;
release) build=release ;;
norelease) build=test ;;
-
- setup | distcheck | debian | upload | clean)
+ setup) setup=yes setupcmd=mdw-setup ;;
+ setup=*) setup=yes setupcmd=${opt#*=} ;;
+ upload) maybe_set upload uploadpath ;;
+ upload=*) upload=yes uploadpath=${opt#*=} ;;
+ sign) maybe_set sign signkey ;;
+ sign=*) sign=yes signkey=${opt#*=} ;;
+ sbuild) maybe_set sbuild sbuildsrv ;;
+ sbuild=*) sbuild=yes sbuildsrv=${opt#*=} ;;
+ dput) maybe_set dput dputtarget ;;
+ dput=*) dput=yes dputtarget=${opt#*=} ;;
+
+ distcheck | debian | clean | vpath | native)
eval "$opt=yes"
;;
- nosetup | nodistcheck | nodebian | noupload | noclean)
+ nocheckout | nosetup | nodistcheck | nodebian | \
+ noupload | nodput | noclean | novpath | nonative | nosbuild | nosign)
eval "${opt#no}=no"
;;
*)
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.
### 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"
done
assign srcpath $(pwd)
+## Build any necessary qualifiers.
+qual= sep=.
+case ${SBOX_SESSION_DIR+t},${DEB_BUILD_ARCH+t} in
+ t,t) qual=$qual$sep$DEB_BUILD_ARCH; sep=- ;;
+ t,*) fail "unknown build arch" ;;
+esac
+
## Construct the output directory.
-assign releasepath $srcpath/dist-$build
+assign releasepath $srcpath/dist-$build$qual
chmod -R +w $releasepath 2>/dev/null || :
rm -rf $releasepath 2>/dev/null || :
mkdir $releasepath
cd $srcpath
[ "$(git ls-files -m)" = "" ] ||
warn "working tree has uncommitted changes"
- gitver=$(git describe)
+ ;;
esac
## Is there Debian build equipment?
info "No debian directory found."
debian=no debver=none
;;
- yes,yes)
- debver=$(dpkg-parsechangelog | sed -n 's/^Version: //p')
+ no,*)
+ debver=none
;;
-esac
-
-## Check the version number.
-case "$gitver,$debver" in
- none,* | *,none)
- ;;
- *)
- [ "$gitver" = "$debver" ] ||
- warn "Git version $gitver doesn't match Debian version $debver"
+ yes,yes)
+ debver=$(dpkg-parsechangelog | sed -n 's/^Version: //p' | tr \~ -)
+ debsrc=$(dpkg-parsechangelog | sed -n 's/^Source: //p')
+ debname=$(git config user.name) debemail=$(git config user.email)
;;
esac
-## Maybe check ot a copy of the source.
+## Maybe check out a copy of the source.
case "$checkout" in
yes)
cd $releasepath
assign srcpath $releasepath/_source
cd $srcpath
run git checkout -b mdw-build $checkoutrev
+ gitver=$(git describe --abbrev=4)
+ ;;
+esac
+
+## Check the version number.
+hack_dch_p=no
+case "$gitver,$debver" in
+ none,* | *,none)
+ ;;
+ *)
+ if [ "$gitver" != "$debver" ]; then
+ warn "Git version $gitver doesn't match Debian version $debver"
+ hack_dch=yes
+ fi
;;
esac
## Maybe refresh the build machinery.
case "$setup" in
yes)
- run mdw-setup
+ run $setupcmd
;;
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
- fail "missing RELEASE file in distribution"
-fi
+case $native in
+ yes)
+ if ! tar tf $buildpath/$distdir.tar.gz 2>/dev/null | grep -q RELEASE
+ then
+ fail "missing RELEASE file in distribution"
+ fi
+ ;;
+esac
run mv $buildpath/$distdir.tar.gz .
+case $build,$sign in
+ release,yes)
+ run gpg -u$signkey -ab -o$distdir.tar.gz.gpg $distdir.tar.gz
+ ;;
+esac
## Maybe build the Debian packages.
case "$debian" in
yes)
run tar xvfz $distdir.tar.gz
cd $distdir
- run dpkg-buildpackage -k$(mdw-conf releasekey)
+ case $hack_dch in
+ yes)
+ dver=$(echo $gitver | sed 's/-/+/; s/-/./g')
+ now=$(date -R)
+ cat - debian/changelog >debian/changelog.new <<EOF
+$debsrc ($dver) experimental; urgency=low
+
+ * Hacking in process, not intended for release.
+
+ -- $debname <$debemail> $now
+
+EOF
+ mv debian/changelog.new debian/changelog
+ ;;
+ esac
+ case $sbuild,$build,$sign in
+ yes,release,yes) run mdw-sbuild -k$signkey $sbuildsrv ;;
+ yes,*) run mdw-sbuild $sbuildsrv ;;
+ no,release,yes) run dpkg-buildpackage -k$signkey ;;
+ no,*) run dpkg-buildpackage -us -uc ;;
+ esac
;;
esac
## Maybe upload Debian packages.
cd $releasepath
case "$upload,$build" in
- yes,test)
- info "Test build: not uploading."
- ;;
- yes,release)
- run rsync $distdir.tar.gz \
- $(mdw-conf upload-target metalzone.distorted.org.uk:/home/ftp/pub/mdw/)
- case "$debian" in
- yes)
- run dput -f $(mdw-conf dput-target metalzone) *.changes
- ;;
- esac
+ yes,test) info "Test build: not uploading." ;;
+ yes,release) run rsync $distdir.tar.gz $distdir.tar.gz.gpg $uploadpath ;;
+esac
+case "$debian,$upload,$dput,$build" in
+ yes,yes,yes,release) run dput -f $dputtarget *.changes ;;
esac
## Tidy up.