cookutils annotate modules/pack @ rev 1120

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