CRUX-ARM : Home

Home :: Documentation :: Download :: Development :: Community :: Ports :: Packages :: Bugs :: Links :: About :: Donors
Improved "dist" target.
[pkgutils-cross.git] / pkgmk.in
CommitLineData
9ac667e6
SR
1#!/bin/bash
2#
3# pkgutils
4#
5# Copyright (c) 2000-2005 Per Liden
6fe55c25 6# Copyright (c) 2006-2007 by CRUX team (http://crux.nu)
9ac667e6
SR
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 2 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21# USA.
22#
23
24info() {
25 echo "=======> $1"
26}
27
28warning() {
e55714dd 29 info "WARNING: $1" >&2
9ac667e6
SR
30}
31
32error() {
e55714dd 33 info "ERROR: $1" >&2
9ac667e6
SR
34}
35
36get_filename() {
37 local FILE="`echo $1 | sed 's|^.*://.*/||g'`"
38
39 if [ "$FILE" != "$1" ]; then
40 FILE="$PKGMK_SOURCE_DIR/$FILE"
41 fi
42
43 echo $FILE
44}
45
46check_pkgfile() {
47 if [ ! "$name" ]; then
48 error "Variable 'name' not specified in $PKGMK_PKGFILE."
49 exit 1
50 elif [ ! "$version" ]; then
51 error "Variable 'version' not specified in $PKGMK_PKGFILE."
52 exit 1
53 elif [ ! "$release" ]; then
54 error "Variable 'release' not specified in $PKGMK_PKGFILE."
55 exit 1
56 elif [ "`type -t build`" != "function" ]; then
57 error "Function 'build' not specified in $PKGMK_PKGFILE."
58 exit 1
59 fi
60}
61
62check_directory() {
63 if [ ! -d $1 ]; then
64 error "Directory '$1' does not exist."
65 exit 1
66 elif [ ! -w $1 ]; then
67 error "Directory '$1' not writable."
68 exit 1
69 elif [ ! -x $1 ] || [ ! -r $1 ]; then
70 error "Directory '$1' not readable."
71 exit 1
72 fi
73}
74
75download_file() {
76 info "Downloading '$1'."
77
78 if [ ! "`type -p wget`" ]; then
79 error "Command 'wget' not found."
80 exit 1
81 fi
82
83 LOCAL_FILENAME=`get_filename $1`
84 LOCAL_FILENAME_PARTIAL="$LOCAL_FILENAME.partial"
85 DOWNLOAD_CMD="--passive-ftp --no-directories --tries=3 --waitretry=3 \
86 --directory-prefix=$PKGMK_SOURCE_DIR --output-document=$LOCAL_FILENAME_PARTIAL $1"
87
88 if [ -f "$LOCAL_FILENAME_PARTIAL" ]; then
89 info "Partial download found, trying to resume"
90 RESUME_CMD="-c"
91 fi
92
93 while true; do
94 wget $RESUME_CMD $DOWNLOAD_CMD
95 error=$?
96 if [ $error != 0 ] && [ "$RESUME_CMD" ]; then
97 info "Partial download failed, restarting"
98 rm -f "$LOCAL_FILENAME_PARTIAL"
99 RESUME_CMD=""
100 else
101 break
102 fi
103 done
104
105 if [ $error != 0 ]; then
106 error "Downloading '$1' failed."
107 exit 1
108 fi
109
110 mv -f "$LOCAL_FILENAME_PARTIAL" "$LOCAL_FILENAME"
111}
112
113download_source() {
114 local FILE LOCAL_FILENAME
115
116 for FILE in ${source[@]}; do
117 LOCAL_FILENAME=`get_filename $FILE`
118 if [ ! -e $LOCAL_FILENAME ]; then
119 if [ "$LOCAL_FILENAME" = "$FILE" ]; then
120 error "Source file '$LOCAL_FILENAME' not found (can not be downloaded, URL not specified)."
121 exit 1
122 else
123 if [ "$PKGMK_DOWNLOAD" = "yes" ]; then
124 download_file $FILE
125 else
126 error "Source file '$LOCAL_FILENAME' not found (use option -d to download)."
127 exit 1
128 fi
129 fi
130 fi
131 done
132}
133
134unpack_source() {
135 local FILE LOCAL_FILENAME COMMAND
136
137 for FILE in ${source[@]}; do
138 LOCAL_FILENAME=`get_filename $FILE`
139 case $LOCAL_FILENAME in
140 *.tar.gz|*.tar.Z|*.tgz)
141 COMMAND="tar -C $SRC --use-compress-program=gzip -xf $LOCAL_FILENAME" ;;
142 *.tar.bz2)
143 COMMAND="tar -C $SRC --use-compress-program=bzip2 -xf $LOCAL_FILENAME" ;;
144 *.zip)
145 COMMAND="unzip -qq -o -d $SRC $LOCAL_FILENAME" ;;
146 *)
147 COMMAND="cp $LOCAL_FILENAME $SRC" ;;
148 esac
149
150 echo "$COMMAND"
151
152 $COMMAND
153
154 if [ $? != 0 ]; then
155 if [ "$PKGMK_KEEP_WORK" = "no" ]; then
156 rm -rf $PKGMK_WORK_DIR
157 fi
158 error "Building '$TARGET' failed."
159 exit 1
160 fi
161 done
162}
163
164make_md5sum() {
165 local FILE LOCAL_FILENAMES
166
167 if [ "$source" ]; then
168 for FILE in ${source[@]}; do
169 LOCAL_FILENAMES="$LOCAL_FILENAMES `get_filename $FILE`"
170 done
171
172 md5sum $LOCAL_FILENAMES | sed -e 's| .*/| |' | sort -k 2
173 fi
174}
175
176make_footprint() {
177 pkginfo --footprint $TARGET | \
178 sed "s|\tlib/modules/`uname -r`/|\tlib/modules/<kernel-version>/|g" | \
179 sort -k 3
180}
181
182check_md5sum() {
183 local FILE="$PKGMK_WORK_DIR/.tmp"
184
185 cd $PKGMK_ROOT
186
187 if [ -f $PKGMK_MD5SUM ]; then
188 make_md5sum > $FILE.md5sum
189 sort -k 2 $PKGMK_MD5SUM > $FILE.md5sum.orig
190 diff -w -t -U 0 $FILE.md5sum.orig $FILE.md5sum | \
191 sed '/^@@/d' | \
192 sed '/^+++/d' | \
193 sed '/^---/d' | \
194 sed 's/^+/NEW /g' | \
195 sed 's/^-/MISSING /g' > $FILE.md5sum.diff
196 if [ -s $FILE.md5sum.diff ]; then
197 error "Md5sum mismatch found:"
e55714dd 198 cat $FILE.md5sum.diff >&2
9ac667e6
SR
199
200 if [ "$PKGMK_KEEP_WORK" = "no" ]; then
201 rm -rf $PKGMK_WORK_DIR
202 fi
203
204 if [ "$PKGMK_CHECK_MD5SUM" = "yes" ]; then
205 error "Md5sum not ok."
206 exit 1
207 fi
208
209 error "Building '$TARGET' failed."
210 exit 1
211 fi
212 else
213 if [ "$PKGMK_CHECK_MD5SUM" = "yes" ]; then
214 if [ "$PKGMK_KEEP_WORK" = "no" ]; then
215 rm -rf $PKGMK_WORK_DIR
216 fi
217 info "Md5sum not found."
218 exit 1
219 fi
220
221 warning "Md5sum not found, creating new."
222 make_md5sum > $PKGMK_MD5SUM
223 fi
224
225 if [ "$PKGMK_CHECK_MD5SUM" = "yes" ]; then
226 if [ "$PKGMK_KEEP_WORK" = "no" ]; then
227 rm -rf $PKGMK_WORK_DIR
228 fi
229 info "Md5sum ok."
230 exit 0
231 fi
232}
233
234strip_files() {
235 local FILE FILTER
236
237 cd $PKG
238
239 if [ -f $PKGMK_ROOT/$PKGMK_NOSTRIP ]; then
240 FILTER="grep -v -f $PKGMK_ROOT/$PKGMK_NOSTRIP"
241 else
242 FILTER="cat"
243 fi
244
245 find . -type f -printf "%P\n" | $FILTER | while read FILE; do
b0bbde50
SR
246 case $(file -b "$FILE") in
247 *ELF*executable*not\ stripped)
9ac667e6 248 strip --strip-all "$FILE"
b0bbde50
SR
249 ;;
250 *ELF*shared\ object*not\ stripped)
9ac667e6 251 strip --strip-unneeded "$FILE"
b0bbde50
SR
252 ;;
253 current\ ar\ archive)
9ac667e6 254 strip --strip-debug "$FILE"
b0bbde50 255 esac
9ac667e6
SR
256 done
257}
258
259compress_manpages() {
260 local FILE DIR TARGET
261
262 cd $PKG
263
264 find . -type f -path "*/man/man*/*" | while read FILE; do
265 if [ "$FILE" = "${FILE%%.gz}" ]; then
266 gzip -9 "$FILE"
267 fi
268 done
269
270 find . -type l -path "*/man/man*/*" | while read FILE; do
271 TARGET=`readlink -n "$FILE"`
272 TARGET="${TARGET##*/}"
273 TARGET="${TARGET%%.gz}.gz"
274 rm -f "$FILE"
275 FILE="${FILE%%.gz}.gz"
276 DIR=`dirname "$FILE"`
277
278 if [ -e "$DIR/$TARGET" ]; then
279 ln -sf "$TARGET" "$FILE"
280 fi
281 done
282}
283
284check_footprint() {
285 local FILE="$PKGMK_WORK_DIR/.tmp"
286
287 cd $PKGMK_ROOT
288
289 if [ -f $TARGET ]; then
290 make_footprint > $FILE.footprint
291 if [ -f $PKGMK_FOOTPRINT ]; then
292 sort -k 3 $PKGMK_FOOTPRINT > $FILE.footprint.orig
293 diff -w -t -U 0 $FILE.footprint.orig $FILE.footprint | \
294 sed '/^@@/d' | \
295 sed '/^+++/d' | \
296 sed '/^---/d' | \
297 sed 's/^+/NEW /g' | \
298 sed 's/^-/MISSING /g' > $FILE.footprint.diff
299 if [ -s $FILE.footprint.diff ]; then
300 error "Footprint mismatch found:"
e55714dd 301 cat $FILE.footprint.diff >&2
9ac667e6
SR
302 BUILD_SUCCESSFUL="no"
303 fi
304 else
305 warning "Footprint not found, creating new."
306 mv $FILE.footprint $PKGMK_FOOTPRINT
307 fi
308 else
309 error "Package '$TARGET' was not found."
310 BUILD_SUCCESSFUL="no"
311 fi
312}
313
314build_package() {
315 local BUILD_SUCCESSFUL="no"
316
317 export PKG="$PKGMK_WORK_DIR/pkg"
318 export SRC="$PKGMK_WORK_DIR/src"
319 umask 022
320
321 cd $PKGMK_ROOT
322 rm -rf $PKGMK_WORK_DIR
323 mkdir -p $SRC $PKG
324
325 if [ "$PKGMK_IGNORE_MD5SUM" = "no" ]; then
326 check_md5sum
327 fi
328
329 if [ "$UID" != "0" ]; then
330 warning "Packages should be built as root."
331 fi
332
333 info "Building '$TARGET'."
334
335 unpack_source
336
337 cd $SRC
338 (set -e -x ; build)
339
340 if [ $? = 0 ]; then
341 if [ "$PKGMK_NO_STRIP" = "no" ]; then
342 strip_files
343 fi
344
345 compress_manpages
346
347 cd $PKG
348 info "Build result:"
349 tar czvvf $TARGET *
350
351 if [ $? = 0 ]; then
352 BUILD_SUCCESSFUL="yes"
353
354 if [ "$PKGMK_IGNORE_FOOTPRINT" = "yes" ]; then
355 warning "Footprint ignored."
356 else
357 check_footprint
358 fi
359 fi
360 fi
361
362 if [ "$PKGMK_KEEP_WORK" = "no" ]; then
363 rm -rf $PKGMK_WORK_DIR
364 fi
365
366 if [ "$BUILD_SUCCESSFUL" = "yes" ]; then
367 info "Building '$TARGET' succeeded."
368 else
369 if [ -f $TARGET ]; then
370 touch -r $PKGMK_ROOT/$PKGMK_PKGFILE $TARGET &> /dev/null
371 fi
372 error "Building '$TARGET' failed."
373 exit 1
374 fi
375}
376
377install_package() {
378 local COMMAND
379
380 info "Installing '$TARGET'."
381
382 if [ "$PKGMK_INSTALL" = "install" ]; then
383 COMMAND="pkgadd $TARGET"
384 else
385 COMMAND="pkgadd -u $TARGET"
386 fi
387
388 cd $PKGMK_ROOT
389 echo "$COMMAND"
390 $COMMAND
391
392 if [ $? = 0 ]; then
393 info "Installing '$TARGET' succeeded."
394 else
395 error "Installing '$TARGET' failed."
396 exit 1
397 fi
398}
399
400recursive() {
401 local ARGS FILE DIR
402
403 ARGS=`echo "$@" | sed -e "s/--recursive//g" -e "s/-r//g"`
404
405 for FILE in `find $PKGMK_ROOT -name $PKGMK_PKGFILE | sort`; do
406 DIR="`dirname $FILE`/"
407 if [ -d $DIR ]; then
408 info "Entering directory '$DIR'."
409 (cd $DIR && $PKGMK_COMMAND $ARGS)
410 info "Leaving directory '$DIR'."
411 fi
412 done
413}
414
415clean() {
416 local FILE LOCAL_FILENAME
417
418 if [ -f $TARGET ]; then
419 info "Removing $TARGET"
420 rm -f $TARGET
421 fi
422
423 for FILE in ${source[@]}; do
424 LOCAL_FILENAME=`get_filename $FILE`
425 if [ -e $LOCAL_FILENAME ] && [ "$LOCAL_FILENAME" != "$FILE" ]; then
426 info "Removing $LOCAL_FILENAME"
427 rm -f $LOCAL_FILENAME
428 fi
429 done
430}
431
432update_footprint() {
433 if [ ! -f $TARGET ]; then
434 error "Unable to update footprint. File '$TARGET' not found."
435 exit 1
436 fi
437
438 make_footprint > $PKGMK_FOOTPRINT
439 touch $TARGET
440
441 info "Footprint updated."
442}
443
444build_needed() {
445 local FILE RESULT
446
447 RESULT="yes"
448 if [ -f $TARGET ]; then
449 RESULT="no"
450 for FILE in $PKGMK_PKGFILE ${source[@]}; do
451 FILE=`get_filename $FILE`
452 if [ ! -e $FILE ] || [ ! $TARGET -nt $FILE ]; then
453 RESULT="yes"
454 break
455 fi
456 done
457 fi
458
459 echo $RESULT
460}
461
462interrupted() {
463 echo ""
464 error "Interrupted."
465
466 if [ "$PKGMK_KEEP_WORK" = "no" ]; then
467 rm -rf $PKGMK_WORK_DIR
468 fi
469
470 exit 1
471}
472
473print_help() {
474 echo "usage: `basename $PKGMK_COMMAND` [options]"
475 echo "options:"
476 echo " -i, --install build and install package"
477 echo " -u, --upgrade build and install package (as upgrade)"
478 echo " -r, --recursive search for and build packages recursively"
479 echo " -d, --download download missing source file(s)"
480 echo " -do, --download-only do not build, only download missing source file(s)"
481 echo " -utd, --up-to-date do not build, only check if package is up to date"
482 echo " -uf, --update-footprint update footprint using result from last build"
483 echo " -if, --ignore-footprint build package without checking footprint"
484 echo " -um, --update-md5sum update md5sum"
485 echo " -im, --ignore-md5sum build package without checking md5sum"
486 echo " -cm, --check-md5sum do not build, only check md5sum"
487 echo " -ns, --no-strip do not strip executable binaries or libraries"
488 echo " -f, --force build package even if it appears to be up to date"
489 echo " -c, --clean remove package and downloaded files"
490 echo " -kw, --keep-work keep temporary working directory"
491 echo " -cf, --config-file <file> use alternative configuration file"
492 echo " -v, --version print version and exit "
493 echo " -h, --help print help and exit"
494}
495
496parse_options() {
497 while [ "$1" ]; do
498 case $1 in
499 -i|--install)
500 PKGMK_INSTALL="install" ;;
501 -u|--upgrade)
502 PKGMK_INSTALL="upgrade" ;;
503 -r|--recursive)
504 PKGMK_RECURSIVE="yes" ;;
505 -d|--download)
506 PKGMK_DOWNLOAD="yes" ;;
507 -do|--download-only)
508 PKGMK_DOWNLOAD="yes"
509 PKGMK_DOWNLOAD_ONLY="yes" ;;
510 -utd|--up-to-date)
511 PKGMK_UP_TO_DATE="yes" ;;
512 -uf|--update-footprint)
513 PKGMK_UPDATE_FOOTPRINT="yes" ;;
514 -if|--ignore-footprint)
515 PKGMK_IGNORE_FOOTPRINT="yes" ;;
516 -um|--update-md5sum)
517 PKGMK_UPDATE_MD5SUM="yes" ;;
518 -im|--ignore-md5sum)
519 PKGMK_IGNORE_MD5SUM="yes" ;;
520 -cm|--check-md5sum)
521 PKGMK_CHECK_MD5SUM="yes" ;;
522 -ns|--no-strip)
523 PKGMK_NO_STRIP="yes" ;;
524 -f|--force)
525 PKGMK_FORCE="yes" ;;
526 -c|--clean)
527 PKGMK_CLEAN="yes" ;;
528 -kw|--keep-work)
529 PKGMK_KEEP_WORK="yes" ;;
530 -cf|--config-file)
531 if [ ! "$2" ]; then
532 echo "`basename $PKGMK_COMMAND`: option $1 requires an argument"
533 exit 1
534 fi
535 PKGMK_CONFFILE="$2"
536 shift ;;
537 -v|--version)
538 echo "`basename $PKGMK_COMMAND` (pkgutils) $PKGMK_VERSION"
539 exit 0 ;;
540 -h|--help)
541 print_help
542 exit 0 ;;
543 *)
544 echo "`basename $PKGMK_COMMAND`: invalid option $1"
545 exit 1 ;;
546 esac
547 shift
548 done
549}
550
551main() {
552 local FILE TARGET
553
554 parse_options "$@"
555
556 if [ "$PKGMK_RECURSIVE" = "yes" ]; then
557 recursive "$@"
558 exit 0
559 fi
560
561 for FILE in $PKGMK_PKGFILE $PKGMK_CONFFILE; do
562 if [ ! -f $FILE ]; then
563 error "File '$FILE' not found."
564 exit 1
565 fi
566 . $FILE
567 done
568
569 check_directory "$PKGMK_SOURCE_DIR"
570 check_directory "$PKGMK_PACKAGE_DIR"
571 check_directory "`dirname $PKGMK_WORK_DIR`"
572
573 check_pkgfile
574
575 TARGET="$PKGMK_PACKAGE_DIR/$name#$version-$release.pkg.tar.gz"
576
577 if [ "$PKGMK_CLEAN" = "yes" ]; then
578 clean
579 exit 0
580 fi
581
582 if [ "$PKGMK_UPDATE_FOOTPRINT" = "yes" ]; then
583 update_footprint
584 exit 0
585 fi
586
587 if [ "$PKGMK_UPDATE_MD5SUM" = "yes" ]; then
588 download_source
589 make_md5sum > $PKGMK_MD5SUM
590 info "Md5sum updated."
591 exit 0
592 fi
593
594 if [ "$PKGMK_DOWNLOAD_ONLY" = "yes" ]; then
595 download_source
596 exit 0
597 fi
598
599 if [ "$PKGMK_UP_TO_DATE" = "yes" ]; then
600 if [ "`build_needed`" = "yes" ]; then
601 info "Package '$TARGET' is not up to date."
602 else
603 info "Package '$TARGET' is up to date."
604 fi
605 exit 0
606 fi
607
608 if [ "`build_needed`" = "no" ] && [ "$PKGMK_FORCE" = "no" ] && [ "$PKGMK_CHECK_MD5SUM" = "no" ]; then
609 info "Package '$TARGET' is up to date."
610 else
611 download_source
612 build_package
613 fi
614
615 if [ "$PKGMK_INSTALL" != "no" ]; then
616 install_package
617 fi
618
619 exit 0
620}
621
622trap "interrupted" SIGHUP SIGINT SIGQUIT SIGTERM
623
624export LC_ALL=POSIX
625
626readonly PKGMK_VERSION="#VERSION#"
627readonly PKGMK_COMMAND="$0"
628readonly PKGMK_ROOT="$PWD"
629
630PKGMK_CONFFILE="/etc/pkgmk.conf"
631PKGMK_PKGFILE="Pkgfile"
632PKGMK_FOOTPRINT=".footprint"
633PKGMK_MD5SUM=".md5sum"
634PKGMK_NOSTRIP=".nostrip"
635
636PKGMK_SOURCE_DIR="$PWD"
637PKGMK_PACKAGE_DIR="$PWD"
638PKGMK_WORK_DIR="$PWD/work"
639
640PKGMK_INSTALL="no"
641PKGMK_RECURSIVE="no"
642PKGMK_DOWNLOAD="no"
643PKGMK_DOWNLOAD_ONLY="no"
644PKGMK_UP_TO_DATE="no"
645PKGMK_UPDATE_FOOTPRINT="no"
646PKGMK_IGNORE_FOOTPRINT="no"
647PKGMK_FORCE="no"
648PKGMK_KEEP_WORK="no"
649PKGMK_UPDATE_MD5SUM="no"
650PKGMK_IGNORE_MD5SUM="no"
651PKGMK_CHECK_MD5SUM="no"
652PKGMK_NO_STRIP="no"
653PKGMK_CLEAN="no"
654
655main "$@"
656
657# End of file