cookutils view modules/pack @ rev 1101

modules/pack: Explain forced package arch
author Aleksej Bobylev <al.bobylev@gmail.com>
date Fri Nov 30 01:41:14 2018 +0200 (2018-11-30)
parents 3a513c4ae923
children 5dcdc6015a2d
line source
1 #!/bin/sh
2 #
3 # pack - module of the SliTaz Cook
4 # Copyright (C) SliTaz GNU/Linux - GNU GPL v3
5 #
7 . /usr/lib/slitaz/libcook.sh
10 ######################################################
11 # BEGIN: Functions may be used in the genpkg_rules() #
12 ######################################################
15 # A bit smarter function than the classic `cp` command
17 scopy() {
18 if [ "$(stat -c %h -- "$1")" -eq 1 ]; then
19 cp -a "$1" "$2" # copy generic files
20 else
21 cp -al "$1" "$2" # copy hardlinks
22 fi
23 }
26 # Copy specified files from $install to $fs
28 cook_copy_files() {
29 action 'Copying files...'
30 cd $install
31 local i j
32 IFS=$'\n'
33 for i in $@; do
34 for j in $(find . -name $i ! -type d); do
35 mkdir -p $fs$(dirname ${j#.})
36 scopy $j $fs$(dirname ${j#.})
37 done
38 done
39 cd - >/dev/null
40 status
41 }
44 # Copy specified folders from $install to $fs
46 cook_copy_folders() {
47 action 'Copying folders...'
48 cd $install
49 local i j
50 IFS=$'\n'
51 for i in $@; do
52 for j in $(find . -name $i -type d); do
53 mkdir -p $fs$(dirname ${j#.})
54 cp -a $j $fs$(dirname ${j#.})
55 done
56 done
57 cd - >/dev/null
58 status
59 }
62 # Remove from current $fs files that are already packed (for receipts v2).
63 # Note: the order in $SPLIT is very important.
64 # Note 2: working in the current set.
66 remove_already_packed() {
67 local i j
68 # $pkg is the name of the main package; $PACKAGE is the name of the current one
69 # $pkg may (or may not) be included in the $SPLIT
70 neighbors=$(
71 echo $basepkg $SPLIT" " \
72 | awk -F$'\t' -vpkg="$thispkg" '
73 BEGIN { RS = " "; FS = ":"; }
74 { set[$1] = $2; }
75 END {
76 current_set = set[pkg];
77 for (i in set)
78 { if (i != pkg && set[i] == current_set) print i; }
79 }
80 ')
81 IFS=$'\n'
82 for neighbor in $neighbors; do
83 i="$taz/$neighbor-$VERSION$EXTRAVERSION/files.list"
84 [ -e "$i" ] || continue
85 while read j; do
86 [ -f $fs$j -o -h $fs$j ] || continue
87 rm $fs$j
88 rmdir --parents --ignore-fail-on-non-empty $fs$(dirname $j)
89 done < $i
90 done
91 unset IFS
92 }
95 # Copy hicolor icons in specified sizes (default: 16 and 48) from $install to $fs
97 cook_copy_icons() {
98 local sizes=$@ i j ifs="$IFS"
99 unset IFS
100 action 'Copying hicolor icons...'
101 [ -d "$fs/usr/share/icons/hicolor" ] && rm -rf "$fs/usr/share/icons/hicolor"
102 mkdir -p $fs/usr/share/icons/hicolor
103 for i in ${sizes:-16 48}; do
104 j="${i}x$i"; [ "$i" == 'scalable' ] && j="$i"
105 [ ! -e "$install/usr/share/icons/hicolor/$j" ] ||
106 scopy $install/usr/share/icons/hicolor/$j \
107 $fs/usr/share/icons/hicolor
108 done
109 status
110 IFS="$ifs"
111 }
114 # Common function to copy files, folders and patterns
116 copy() {
117 action 'Copying folders and files...'
118 local i j k filelist=$(mktemp) folderlist=$(mktemp)
120 IFS=$'\n'
121 cd $install
122 find ! -type d | sed 's|\.||' > $filelist
123 find -type d | sed 's|\.||' > $folderlist
125 for i in $@; do
126 case $i in
127 @std)
128 # Copy "standard" files (all but "developer files", man pages, documentation, translations)
129 sed '/\.h$/d; /\.hxx$/d; /\.a$/d; /\.la$/d; /\.pc$/d; /\.pri$/d; /bin\/.*-config$/d;
130 /\.m4$/d; /\.gir$/d; /\.typelib$/d; /\.vapi$/d; /\.deps$/d; /\.cmake$/d;
131 /\/Makefile.*/d; /\.inc$/d; /\/include\//d;
132 /\/share\/man\//d; /\/share\/doc\//d; /\/share\/gtk-doc\//d; /\/share\/info\//d;
133 /\/share\/devhelp\//d; /\/share\/locale\//d;
134 /\/share\/bash-completion\//d; /\/etc\/bash_completion\.d\//d; /\/lib\/systemd\//d;
135 /\/fonts\.scale$/d; /\/fonts\.dir$/d;
136 /\/share\/appdata\//d; /\/share\/help\//d; /\/share\/metainfo\//d; /\/share\/mimelnk\//d;
137 /\/share\/application-registry\//d; /\/share\/mime-info\//d;
138 /\/share\/gnome\/help\//d; /\/share\/omf\//d;
139 /\/share\/icons\/hicolor\/[12356][1245][268]*x[12356][1245][268]*\//d; # 22, 24, 32, 64, 128, 256, 512
140 /\.so\.dbg$/d;
141 ' $filelist
142 ;;
143 @dev)
144 # Copy "developer files"
145 sed -n '
146 /\/share\/doc\//d;
147 /\.h$/p; /\.hxx$/p; /\.a$/p; /\.pc$/p; /\.pri$/p; /bin\/.*-config$/p;
148 /\.m4$/p; /\.gir$/p; /\.typelib$/p; /\.vapi$/p; /\.deps$/p; /\.cmake$/p;
149 /\/Makefile.*/p; /\.inc$/p; /\/include\//p;
150 /\.so\.dbg$/p;
151 ' $filelist
152 ;;
153 @ruby)
154 # Copy mandatory Ruby files
155 gem_base="\/usr\/lib\/ruby\/gems\/.*\/${PACKAGE#*-}-$VERSION"
156 sed -n '/\/extensions\/.*\.so$/p; /'$gem_base'\/lib\//p; /\.gemspec$/p;
157 /\/usr\/bin\//p; /\/gems\/.*\/bin\//p;
158 ' $filelist | sed '/\/gems\/.*\/lib\/.*\.so$/d; /\/gems\/.*\/lib\/.*\.h$/d;
159 /\/gems\/.*\/gems\/.*\.gemspec$/d;'
160 ;;
161 @ruby-dev)
162 sed -n '/\/ext\/.*\.h$/p; /\/ext\/.*\.pc$/p; /\/gem.build_complete$/p;
163 /\/gems\/.*\/lib\/.*\.h$/p;
164 ' $filelist
165 ;;
166 @rm)
167 # Quick alias
168 remove_already_packed
169 ;;
170 @ico)
171 # Quick alias
172 cook_copy_icons >/dev/null
173 ;;
174 */)
175 # Copy specified folders.
176 i="${i%/}"
177 find -type d -path "*/${i#/}" | sed 's|^.||'
178 ;;
179 *)
180 # Copy specified files.
181 find ! -type d -path "*/${i#/}" | sed 's|^.||'
182 ;;
183 esac \
184 | sort -u \
185 | while read j; do
186 mkdir -p $fs$(dirname "$j")
187 if [ -d "$install$j" ]; then
188 cp -a "$install$j" $fs$(dirname "$j")
189 else
190 scopy "$install$j" $fs$(dirname "$j")
191 fi
192 done
193 # Copy empty directories
194 case $i in
195 @std)
196 while read j; do
197 case $j in
198 # skip empty man & doc folders
199 */man/*|*/doc/*) continue;;
200 esac
201 [ -z "$(ls -A "$install$j")" ] || continue
202 # directory $j is empty
203 k="$j"
204 # make 'ladder' from directories, from root dir to $j
205 # /a /a/b /a/b/c etc.
206 while :; do
207 [ -z "$k" ] && break
208 echo "$k"
209 k="${k%/*}"
210 done \
211 | tac \
212 | while read k; do
213 # make dir if it does not exist
214 if [ ! -d "$fs$k" ]; then
215 # It's like "copy the directory without its underlying content".
216 # keep original ownership/permissions, access:
217 keepIFS="$IFS"; unset IFS
218 install -d $(stat -c'-o%u -g%g -m%a' "$install$k") "$fs$k"
219 # keep last-modified date:
220 touch -r "$install$k" "$fs$k"
221 IFS="$keepIFS"; unset keepIFS
222 fi
223 done
224 done < $folderlist
225 ;;
226 esac
227 done
228 cd - >/dev/null
229 unset IFS
230 rm $filelist $folderlist
231 status
232 }
234 ####################################################
235 # END: Functions may be used in the genpkg_rules() #
236 ####################################################
241 # Receipt used for cooking the package is redundant to be included into package.
242 # This script will strip the original receipt to bare minimum: variables,
243 # {pre,post}_{install,remove} functions.
245 mk_pkg_receipt() {
246 orig_receipt="$1"
248 # 1. Main package.
249 # By default it has no dependencies.
250 # You can write or omit DEPENDS="" for indicating package have no
251 # dependencies.
252 # 2. Split package (excluding *-dev).
253 # By default every split package depends on the main package.
254 # Unfortunately, in the shell script (receipt is the shell script too),
255 # every undeclared variable has empty value, so there's no difference if
256 # you wrote DEPENDS="" or omit it - result will be the same empty value.
257 # If you want to define the split package has no dependencies - you need
258 # to to put single space between the quotes: DEPENDS=" ".
259 # 3. Development split package.
260 # Installing *-dev package should install all the files produced during
261 # compilation and then were separated to the different packages, so
262 # by default (if you wrote DEPENDS="" or omit it) *-dev package depends
263 # on the main package and all the split packages (excluding the itself).
264 [ "$DEPENDS" == ' ' ] && DEPENDS='@EMPTY@'
266 # Receipt's signature is important, although some receipts may miss it
267 signature=$(head -n1 "$orig_receipt")
268 [ "${signature:0:1}" == '#' ] || signature='# SliTaz package receipt.'
270 save="$(mktemp)"
271 # `$(echo ...)`: normalize whitespace (space, tab, newline and their
272 # combinations and repeats)
273 cat > $save <<EOT
274 PACKAGE="$PACKAGE"; DEPENDS="$(echo $DEPENDS)"; PROVIDE="$(echo $PROVIDE)"
275 SUGGESTED="$(echo $SUGGESTED)"; TAZPANEL_DAEMON="$TAZPANEL_DAEMON"
276 TAGS="$(echo $TAGS)"; VERSION="$VERSION"; SHORT_DESC="$SHORT_DESC"
277 WEB_SITE="$WEB_SITE"; CATEGORY="$CATEGORY"
278 EOT
279 unset_receipt
280 . "$orig_receipt"
281 MAIN_PACKAGE="$PACKAGE"
282 . $save; rm $save # restore values
284 # Manage split packages
285 SPLIT=" $SPLIT "
286 if [ "$PACKAGE" != "$MAIN_PACKAGE" -a "$SPLIT" != ' ' ] &&
287 echo "$SPLIT" | fgrep -q " $PACKAGE "; then
288 # For packages with empty $DEPENDS
289 if [ -z "$DEPENDS" ]; then
290 case $PACKAGE in
291 *-dev)
292 # main package and all the split packages but this *-dev itself
293 DEPENDS=$(echo "$MAIN_PACKAGE $SPLIT " | sed "s| $PACKAGE | |; s| *$||");;
294 *)
295 DEPENDS="$MAIN_PACKAGE";;
296 esac
297 fi
299 # Default $CAT
300 [ -z "$CAT" ] &&
301 case $PACKAGE in
302 *-dev) CAT="development|development files" ;;
303 esac
304 fi
306 # Manage two-in-one $CAT="$CATEGORY|$SHORT_DESC_ADDITION"
307 if [ -n "$CAT" ]; then
308 CATEGORY="${CAT%|*}"
309 SHORT_DESC="$SHORT_DESC (${CAT#*|})"
310 fi
312 # escape quotes for receipt
313 SHORT_DESC="${SHORT_DESC//\"/\\\"}"
315 # Mandatory variables
316 cat <<-EOF
317 $signature
319 PACKAGE="$PACKAGE"
320 VERSION="$VERSION"
321 EOF
322 [ -n "$EXTRAVERSION" ] && echo "EXTRAVERSION=\"$EXTRAVERSION\""
323 cat <<-EOF
324 CATEGORY="$CATEGORY"
325 SHORT_DESC="$SHORT_DESC"
326 MAINTAINER="$MAINTAINER"
327 LICENSE="$LICENSE"
328 WEB_SITE="$WEB_SITE"
329 EOF
331 # Optional variables
332 [ -n "$TAGS" ] && echo "TAGS=\"$TAGS\"" | tr -ds '\t' ' '
333 case "x$DEPENDS" in
334 x|x@EMPTY@) ;;
335 *) echo "DEPENDS=\"$DEPENDS\"" | tr -ds '\t' ' ';;
336 esac
337 [ -n "$PROVIDE" ] && echo "PROVIDE=\"$PROVIDE\"" | tr -ds '\t' ' '
338 [ -n "$CONFIG_FILES" ] && echo "CONFIG_FILES=\"$CONFIG_FILES\"" | tr -ds '\t' ' '
339 [ -n "$SUGGESTED" ] && echo "SUGGESTED=\"$SUGGESTED\"" | tr -ds '\t' ' '
340 [ -n "$DATABASE_FILES" ] && echo "DATABASE_FILES=\"$DATABASE_FILES\""
341 [ -n "$TAZPANEL_DAEMON" ] && echo "TAZPANEL_DAEMON=\"$TAZPANEL_DAEMON\""
343 # Extract {pre,post}_{install,remove} functions;
344 # post_install() will be copied for both main and all the split packages
345 # post_install_gtk_() will be copied as post_install() for gtk+ package only
346 #
347 # restricted name (gtk+ -> gtk_; acl-dev -> acl_dev)
348 rname=$(echo -n $PACKAGE | tr -c 'a-zA-Z0-9' '_')
349 for i in pre post; do
350 for j in install remove; do
351 sed "/^${i}_${j}()/,/^}/!d" "$orig_receipt"
352 sed "/^${i}_${j}_$rname()/,/^}/!d" "$orig_receipt" \
353 | sed "s|^${i}_${j}_$rname()|${i}_${j}()|"
354 done
355 done
356 }
359 # Copy all generic files (locale, pixmaps, .desktop) from $install to $fs.
360 # We use standard paths, so some packages need to copy these files with the
361 # receipt and genpkg_rules.
362 # This function executes inside the packaging process, before compressor call.
364 copy_generic_files() {
365 # $LOCALE is set in cook.conf
366 if [ -n "$LOCALE" -a -z "$WANTED" ]; then
367 if [ -d "$install/usr/share/locale" ]; then
368 mkdir -p "$fs/usr/share/locale"
369 for i in $LOCALE; do
370 if [ -d "$install/usr/share/locale/$i" ]; then
371 cp -r $install/usr/share/locale/$i $fs/usr/share/locale
372 fi
373 done
374 fi
375 fi
377 # Generic pixmaps copy can be disabled with COOKOPTS="!pixmaps" (or GENERIC_PIXMAPS="no")
378 if [ "${COOKOPTS/!pixmaps/}" == "$COOKOPTS" -a "$GENERIC_PIXMAPS" != 'no' ]; then
379 if [ -d "$install/usr/share/pixmaps" ]; then
380 mkdir -p "$fs/usr/share/pixmaps"
381 for i in png xpm; do
382 [ -f "$install/usr/share/pixmaps/$PACKAGE.$i" -a ! -f "$fs/usr/share/pixmaps/$PACKAGE.$i" ] &&
383 cp -r $install/usr/share/pixmaps/$PACKAGE.$i $fs/usr/share/pixmaps
384 done
385 fi
386 fi
388 # Desktop entry (.desktop).
389 # Generic desktop entry copy can be disabled with COOKOPTS="!menus" (or GENERIC_MENUS="no")
390 if [ "${COOKOPTS/!menus/}" == "$COOKOPTS" -a "$GENERIC_MENUS" != 'no' ]; then
391 if [ -d "$install/usr/share/applications" -a -z "$WANTED" ]; then
392 mkdir -p "$fs/usr/share"
393 cp -r $install/usr/share/applications $fs/usr/share
394 fi
395 fi
396 }
399 # Determine package architecture
400 # Input: $1 = $fs; output string: i486 | x86_64 | any
402 determine_pkg_arch() {
403 if [ "${COOKOPTS/force-arch/}" != "$COOKOPTS" ]; then
404 action 'Forced package architecture to' >&2
405 echo " $ARCH" >&2
406 arch="$ARCH"
407 else
408 action 'Determining package architecture...' >&2
409 archs="$(
410 IFS=$'\n'
411 {
412 # examine all the executables and static libs (*.a)
413 busybox find "$1" -type f \( -perm +111 -o -name '*.a' \) \
414 | while read i; do
415 readelf -Wh "$i" 2>/dev/null \
416 | sed '/Machine:/!d; s|.* ||'
417 done
419 # examine compressed kernel modules (we use exclusively *.ko.xz)
420 tmpko=$(mktemp)
421 find "$1" -type f -name '*.ko.xz' \
422 | while read i; do
423 unxz -kc $i >$tmpko
424 readelf -Wh "$tmpko" 2>/dev/null \
425 | sed '/Machine:/!d; s|.* ||'
426 done
427 rm $tmpko
429 # examine Guile *.go files (Machine: None, so check Class)
430 find "$1" -type f -name '*.go' \
431 | while read i; do
432 readelf -Wh "$i" 2>/dev/null \
433 | sed '/Class:/!d; s|.* ||'
434 done \
435 | sed 's|ELF32|80386|; s|ELF64|X86-64|'
436 } | sort -u
437 )"
439 case $archs in
440 80386) arch='i486'; echo ' i486' >&2;;
441 X86-64) arch='x86_64'; echo ' x86_64' >&2;;
442 '') arch='any'; echo ' any' >&2;;
443 *) arch="$ARCH"; echo ' ' $archs >&2
444 echo "Warning: weird architecture found, forced to use $ARCH for now." >&2
445 ;;
446 esac
447 fi
449 touch $pkgdir/.arch
450 sed -i "/^$PACKAGE /d" $pkgdir/.arch # remove previous entry
451 echo "$PACKAGE $arch" >> $pkgdir/.arch # put new one
453 echo $arch
454 }
457 # Find the variables inside receipt
459 find_vars() {
460 # You can define variables in the root of the receipt describing
461 # the dependencies (tags, config files, etc.) for each sub-package.
462 # Example:
463 # PACKAGE="cool"
464 # SPLIT="$PACKAGE-extra libcool $PACKAGE-dev"
465 #
466 # DEPENDS_cool or DEPENDS_std # latter is the universal name for main package deps
467 # DEPENDS_cool_extra or DEPENDS_extra # you can skip "$PACKAGE" at the start
468 # DEPENDS_libcool # name not starts with "$PACKAGE" so no "short" name
469 # DEPENDS_cool_dev or DEPENDS_dev
471 local out
472 local var=$1
473 local pkg=$(echo -n $2 | tr -c 'a-zA-Z0-9' '_')
474 local end=$(echo -n ${2#$basepkg-} | tr -c 'a-zA-Z0-9' '_')
475 if [ "$2" == "$basepkg" ]; then
476 eval out="\$${var}_$pkg"
477 [ -n "$out" ] || eval out="\$${var}_std"
478 else
479 eval out="\$${var}_$pkg"
480 [ -n "$out" ] || eval out="\$${var}_$end"
481 fi
482 echo "$out"
483 }
486 # Create the package
488 packit() {
489 basepkg="$PACKAGE"
490 thispkg="$1"
492 pkgdir="$WOK/$basepkg"
493 receipt="$pkgdir/receipt"
494 . $receipt
496 title 'Pack: %s' "$thispkg $VERSION"
499 #
500 # Set variables
501 #
503 # Determine set name for specified package from $SPLIT variable
504 local set=$(echo -n $SPLIT \
505 | awk -vpkg="$thispkg" '
506 BEGIN { RS = " "; FS = ":"; }
507 { if ($1 == pkg && $2 != "") { print "-" $2; exit; } }')
509 # Set paths
510 export stuff="$pkgdir/stuff"
511 export src="$pkgdir/source/$basepkg-$VERSION$set"
512 export install="$pkgdir/install$set"
513 export DESTDIR="$install"
514 export taz="$pkgdir/taz"
515 export pack="$taz/$thispkg-$VERSION$EXTRAVERSION"
516 export fs="$pack/fs"
518 export PACKAGE=$thispkg
521 #
522 # Execute genpkg_rules()
523 #
525 if grep -q ^genpkg_rules $receipt; then
526 _ 'Executing: %s' 'genpkg_rules'
527 set -e; cd $pkgdir; mkdir -p $fs
528 genpkg_rules || (newline; _ 'ERROR: genpkg_rules failed'; newline) >> \
529 $LOGS/$pkg.log
530 else
531 cd $pkgdir
532 mkdir -p $fs
533 if [ "$CATEGORY" == 'meta' -a "$thispkg" == "$basepkg" ]; then
534 _ 'No packages rules: meta package'
535 else
536 # Auto-packing
537 for i in DEPENDS SUGGESTED PROVIDE CONFIG_FILES TAGS CAT COPY; do
538 eval $i="\$(find_vars $i $thispkg)"
539 done
541 [ -n "$COPY" ] ||
542 case "$thispkg" in
543 $basepkg) COPY='@std @rm';;
544 *-dev) COPY='@dev @rm';;
545 lib$basepkg) COPY='*.so*';;
546 esac
547 [ -n "$COPY" ] || die "ERROR: COPY_$thispkg rules undefined"
548 copy $COPY
549 fi
550 fi
553 #
554 # Check CONFIG_FILES
555 #
557 if [ -n "$CONFIG_FILES" ]; then
558 unset IFS
559 for i in $CONFIG_FILES; do
560 if [ ! -e $fs$i ]; then
561 case $i in
562 */) mkdir -p $fs$i ;;
563 *) mkdir -p $fs$(dirname $i); touch $fs$i ;;
564 esac
565 fi
566 done
567 fi
569 # First QA check to stop now if genpkg_rules failed.
570 if fgrep -q '^ERROR' $LOGS/$basepkg.log; then
571 broken; exit 1
572 fi
575 #
576 # Copy receipt and description
577 #
579 cd $taz
580 action 'Copying "%s"...' 'receipt'
581 mk_pkg_receipt "$(realpath ../receipt)" > $pack/receipt
582 chown 0:0 $pack/receipt
583 status
585 unset desc
586 # description common to all the sub-packages
587 [ -f "../description.txt" ] && desc="../description.txt"
588 # description for specified sub-package
589 [ -f "../description.$thispkg.txt" ] && desc="../description.$thispkg.txt"
590 if [ -n "$desc" ]; then
591 action 'Copying "%s"...' "$(basename "$desc")"
592 cp -f $desc $pack/description.txt
593 chown 0:0 $pack/description.txt
594 status
595 fi
598 #
599 # Copy generic files
600 #
602 # Proceed only for "main" package (for v2), and for any packages (v1)
603 [ "$thispkg" == "$mainpkg" ] && copy_generic_files
606 #
607 # Strip / compress files
608 #
610 arch="$(determine_pkg_arch $fs)"
612 export COOKOPTS ARCH HOST_SYSTEM LOCALE fs; @@PREFIX@@/libexec/cookutils/compressor fs
615 #
616 # Make lists
617 #
619 # Create files.list
620 action 'Creating the list of files...'
621 cd $fs
622 find . \( -type f -o -type l \) | sed 's|^.||' > ../files.list
623 cd ..
624 status
626 # Md5sum of files.
627 action 'Creating md5sum of files...'
628 while read file; do
629 [ -L "fs$file" ] && continue
630 [ -f "fs$file" ] || continue
631 case "$file" in
632 /lib/modules/*/modules.*|*.pyc) continue ;;
633 esac
634 md5sum "fs$file" | sed 's| fs| |'
635 done < files.list | sort -k2 > md5sum
636 status
639 #
640 # Calculate release checksum
641 #
643 # Usually it does not change on "just recook".
644 # Md5sum of the *.tazpkg will change every time because of embedded timestamps;
645 # on the other hand release checksum don't relies on the timestamps, but
646 # only on files content and their permissions.
648 # Calculate rsum for new package
649 RSUM=$(
650 {
651 # a) md5sums of all files
652 cat $pack/md5sum
653 # b) md5sum of receipt
654 md5sum $pack/receipt | sed 's| [^ ]*/| |'
655 # c) md5sum of description.txt
656 [ -e "$pack/description.txt" ] &&
657 md5sum $pack/description.txt | sed 's| [^ ]*/| |'
658 # d) md5sum of list of permissions and ownership of all the files and
659 # folders of the package
660 # stat line example: -rwsr-xr-x 0:0 ./bin/busybox
661 {
662 cd $fs
663 find . -print0 | sort -z | xargs -0rn 1 stat -c '%A %g:%u %N' | md5sum
664 }
665 } | md5sum $rsum_file | awk '{print $1}')
668 #
669 # Compressing
670 #
672 UNPACKED_SIZE=$(du -cks fs receipt files.list md5sum description.txt \
673 2>/dev/null | awk 'END{ print $1 "K"}')
675 # Build fs cpio archive
676 action 'Compressing the FS...'
677 find fs -newer $receipt -exec touch -hr $receipt '{}' \;
678 # find fs | cpio -o -H newc --quiet | lzma-alone e fs.cpio.lzma -si
679 find fs | cpio -o -H newc --quiet | /bin/lzma -qzeT0 >fs.cpio.lzma
680 mv fs ../
681 status
683 PACKED_SIZE=$(du -cks fs.cpio.lzma receipt files.list md5sum description.txt \
684 2>/dev/null | awk 'END{ print $1 "K"}')
687 #
688 # Add variables to the receipt
689 #
691 # Store sizes
692 sed -i '/^PACKED_SIZE=/d; /^UNPACKED_SIZE=/d' receipt
693 sed -i "s|^PACKAGE=|PACKED_SIZE=\"$PACKED_SIZE\"\nUNPACKED_SIZE=\"$UNPACKED_SIZE\"\nPACKAGE=|" receipt
695 # Store RSUM
696 sed -i "s|^PACKAGE=|RSUM=\"$RSUM\"\nPACKAGE=|" receipt
698 # Set extra version
699 if [ -n "$EXTRAVERSION" ]; then
700 sed -i '/^EXTRAVERSION=/d' receipt
701 sed -i "s|^VERSION=|EXTRAVERSION=\"$EXTRAVERSION\"\nVERSION=|" receipt
702 fi
705 #
706 # Build *.tazpkg
707 #
709 action 'Creating full cpio archive...'
710 find . -newer $receipt -exec touch -hr $receipt '{}' \;
711 find . | cpio -o -H newc --quiet > ../$PACKAGE-$VERSION$EXTRAVERSION-$arch.tazpkg
712 status
714 # Restoring original package tree.
715 mv ../fs .
717 rm fs.cpio.lzma; cd ..
719 tazpkg=$(ls *.tazpkg)
722 #
723 # Verify package quality and consistency
724 #
726 # Preferrable way is to combine the commands chain in the compile_rules()
727 # using '&&': when any of the chunk broke, process will stop and function
728 # will return non-zero return code.
729 # On the other hand some old receipts don't use '&&' but depends on the
730 # error messages on the log.
731 # Sometimes it produce false positives on the configuration stage.
732 # In this case we can use the "skip-log-errors".
733 if [ "${COOKOPTS/skip-log-errors/}" == "$COOKOPTS" ]; then
734 # Exit if any error found in log file.
735 if fgrep -q ^ERROR $LOGS/$basepkg.log; then
736 rm -f $command
737 broken; exit 1
738 fi
739 fi
742 # Allow meta-packages in v2 receipts
743 [ -n "$CAT" ] && CATEGORY="${CAT%|*}"
745 if [ "${COOKOPTS/empty-pkg/}" == "$COOKOPTS" ]; then
746 action 'QA: checking for empty package...'
747 if [ ! -s "$pack/files.list" -a "$CATEGORY" != 'meta' ]; then
748 broken
749 rm -f $command
750 false; status
751 die 'ERROR: empty package'
752 fi
753 :; status
754 fi
757 #
758 # Get RSUM from the old package
759 #
761 pkg_file="$PKGS/$PACKAGE-$VERSION$EXTRAVERSION-$arch.tazpkg"
762 if [ -f "$pkg_file" ]; then
763 # don't trust database entry, check the package file
764 tmpdir=$(mktemp -d)
765 cd $tmpdir
766 cpio -F "$pkg_file" -i receipt >/dev/null 2>&1
767 RSUM_OLD=$(. receipt; echo $RSUM)
768 cd - >/dev/null
769 rm -r $tmpdir
770 else
771 unset RSUM_OLD
772 fi
775 #
776 # Removing unhandled old packages
777 #
779 if [ $ARCH == 'i486' -a -e $PKGS/$PACKAGE-$VERSION$EXTRAVERSION.tazpkg ]; then
780 action 'Removing old i486 package without arch specifier'
781 rm -f $PKGS/$PACKAGE-$VERSION$EXTRAVERSION.tazpkg
782 status
783 fi
785 # For example, if *-dev package contains *.a static libs, it will be either
786 # i486 or x86_64 arch; otherwise it will be "any" arch. This transition
787 # may be done forth and back depending on you disable static libs or not.
788 case $arch in
789 any)
790 if [ -e $PKGS/$PACKAGE-$VERSION$EXTRAVERSION-$ARCH.tazpkg ]; then
791 action "Removing old $ARCH package because it arch-less now"
792 rm -f $PKGS/$PACKAGE-$VERSION$EXTRAVERSION-$ARCH.tazpkg
793 status
794 fi
795 ;;
796 *)
797 if [ -e $PKGS/$PACKAGE-$VERSION$EXTRAVERSION-any.tazpkg ]; then
798 action "Removing old arch-less package because it $ARCH now"
799 rm -f $PKGS/$PACKAGE-$VERSION$EXTRAVERSION-any.tazpkg
800 status
801 fi
802 ;;
803 esac
805 # Find and remove old package only if "release checksum" has changed
807 pi="$PKGS/packages-$ARCH.info"
808 touch $pi
810 if [ "$RSUM" != "$RSUM_OLD" ]; then
811 old_file=$(awk -F$'\t' -vname="$PACKAGE" -varch="$arch" '{
812 if ($1 == name) printf("%s-%s-%s.tazpkg", $1, $2, arch);
813 }' $pi) # <name>-<version><extra_version>-<arch>.tazpkg
814 if [ -f "$PKGS/$old_file" ]; then
815 action 'Removing old package "%s"' "$old_file"
816 rm -f "$PKGS/$old_file"
817 status
818 fi
819 # package changed, substitute old package by new one
820 mv -f $pkgdir/taz/$PACKAGE-$VERSION$EXTRAVERSION-$arch.tazpkg $PKGS
821 _ 'The release checksum has changed.'
822 else
823 # package not changed, remove new package
824 rm -f $pkgdir/taz/$PACKAGE-$VERSION$EXTRAVERSION-$arch.tazpkg
825 _ 'The release checksum has not changed.'
826 fi
829 #
830 # Package isn't broken anymore
831 #
833 touch $broken
834 sed -i "/^${thispkg}$/d" $broken
837 #
838 # Update packages database every time after successful build
839 #
841 # packages-arch.info (unsorted, located near to packages)
842 unset_receipt; . $pack/receipt
843 SIZES=$(echo $PACKED_SIZE $UNPACKED_SIZE | sed 's|\.0||g')
844 DEPENDS=$(echo $DEPENDS) # remove newlines, tabs and multiple spaces from variable
845 case $arch in
846 i?86) arch_code='3';; # 3 for 32-bit
847 x86_64) arch_code='6';; # 6 for 64-bit
848 any) arch_code='0';; # 0 for any arch
849 esac
851 sed -i "/^$PACKAGE\t/d" $pi # remove old entry
852 cat >> $pi <<EOT
853 $PACKAGE $VERSION$EXTRAVERSION $CATEGORY $SHORT_DESC $WEB_SITE $TAGS $SIZES $DEPENDS $rsum $PROVIDE $arch_code
854 EOT
856 # files.list (uncompressed, unsorted, located in $cache)
857 fl="$cache/files.list"
858 touch $fl
859 sed -i "/^$PACKAGE: /d" $fl
860 sed "s/^/$PACKAGE: \0/" $pack/files.list >> $fl
862 footer "$(_ 'Package "%s" created' "$tazpkg")"
863 }
866 packit "$1"