cookutils annotate modules/pack @ rev 1135

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