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