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