CRUX-ARM : Home

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