8bbc644bb4130b96475bd079d17f09fede07637e
[mmh] / SPECS / build-nmh-cygwin
1 #!/bin/bash
2 #
3 # ==========================================================================
4 # Change from generic-build-script:  added this comment block.
5 # Based on Cygwin generic package build script, customized for nmh.
6 #
7 # This script is incompatible with directory names that contain spaces, etc.
8 # To fix that, a whole bunch of shell variables need to be wrapped with "".
9 # ==========================================================================
10 #
11 # Generic package build script
12 #
13 # $Id: generic-build-script,v 1.47 2006/02/01 14:01:14 igor Exp $
14 #
15 # Package maintainers: if the original source is not distributed as a
16 # (possibly compressed) tarball, set the value of ${src_orig_pkg_name},
17 # and redefine the unpack() helper function appropriately.
18 # Also, if the Makefile rule to run the test suite is not "check", change
19 # the definition of ${test_rule} below.
20
21 # find out where the build script is located
22 tdir=`echo "$0" | sed 's%[\\/][^\\/][^\\/]*$%%'`
23 test "x$tdir" = "x$0" && tdir=.
24 scriptdir=`cd $tdir; pwd`
25 # find src directory.
26 # If scriptdir ends in SPECS, then topdir is $scriptdir/..
27 # If scriptdir ends in CYGWIN-PATCHES, then topdir is $scriptdir/../..
28 # Otherwise, we assume that topdir = scriptdir
29 topdir1=`echo ${scriptdir} | sed 's%/SPECS$%%'`
30 topdir2=`echo ${scriptdir} | sed 's%/CYGWIN-PATCHES$%%'`
31 if [ "x$topdir1" != "x$scriptdir" ] ; then # SPECS
32   topdir=`cd ${scriptdir}/..; pwd`
33 else
34   if [ "x$topdir2" != "x$scriptdir" ] ; then # CYGWIN-PATCHES
35     topdir=`cd ${scriptdir}/../..; pwd`
36   else
37     topdir=`cd ${scriptdir}; pwd`
38   fi
39 fi
40
41 tscriptname=`basename $0 .sh`
42 export PKG=`echo $tscriptname | sed -e 's/\-[^\-]*\-[^\-]*$//'`
43 export VER=`echo $tscriptname | sed -e "s/${PKG}\-//" -e 's/\-[^\-]*$//'`
44 export REL=`echo $tscriptname | sed -e "s/${PKG}\-${VER}\-//"`
45 # BASEPKG refers to the upstream base package
46 # SHORTPKG refers to the Cygwin package
47 # Normally, these are identical, but if the Cygwin package name is different
48 # from the upstream package name, you will want to redefine BASEPKG.
49 # Example: For Apache 2, BASEPKG=httpd-2.x.xx but SHORTPKG=apache2-2.x.xx
50 export BASEPKG=${PKG}-${VER}
51 # Change from generic-build-script:  redefined BASEPKG.
52 export BASEPKG=${PKG}-${VER}-dev
53 export SHORTPKG=${PKG}-${VER}
54 export FULLPKG=${SHORTPKG}-${REL}
55
56 # determine correct decompression option and tarball filename
57 # Change from generic-build-script:  set scr_orig_pkg_name here.
58 export src_orig_pkg_name=nmh-1.5-dev.tar.gz
59 if [ -e "${src_orig_pkg_name}" ] ; then
60   # Change from generic-build-script:  don't need the following line, use
61   # opt_decomp of z.
62   # export opt_decomp=? # Make sure tar punts if unpack() is not redefined
63   export opt_decomp=z
64 elif [ -e ${BASEPKG}.tar.bz2 ] ; then
65   export opt_decomp=j
66   export src_orig_pkg_name=${BASEPKG}.tar.bz2
67 elif [ -e ${BASEPKG}.tar.gz ] ; then
68   export opt_decomp=z
69   export src_orig_pkg_name=${BASEPKG}.tar.gz
70 elif [ -e ${BASEPKG}.tgz ] ; then
71   export opt_decomp=z
72   export src_orig_pkg_name=${BASEPKG}.tgz
73 elif [ -e ${BASEPKG}.tar ] ; then
74   export opt_decomp=
75   export src_orig_pkg_name=${BASEPKG}.tar
76 else
77   echo "Cannot find PKG:${PKG} VER:${VER} REL:${REL}.  Rename $0 to"
78   echo "something more appropriate, and try again."
79   exit 1
80 fi
81
82 export src_orig_pkg=${topdir}/${src_orig_pkg_name}
83
84 # determine correct names for generated files
85 export src_pkg_name=${FULLPKG}-src.tar.bz2
86 export src_patch_name=${FULLPKG}.patch
87 export bin_pkg_name=${FULLPKG}.tar.bz2
88 export log_pkg_name=${FULLPKG}-BUILDLOGS.tar.bz2
89
90 export configurelogname=${FULLPKG}-CONFIGURE.LOG
91 export makelogname=${FULLPKG}-MAKE.LOG
92 export checklogname=${FULLPKG}-CHECK.LOG
93 export installlogname=${FULLPKG}-INSTALL.LOG
94
95 export src_pkg=${topdir}/${src_pkg_name}
96 export src_patch=${topdir}/${src_patch_name}
97 export bin_pkg=${topdir}/${bin_pkg_name}
98 export srcdir=${topdir}/${BASEPKG}
99 export objdir=${srcdir}/.build
100 export instdir=${srcdir}/.inst
101 export srcinstdir=${srcdir}/.sinst
102 export buildlogdir=${srcdir}/.buildlogs
103 export configurelogfile=${srcinstdir}/${configurelogname}
104 export makelogfile=${srcinstdir}/${makelogname}
105 export checklogfile=${srcinstdir}/${checklogname}
106 export installlogfile=${srcinstdir}/${installlogname}
107
108 prefix=/usr
109 # Change from generic-build-script:  use /etc/nmh instead of /etc.
110 sysconfdir=/etc/nmh
111 localstatedir=/var
112 if [ -z "$MY_CFLAGS" ]; then
113   MY_CFLAGS="-O2"
114 fi
115 if [ -z "$MY_LDFLAGS" ]; then
116   MY_LDFLAGS=
117 fi
118
119 # Change from generic-build-script:  disabled install_docs because
120 # nmh's make install takes care of it.  Though it installs in
121 # /usr/share/doc/nmh/ instead of /usr/share/doc/nmh-<version>/,
122 # that seems to be more common on Cygwin than using the -<version>.
123 export install_docs=
124 #export install_docs="`for i in ${install_docs}; do echo $i; done | sort -u`"
125 export test_rule=check
126 if [ -z "$SIG" ]; then
127   export SIG=0  # set to 1 to turn on signing by default
128 fi
129 # Sort in POSIX order.
130 export LC_ALL=C
131
132 # helper functions
133
134 # Provide help.
135 help() {
136 cat <<EOF
137 This is the cygwin packaging script for ${FULLPKG}.
138 Usage: $0 [<option>...] <action>...
139 Options are:
140     help, --help        Print this message
141     version, --version  Print the version message
142     with_logs, --logs   Create logs of remaining steps
143 Actions are:
144     prep                Unpack and patch into ${srcdir}
145     mkdirs              Make hidden directories needed during build
146     conf, configure     Configure the package (./configure)
147     reconf              Rerun configure
148     build, make         Build the package (make)
149     check, test         Run the testsuite (make ${test_rule})
150     clean               Remove built files (make clean)
151     install             Install package to staging area (make install)
152     list                List package contents
153     depend              List package dependencies
154     strip               Strip package executables
155     pkg, package        Prepare the binary package ${bin_pkg_name}
156     mkpatch             Prepare the patch file ${src_patch_name}
157     acceptpatch         Copy patch file ${src_patch_name} to ${topdir}
158     spkg, src-package   Prepare the source package ${src_pkg_name}
159     finish              Remove source directory ${srcdir}
160     checksig            Validate GPG signatures (requires gpg)
161     first               Full run for spkg (mkdirs, spkg, finish)
162     almostall           Full run for bin pkg, except for finish
163     all                 Full run for bin pkg
164 EOF
165 }
166
167 # Provide version of generic-build-script modified to make this script.
168 version() {
169     vers=`echo '$Revision: 1.47 $' | sed -e 's/Revision: //' -e 's/ *\\$//g'`
170     echo "$0 based on generic-build-script $vers"
171 }
172
173 # Unpacks the original package source archive into ./${BASEPKG}/.
174 # Change this if the original package was not tarred
175 # or if it doesn't unpack to a correct directory.
176 unpack() {
177   tar xv${opt_decomp}f "$1"
178 }
179
180 # Make the hidden directories used by this script.
181 mkdirs() {
182   (cd ${topdir} && \
183   rm -fr ${objdir} ${instdir} ${srcinstdir} && \
184   mkdir -p ${objdir} && \
185   mkdir -p ${instdir} && \
186   mkdir -p ${srcinstdir} )
187 }
188 mkdirs_log() {
189   (cd ${topdir} && \
190   mkdirs "$@" && \
191   rm -fr ${buildlogdir} && \
192   mkdir -p ${buildlogdir} )
193 }
194
195 # Unpack the original tarball, and get everything set up for this script.
196 prep() {
197   (cd ${topdir} && \
198   unpack ${src_orig_pkg} && \
199   cd ${topdir} && \
200   if [ -f ${src_patch} ] ; then \
201     patch -Z -p0 < ${src_patch} ;\
202   fi && \
203   mkdirs )
204 }
205 prep_log() {
206   prep "$@" && \
207   mkdirs_log && \
208   if [ -f ${topdir}/${log_pkg_name} ] ; then \
209     # Change from generic-build-script:  do the following in subshell
210     # so that cd isn't permanent.
211     (cd ${buildlogdir} && \
212     tar xvjf "${topdir}"/${log_pkg_name})
213   fi
214 }
215
216 # Configure the package.
217 # Change from generic-build-script:  added following notes:
218 # Could add --with-cyrus-sasl if libsasl2 and libsas2-devel
219 #   packages are installed.
220 # Could add --with-tls if libgnutls26 and gnutls-devel
221 #   packages are installed.
222 #
223 conf() {
224   (cd ${objdir} && \
225   CFLAGS="${MY_CFLAGS}" LDFLAGS="${MY_LDFLAGS}" \
226   ${srcdir}/configure \
227   --srcdir=${srcdir} --prefix="${prefix}" \
228   --exec-prefix='${prefix}' --sysconfdir="${sysconfdir}" \
229   --libdir='${prefix}/lib' --includedir='${prefix}/include' \
230   --mandir='${prefix}/share/man' --infodir='${prefix}/share/info' \
231   --libexecdir='${sbindir}' --localstatedir="${localstatedir}" \
232   --datadir='${prefix}/share' )
233 }
234 conf_log() {
235   conf "$@" 2>&1 | tee ${configurelogfile}
236   return ${PIPESTATUS[0]}
237 }
238
239 # Rerun configure to pick up changes in the environment.
240 reconf() {
241   (cd ${topdir} && \
242   rm -fr ${objdir} && \
243   mkdir -p ${objdir} && \
244   conf )
245 }
246 reconf_log() {
247   reconf "$@" 2>&1 | tee ${configurelogfile}
248   return ${PIPESTATUS[0]}
249 }
250
251 # Run make.
252 build() {
253   (cd ${objdir} && \
254   make CFLAGS="${MY_CFLAGS}" )
255 }
256 build_log() {
257   build "$@" 2>&1 | tee ${makelogfile}
258   return ${PIPESTATUS[0]}
259 }
260
261 # Run the package testsuite.
262 check() {
263   (cd ${objdir} && \
264   make -k ${test_rule} )
265 }
266 check_log() {
267   check "$@" 2>&1 | tee ${checklogfile}
268   return ${PIPESTATUS[0]}
269 }
270
271 # Remove files created by configure and make.
272 clean() {
273   (cd ${objdir} && \
274   make clean )
275 }
276
277 # Install the package, with DESTDIR set to '.inst'.
278 # Change from generic-build-script:  added ":;" after "find ... | gzip"
279 # because it returns non-zero status.
280 install() {
281   (cd ${objdir} && \
282   rm -fr ${instdir}/* && \
283   make install DESTDIR=${instdir} && \
284   for f in ${prefix}/share/info/dir ${prefix}/info/dir ; do \
285     if [ -f ${instdir}${f} ] ; then \
286       rm -f ${instdir}${f} ; \
287     fi ;\
288   done &&\
289   for d in ${prefix}/share/doc/${SHORTPKG} ${prefix}/share/doc/Cygwin ; do \
290     if [ ! -d ${instdir}${d} ] ; then \
291       mkdir -p ${instdir}${d} ;\
292     fi ;\
293   done &&\
294   if [ -d ${instdir}${prefix}/share/info ] ; then \
295     find ${instdir}${prefix}/share/info -name "*.info" | xargs -r gzip -q ; \
296   fi && \
297   if [ -d ${instdir}${prefix}/share/man ] ; then \
298     find ${instdir}${prefix}/share/man -name "*.1" -o -name "*.3" -o \
299       -name "*.3x" -o -name "*.3pm" -o -name "*.5" -o -name "*.6" -o \
300       -name "*.7" -o -name "*.8" | xargs -r gzip -q ; :; \
301   fi && \
302   templist="" && \
303   for fp in ${install_docs} ; do \
304     case "$fp" in \
305       */) templist="$templist `find ${srcdir}/$fp -type f`" ;;
306       *)  for f in ${srcdir}/$fp ; do \
307             if [ -f $f ] ; then \
308               templist="$templist $f"; \
309             fi ; \
310           done ;; \
311     esac ; \
312   done && \
313   if [ ! "x$templist" = "x" ]; then \
314     /usr/bin/install -m 644 $templist \
315          ${instdir}${prefix}/share/doc/${SHORTPKG} ; \
316   fi && \
317   if [ -f ${srcdir}/CYGWIN-PATCHES/${PKG}.README ]; then \
318     /usr/bin/install -m 644 ${srcdir}/CYGWIN-PATCHES/${PKG}.README \
319       ${instdir}${prefix}/share/doc/Cygwin/${SHORTPKG}.README ; \
320   elif [ -f ${srcdir}/CYGWIN-PATCHES/README ] ; then \
321     /usr/bin/install -m 644 ${srcdir}/CYGWIN-PATCHES/README \
322       ${instdir}${prefix}/share/doc/Cygwin/${SHORTPKG}.README ; \
323   fi && \
324   if [ -f ${srcdir}/CYGWIN-PATCHES/${PKG}.sh ] ; then \
325     if [ ! -d ${instdir}${sysconfdir}/postinstall ]; then \
326       mkdir -p ${instdir}${sysconfdir}/postinstall ; \
327     fi && \
328     /usr/bin/install -m 755 ${srcdir}/CYGWIN-PATCHES/${PKG}.sh \
329       ${instdir}${sysconfdir}/postinstall/${PKG}.sh ; \
330   elif [ -f ${srcdir}/CYGWIN-PATCHES/postinstall.sh ] ; then \
331     if [ ! -d ${instdir}${sysconfdir}/postinstall ]; then \
332       mkdir -p ${instdir}${sysconfdir}/postinstall ; \
333     fi && \
334     /usr/bin/install -m 755 ${srcdir}/CYGWIN-PATCHES/postinstall.sh \
335       ${instdir}${sysconfdir}/postinstall/${PKG}.sh ; \
336   fi && \
337   if [ -f ${srcdir}/CYGWIN-PATCHES/preremove.sh ] ; then \
338     if [ ! -d ${instdir}${sysconfdir}/preremove ]; then \
339       mkdir -p ${instdir}${sysconfdir}/preremove ; \
340     fi && \
341     /usr/bin/install -m 755 ${srcdir}/CYGWIN-PATCHES/preremove.sh \
342       ${instdir}${sysconfdir}/preremove/${PKG}.sh ; \
343   fi &&
344   if [ -f ${srcdir}/CYGWIN-PATCHES/manifest.lst ] ; then
345     if [ ! -d ${instdir}${sysconfdir}/preremove ]; then
346       mkdir -p ${instdir}${sysconfdir}/preremove ;
347     fi &&
348     /usr/bin/install -m 644 ${srcdir}/CYGWIN-PATCHES/manifest.lst \
349       ${instdir}${sysconfdir}/preremove/${PKG}-manifest.lst ;
350   fi )
351 }
352 install_log() {
353   install "$@" 2>&1 | tee ${installlogfile}
354   return ${PIPESTATUS[0]}
355 }
356
357 # Strip all binaries.
358 strip() {
359   (cd ${instdir} && \
360   find . -name "*.dll" -or -name "*.exe" | xargs -r strip 2>&1 ; \
361   true )
362 }
363
364 # List all non-hidden files that belong to the package.
365 list() {
366   (cd ${instdir} && \
367   find . -name "*" ! -type d | sed 's%^\.%  %' | sort ; \
368   true )
369 }
370
371 # List the static .dll dependencies of the package.  This does not pick up
372 # dynamic dependencies (whether or not libtool was used), nor does it pick
373 # up program dependencies, such as system() depending on /bin/sh.
374 depend() {
375   (cd ${instdir} && \
376   find ${instdir} -name "*.exe" -o -name "*.dll" | xargs -r cygcheck | \
377   sed -ne '/^  [^ ]/ s,\\,/,gp' | sort -bu | \
378   xargs -r -n1 cygpath -u | xargs -r cygcheck -f | sed 's%^%  %' | sort -u ; \
379   true )
380 }
381
382 # Build the binary package tarball.
383 pkg() {
384   (cd ${instdir} && \
385   tar cvjf ${bin_pkg} * )
386 }
387
388 # Compare the original tarball against cygwin modifications.
389 mkpatch() {
390   (cd ${srcdir} && \
391   find . -name "autom4te.cache" | xargs -r rm -rf ; \
392   unpack ${src_orig_pkg} && \
393   mv ${BASEPKG} ../${BASEPKG}-orig && \
394   cd ${topdir} && \
395   diff -urN -x '.build' -x '.inst' -x '.sinst' -x '.buildlogs' \
396     ${BASEPKG}-orig ${BASEPKG} > \
397     ${srcinstdir}/${src_patch_name} ; \
398   rm -rf ${BASEPKG}-orig )
399 }
400
401 # Note: maintainer-only functionality
402 acceptpatch() {
403   cp --backup=numbered ${srcinstdir}/${src_patch_name} ${topdir}
404 }
405
406 # Build the source tarball.
407 spkg() {
408   (mkpatch && \
409   if [ "${SIG}" -eq 1 ] ; then \
410     name=${srcinstdir}/${src_patch_name} text="PATCH" sigfile ; \
411   fi && \
412   cp ${src_orig_pkg} ${srcinstdir}/${src_orig_pkg_name} && \
413   if [ -e ${src_orig_pkg}.sig ] ; then \
414     cp ${src_orig_pkg}.sig ${srcinstdir}/ ; \
415   fi && \
416   cp $0 ${srcinstdir}/`basename $0` && \
417   name=$0 text="SCRIPT" sigfile && \
418   if [ "${SIG}" -eq 1 ] ; then \
419     cp $0.sig ${srcinstdir}/ ; \
420   fi && \
421   cd ${srcinstdir} && \
422   tar cvjf ${src_pkg} * )
423 }
424 spkg_log() {
425   spkg "$@" && \
426   (cd ${srcinstdir} && \
427   if [ -e ${configurelogname} -o -e ${makelogname} -o \
428        -e ${checklogname} -o -e ${installlogname} ]; then
429     tar --ignore-failed-read -cvjf ${log_pkg_name} \
430       ${configurelogname} ${makelogname} ${checklogname} ${installlogname} && \
431     rm -f \
432       ${configurelogname} ${makelogname} ${checklogname} ${installlogname} ; \
433   fi && \
434   tar uvjf ${src_pkg} * )
435 }
436
437 # Clean up everything.
438 finish() {
439   rm -rf ${srcdir}
440 }
441
442 # Generate GPG signatures.
443 sigfile() {
444   if [ \( "${SIG}" -eq 1 \) -a \( -e $name \) -a \( \( ! -e $name.sig \) -o \( $name -nt $name.sig \) \) ]; then \
445     if [ -x /usr/bin/gpg ]; then \
446       echo "$text signature need to be updated"; \
447       rm -f $name.sig; \
448       /usr/bin/gpg --detach-sign $name; \
449     else \
450       echo "You need the gnupg package installed in order to make signatures."; \
451     fi; \
452   fi
453 }
454
455 # Validate GPG signatures.
456 checksig() {
457   if [ -x /usr/bin/gpg ]; then \
458     if [ -e ${src_orig_pkg}.sig ]; then \
459       echo "ORIGINAL PACKAGE signature follows:"; \
460       /usr/bin/gpg --verify ${src_orig_pkg}.sig ${src_orig_pkg}; \
461     else \
462       echo "ORIGINAL PACKAGE signature missing."; \
463     fi; \
464     if [ -e $0.sig ]; then \
465       echo "SCRIPT signature follows:"; \
466       /usr/bin/gpg --verify $0.sig $0; \
467     else \
468       echo "SCRIPT signature missing."; \
469     fi; \
470     if [ -e ${src_patch}.sig ]; then \
471       echo "PATCH signature follows:"; \
472       /usr/bin/gpg --verify ${src_patch}.sig ${src_patch}; \
473     else \
474       echo "PATCH signature missing."; \
475     fi; \
476   else
477     echo "You need the gnupg package installed in order to check signatures." ; \
478   fi
479 }
480
481 f_mkdirs=mkdirs
482 f_prep=prep
483 f_conf=conf
484 f_reconf=conf
485 f_build=build
486 f_check=check
487 f_install=install
488 f_spkg=spkg
489
490 enablelogging() {
491   f_mkdirs=mkdirs_log && \
492   f_prep=prep_log && \
493   f_conf=conf_log && \
494   f_reconf=reconf_log && \
495   f_build=build_log && \
496   f_check=check_log && \
497   f_install=install_log && \
498   f_spkg=spkg_log
499 }
500
501 while test -n "$1" ; do
502   case $1 in
503     help|--help)        help ; STATUS=$? ;;
504     version|--version)  version ; STATUS=$? ;;
505     with_logs|--logs)   enablelogging ; STATUS=$? ;;
506     prep)               $f_prep ; STATUS=$? ;;
507     mkdirs)             $f_mkdirs ; STATUS=$? ;;
508     conf)               $f_conf ; STATUS=$? ;;
509     configure)          $f_conf ; STATUS=$? ;;
510     reconf)             $f_reconf ; STATUS=$? ;;
511     build)              $f_build ; STATUS=$? ;;
512     make)               $f_build ; STATUS=$? ;;
513     check)              $f_check ; STATUS=$? ;;
514     test)               $f_check ; STATUS=$? ;;
515     clean)              $f_clean ; STATUS=$? ;;
516     install)            $f_install ; STATUS=$? ;;
517     list)               list ; STATUS=$? ;;
518     depend)             depend ; STATUS=$? ;;
519     strip)              strip ; STATUS=$? ;;
520     package)            pkg ; STATUS=$? ;;
521     pkg)                pkg ; STATUS=$? ;;
522     mkpatch)            mkpatch ; STATUS=$? ;;
523     acceptpatch)        acceptpatch ; STATUS=$? ;;
524     src-package)        $f_spkg ; STATUS=$? ;;
525     spkg)               $f_spkg ; STATUS=$? ;;
526     finish)             finish ; STATUS=$? ;;
527     checksig)           checksig ; STATUS=$? ;;
528     first)              $f_mkdirs && $f_spkg && finish ; STATUS=$? ;;
529     almostall)          checksig && $f_prep && $f_conf && $f_build && \
530                         $f_install && strip && pkg && $f_spkg ; STATUS=$? ;;
531     all)                checksig && $f_prep && $f_conf && $f_build && \
532                         $f_install && strip && pkg && $f_spkg && finish ; \
533                         STATUS=$? ;;
534     *) echo "Error: bad arguments" ; exit 1 ;;
535   esac
536   ( exit ${STATUS} ) || exit ${STATUS}
537   shift
538 done