cookutils view cook @ rev 893
web/cooker.cgi: work with HTTP headers "Last-Modified", "If-Modified-Since", "HTTP 304 Not Modified", "HTTP 404 Not Found". Other small improvements.
SliTaz Next Cooker is working right now with this version of cooker.cgi.
SliTaz Next Cooker is working right now with this version of cooker.cgi.
author | Aleksej Bobylev <al.bobylev@gmail.com> |
---|---|
date | Mon Mar 20 05:12:29 2017 +0200 (2017-03-20) |
parents | 6ceb2fe81f83 |
children | 2ff4c8d701d3 |
line source
1 #!/bin/sh
2 #
3 # Cook - A tool to cook and generate SliTaz packages. Read the README
4 # before adding or modifying any code in cook!
5 #
6 # Copyright (C) SliTaz GNU/Linux - GNU gpl v3
7 # Author: Christophe Lincoln <pankso@slitaz.org>
8 #
10 . /usr/lib/slitaz/libcook.sh
12 VERSION="3.2"
13 export output=raw
16 # Internationalization.
18 export TEXTDOMAIN='cook'
21 #
22 # Functions
23 #
25 usage() {
26 cat <<EOT
28 $(boldify "$(_ 'Usage:')") $(_ 'cook [package|command] [list|--option]')
30 $(boldify "$(_ 'Commands:')")
31 usage|help $(_ 'Display this short usage.')
32 setup $(_ 'Setup your build environment.')
33 *-setup $(_ 'Setup a cross environment.')
34 * = {arm|armv6hf|armv7|x86_64}
35 test $(_ 'Test environment and cook a package.')
36 list-wok $(_ 'List packages in the wok.')
37 search $(_ 'Simple packages search function.')
38 new $(_ 'Create a new package with a receipt.')
39 list $(_ 'Cook a list of packages.')
40 clean-wok $(_ 'Clean-up all packages files.')
41 clean-src $(_ 'Clean-up all packages sources.')
42 uncook $(_ 'Check for uncooked packages')
43 pkgdb $(_ 'Create packages DB lists and flavors.')
45 $(boldify "$(_ 'Options:')")
46 cook <pkg>
47 --clean -c $(_ 'clean the package in the wok.')
48 --install -i $(_ 'cook and install the package.')
49 --getsrc -gs $(_ 'get the package source tarball.')
50 --block -b $(_ 'block a package so cook will skip it.')
51 --unblock -ub $(_ 'unblock a blocked package.')
52 --cdeps $(_ 'check dependencies of cooked package.')
53 --pack $(_ 'repack an already built package.')
54 --debug $(_ 'display debugging messages.')
55 --continue $(_ 'continue running compile_rules.')
56 cook new <pkg>
57 --interactive -x $(_ 'create a receipt interactively.')
58 cook setup
59 --wok $(_ 'clone the cooking wok from Hg repo.')
60 --stable $(_ 'clone the stable wok from Hg repo.')
61 --undigest $(_ 'clone the undigest wok from Hg repo.')
62 --tiny $(_ 'clone the tiny SliTaz wok from Hg repo.')
63 --forced $(_ 'force reinstall of chroot packages.')
64 cook pkgdb
65 --flavors $(_ 'create up-to-date flavors files.')
67 EOT
68 exit 0
69 }
72 # We don't want these escapes in web interface.
74 clean_log() {
75 sed -i -e s'|\[70G\[ \[1;32m| |' \
76 -e s'|\[0;39m \]||' $LOGS/$pkg.log
77 }
80 # Be sure package exists in wok.
82 check_pkg_in_wok() {
83 [ -d "$WOK/$pkg" ] || die 'Unable to find package "%s" in the wok' "$pkg"
84 }
87 if_empty_value() {
88 # L10n: QA is quality assurance
89 [ -n "$value" ] || die 'QA: empty variable: %s' "$var=\"\""
90 }
93 # Initialize files used in $CACHE
95 init_db_files() {
96 _ 'Creating directories structure in "%s"' "$SLITAZ"
97 mkdir -p $WOK $PKGS $SRC $CACHE $LOGS $FEEDS
98 _ 'Creating DB files in "%s"' "$CACHE"
99 touch $activity $command $broken $blocked
100 }
103 # QA: check a receipt consistency before building.
105 receipt_quality() {
106 _ 'QA: checking package receipt...'
107 unset online
108 if ifconfig | grep -q -A 1 "^[a-z]*[0-9]" | fgrep 'addr:'; then
109 online='online'
110 fi
111 for var in PACKAGE VERSION CATEGORY SHORT_DESC MAINTAINER WEB_SITE; do
112 unset value
113 value="$(. $receipt; eval echo \$$var)"
114 case "$var" in
115 PACKAGE|VERSION|SHORT_DESC)
116 if_empty_value
117 ;;
118 CATEGORY)
119 value="${value:-empty}"
120 valid="$(echo $PKGS_CATEGORIES)" # avoid newlines
121 if ! echo " $valid " | grep -q " $value "; then
122 _ 'QA: unknown category "%s"' "$value"
123 die 'Please, use one of: %s' "$valid"
124 fi
125 ;;
126 WEB_SITE)
127 # We don't check WGET_URL since if dl is needed it will fail.
128 # Break also if we're not online. Here error is not fatal.
129 if_empty_value
130 [ -z "$online" ] && break
131 if ! busybox wget -T 12 -s $value 2>/dev/null; then
132 _ 'QA: unable to reach "%s"' "$value"
133 fi
134 ;;
135 esac
136 done
137 }
140 # Paths used in receipt and by cook itself.
142 set_paths() {
143 pkgdir="$WOK/$PACKAGE"
144 . "$pkgdir/receipt"
145 basesrc="$pkgdir/source"
146 tmpsrc="$basesrc/tmp"
147 src="$basesrc/$PACKAGE-$VERSION"
148 taz="$pkgdir/taz"
149 pack="$taz/$PACKAGE-$VERSION$EXTRAVERSION"
150 fs="$pack/fs"
151 stuff="$pkgdir/stuff"
152 install="$pkgdir/install"
153 pkgsrc="${SOURCE:-$PACKAGE}-${KBASEVER:-$VERSION}"
154 lzma_tarball="$pkgsrc.tar.lzma"
155 if [ -n "$PATCH" ]; then
156 [ -z "$PTARBALL" ] && PTARBALL="$(basename $PATCH)"
157 fi
158 if [ -n "$WANTED" ]; then
159 basesrc="$WOK/$WANTED/source"
160 src="$basesrc/$WANTED-$VERSION"
161 install="$WOK/$WANTED/install"
162 wanted_stuff="$WOK/$WANTED/stuff"
163 fi
164 if [ -n "$SOURCE" ]; then
165 source_stuff="$WOK/$SOURCE/stuff"
166 fi
167 # Kernel version is set from wok/linux or installed/linux-api-headers(wok-undigest)
168 if [ -f "$WOK/linux/receipt" ]; then
169 kvers=$(grep ^VERSION= $WOK/linux/receipt | cut -d\" -f2)
170 kbasevers=${kvers:0:3}
171 elif [ -f "$INSTALLED/linux-api-headers/receipt" ]; then
172 kvers=$(grep ^VERSION= $INSTALLED/linux-api-headers/receipt | cut -d\" -f2)
173 kbasevers=${kvers:0:3}
174 fi
175 # Python version
176 if [ -f "$WOK/python/receipt" ]; then
177 pyvers=$(grep ^VERSION= $WOK/python/receipt | cut -d\" -f2)
178 fi
179 # Perl version for some packages needed it
180 if [ -f "$WOK/perl/receipt" ]; then
181 perlvers=$(grep ^VERSION= $WOK/perl/receipt | cut -d\" -f2)
182 fi
183 # Old way compatibility.
184 _pkg="$install"
185 }
188 # Create source tarball when URL is a SCM.
190 create_tarball() {
191 local tarball
192 tarball="$pkgsrc.tar.bz2"
193 [ -n "$LZMA_SRC" ] && tarball="$lzma_tarball"
194 _ 'Creating tarball "%s"' "$tarball"
195 if [ -n "$LZMA_SRC" ]; then
196 tar -c $pkgsrc | lzma e $SRC/$tarball -si $LZMA_SET_DIR || exit 1
197 LZMA_SRC=''
198 else
199 tar -cjf $tarball $pkgsrc || exit 1
200 mv $tarball $SRC; rm -rf $pkgsrc
201 fi
202 TARBALL="$tarball"
203 }
206 # Get package source. For SCM we are in cache so clone here and create a
207 # tarball here.
209 get_source() {
210 local url
211 url=${WGET_URL#*|}
212 set_paths
213 pwd=$(pwd)
214 case "$WGET_URL" in
215 http://*|ftp://*|https://*)
216 url="$MIRROR_URL/sources/packages/${TARBALL:0:1}/$TARBALL"
217 wget -T 60 -c -O $SRC/$TARBALL $WGET_URL ||
218 wget -T 60 -c -O $SRC/$TARBALL $url ||
219 die 'ERROR: %s' "wget $WGET_URL"
220 ;;
222 hg*|mercurial*)
223 _ 'Getting source from %s...' 'Hg'
224 _ 'URL: %s' "$url"
225 _ 'Cloning to "%s"' "$pwd/$pkgsrc"
226 if [ -n "$BRANCH" ]; then
227 _ 'Hg branch: %s' "$BRANCH"
228 hg clone $url --rev $BRANCH $pkgsrc ||
229 die 'ERROR: %s' "hg clone $url --rev $BRANCH"
230 else
231 hg clone $url $pkgsrc || die 'ERROR: %s' "hg clone $url"
232 fi
233 rm -rf $pkgsrc/.hg
234 create_tarball
235 ;;
237 git*)
238 _ 'Getting source from %s...' 'Git'
239 _ 'URL: %s' "$url"
240 cd $SRC
241 git clone $url $pkgsrc || die 'ERROR: %s' "git clone $url"
242 if [ -n "$BRANCH" ]; then
243 _ 'Git branch: %s' "$BRANCH"
244 cd $pkgsrc; git checkout $BRANCH; cd ..
245 fi
246 cd $SRC
247 create_tarball
248 ;;
250 cvs*)
251 mod=$PACKAGE
252 [ -n "$CVS_MODULE" ] && mod=$CVS_MODULE
253 _ 'Getting source from %s...' 'CVS'
254 _ 'URL: %s' "$url"
255 [ -n "$CVS_MODULE" ] && _ 'CVS module: %s' "$mod"
256 _ 'Cloning to "%s"' "$pwd/$mod"
257 cvs -d:$url co $mod && mv $mod $pkgsrc
258 create_tarball
259 ;;
261 svn*|subversion*)
262 _ 'Getting source from %s...' 'SVN'
263 _ 'URL: %s' "$url"
264 if [ -n "$BRANCH" ]; then
265 echo t | svn co $url -r $BRANCH $pkgsrc
266 else
267 echo t | svn co $url $pkgsrc
268 fi
269 create_tarball
270 ;;
272 bzr*)
273 _ 'Getting source from %s...' 'bazaar'
274 cd $SRC
275 pkgsrc=${url#*:}
276 if [ -n "$BRANCH" ]; then
277 echo "bzr -Ossl.cert_reqs=none branch $url -r $BRANCH"
278 bzr -Ossl.cert_reqs=none branch $url -r $BRANCH
279 else
280 echo "bzr -Ossl.cert_reqs=none branch $url"
281 bzr -Ossl.cert_reqs=none branch $url
282 cd $pkgsrc; BRANCH=$(bzr revno); cd ..
283 _ "Don't forget to add to receipt:"
284 echo -e "BRANCH=\"$BRANCH\"\n"
285 fi
286 mv $pkgsrc $pkgsrc-$BRANCH
287 pkgsrc="$pkgsrc-$BRANCH"
288 create_tarball ;;
290 *)
291 (newline; _ 'ERROR: Unable to handle "%s"' "$WGET_URL"; newline) | \
292 tee -a $LOGS/$PACKAGE.log
293 exit 1 ;;
294 esac
295 }
298 # Extract source package.
300 extract_source() {
301 if [ ! -s "$SRC/$TARBALL" ]; then
302 local url
303 url="$MIRROR_URL/sources/packages"
304 url="$url/${TARBALL:0:1}/$TARBALL"
305 _ 'Getting source from %s...' 'mirror'
306 _ 'URL: %s' "$url"
307 busybox wget -c -P $SRC $url || _ 'ERROR: %s' "wget $url"
308 fi
309 _ 'Extracting source archive "%s"' "$TARBALL"
310 case "$TARBALL" in
311 *.tar.gz|*.tgz) tar -xzf $SRC/$TARBALL 2>/dev/null ;;
312 *.tar.bz2|*.tbz|*.tbz2) tar -xjf $SRC/$TARBALL 2>/dev/null ;;
313 *.tar.lzma) tar -xaf $SRC/$TARBALL ;;
314 *.tar.lz|*.tlz) lzip -d < $SRC/$TARBALL | tar -xf - 2>/dev/null ;;
315 *.tar) tar -xf $SRC/$TARBALL ;;
316 *.zip|*.xpi) unzip -o $SRC/$TARBALL ;;
317 *.xz) unxz -c $SRC/$TARBALL | tar -xf - || \
318 tar -xf $SRC/$TARBALL 2>/dev/null;;
319 *.7z) 7zr x $SRC/$TARBALL 2>/dev/null >&2 ;;
320 *.Z|*.z) uncompress -c $SRC/$TARBALL | tar -xf - ;;
321 *.rpm) rpm2cpio $SRC/$TARBALL | cpio -idm --quiet ;;
322 *.run) /bin/sh $SRC/$TARBALL $RUN_OPTS ;;
323 *) cp $SRC/$TARBALL $(pwd) ;;
324 esac
325 }
328 # Display time.
330 disp_time() {
331 local sec div min
332 sec="$1"
333 div=$(( ($1 + 30) / 60))
334 case $div in
335 0) min='';;
336 # L10n: 'm' is for minutes (approximate cooking time)
337 *) min=$(_n ' ~ %dm' "$div");;
338 esac
340 # L10n: 's' is for seconds (cooking time)
341 _ '%ds%s' "$sec" "$min"
342 }
345 # Display cooked package summary.
347 summary() {
348 set_paths
349 cd $WOK/$pkg
350 [ -d $WOK/$pkg/install ] && prod=$(du -sh $WOK/$pkg/install | awk '{print $1}' 2>/dev/null)
351 [ -d $WOK/$pkg/source ] && srcdir=$(du -sh $WOK/$pkg/source | awk '{print $1}' 2>/dev/null)
352 fs=$(du -sh $WOK/$pkg/taz/* | awk '{print $1}')
353 size=$(ls -lh $PKGS/$pkg-${VERSION}*.tazpkg | awk '{print $5}')
354 files=$(cat $WOK/$pkg/taz/$pkg-*/files.list | wc -l) # please keep cat here, otherwise it'll not work
355 [ -n "$TARBALL" ] && srcsize=$(du -sh $SRC/$TARBALL | awk '{print $1}')
357 _ 'Summary for: %s' "$PACKAGE $VERSION"
358 separator
360 # L10n: keep the same width of translations to get a consistent view
361 [ -n "$srcdir" ] && _ 'Source dir : %s' "$srcdir"
362 [ -n "$TARBALL" ] && _ 'Src file : %s' "$TARBALL"
363 [ -n "$srcsize" ] && _ 'Src size : %s' "$srcsize"
364 [ -n "$prod" ] && _ 'Produced : %s' "$prod"
365 _ 'Packed : %s' "$fs"
366 _ 'Compressed : %s' "$size"
367 _ 'Files : %s' "$files"
368 _ 'Cook time : %s' "$(disp_time "$time")"
369 _ 'Cook date : %s' "$(date "$(_ '+%%F %%R')")"
370 _ 'Host arch : %s' "$ARCH"
371 separator
372 }
375 # Display debugging error info.
377 debug_info() {
378 title 'Debug information'
379 # L10n: specify your format of date and time (to help: man date)
380 # L10n: not bad one is '+%x %R'
381 _ 'Cook date: %s' "$(date "$(_ '+%%F %%R')")"
382 if [ -n "$time" ]; then
383 times="$(($(date +%s) - $time))"
384 _ 'Cook time : %s' "$(disp_time "$times")"
385 fi
386 for error in \
387 ERROR 'No package' "cp: can't" "can't open" "can't cd" \
388 'error:' 'fatal error:' 'undefined reference to' \
389 'Unable to connect to' 'link: cannot find the library' \
390 'CMake Error' ': No such file or directory' \
391 'Could not read symbols: File in wrong format'
392 do
393 # format "line number:line content"
394 fgrep -n "$error" $LOGS/$pkg.log
395 done > $LOGS/$pkg.log.debug_info 2>&1
396 # sort by line number, remove duplicates
397 sort -gk1,1 -t: -u $LOGS/$pkg.log.debug_info
398 rm -f $LOGS/$pkg.log.debug_info
399 footer
400 }
403 # A bit smarter function than the classic `cp` command
405 copy() {
406 if [ "$(stat -c %h -- "$1")" -gt 1 ]; then
407 cp -al "$1" "$2" # copy hardlinks
408 else
409 cp -a "$1" "$2" # copy generic files
410 fi
411 }
414 # Copy all generic files (locale, pixmaps, .desktop). We use standard paths,
415 # so some packages need to copy these files with the receipt and genpkg_rules.
417 copy_generic_files() {
418 # $LOCALE is set in cook.conf
419 if [ -n "$LOCALE" -a -z "$WANTED" ]; then
420 if [ -d "$install/usr/share/locale" ]; then
421 mkdir -p $fs/usr/share/locale
422 for i in $LOCALE; do
423 if [ -d "$install/usr/share/locale/$i" ]; then
424 copy $install/usr/share/locale/$i $fs/usr/share/locale
425 fi
426 done
427 fi
428 fi
430 # Generic pixmaps copy can be disabled with COOKOPTS="!pixmaps" (or GENERIC_PIXMAPS="no")
431 if [ "${COOKOPTS/!pixmaps/}" == "$COOKOPTS" -a "$GENERIC_PIXMAPS" != 'no' ]; then
432 if [ -d "$install/usr/share/pixmaps" ]; then
433 mkdir -p $fs/usr/share/pixmaps
434 for i in png xpm; do
435 [ -f "$install/usr/share/pixmaps/$PACKAGE.$i" ] &&
436 copy $install/usr/share/pixmaps/$PACKAGE.$i $fs/usr/share/pixmaps
437 done
438 fi
440 # Custom or homemade PNG pixmap can be in stuff.
441 if [ -f "$stuff/$PACKAGE.png" ]; then
442 mkdir -p $fs/usr/share/pixmaps
443 copy $stuff/$PACKAGE.png $fs/usr/share/pixmaps
444 fi
445 fi
447 # Desktop entry (.desktop).
448 # Generic desktop entry copy can be disabled with COOKOPTS="!menus" (or GENERIC_MENUS="no")
449 if [ "${COOKOPTS/!menus/}" == "$COOKOPTS" -a "$GENERIC_MENUS" != 'no' ]; then
450 if [ -d "$install/usr/share/applications" ] && [ -z "$WANTED" ]; then
451 mkdir -p $fs/usr/share
452 copy $install/usr/share/applications $fs/usr/share
453 fi
454 fi
456 # Homemade desktop file(s) can be in stuff.
457 if [ -d "$stuff/applications" ]; then
458 mkdir -p $fs/usr/share
459 copy $stuff/applications $fs/usr/share
460 fi
461 if [ -f "$stuff/$PACKAGE.desktop" ]; then
462 mkdir -p $fs/usr/share/applications
463 copy $stuff/$PACKAGE.desktop $fs/usr/share/applications
464 fi
466 # Add custom licenses
467 if [ -d "$stuff/licenses" ]; then
468 mkdir -p $fs/usr/share/licenses
469 copy $stuff/licenses $fs/usr/share/licenses/$PACKAGE
470 fi
471 }
474 # Remove files provided by split packages
475 # For example:
476 # 1. Package "pkg-main":
477 # SPLIT="pkg-1 pkg-2 pkg-extra"
478 # 2. Package="pkg-extra":
479 # WANTED="pkg-main"
480 # BUILD_DEPENDS="pkg-1 pkg-2"
481 # cook_copy_folders usr
482 # cook_split_rm $BUILD_DEPENDS
484 cook_split_rm() {
485 for i in $@; do
486 action 'Remove files provided by split package %s...' "$i"
487 while read j; do
488 [ -f "$fs$j" -o -h "$fs$j" ] && rm $fs$j
489 rmdir "$(dirname "$fs$j")" 2>/dev/null
490 done < $WOK/$i/taz/$i-$VERSION/files.list
491 :; status
492 done
493 }
496 # Update installed.cook.diff
498 update_installed_cook_diff() {
499 # If a cook failed deps are removed.
500 cd $root$INSTALLED; ls -1 > $CACHE/installed.cook
501 cd $CACHE
502 [ "$1" == 'force' -o ! -s '/tmp/installed.cook.diff' ] && \
503 busybox diff installed.list installed.cook > /tmp/installed.cook.diff
504 deps=$(cat /tmp/installed.cook.diff | grep ^+[a-zA-Z0-9] | wc -l)
505 }
508 # Remove installed deps.
510 remove_deps() {
511 # Now remove installed build deps.
512 diff='/tmp/installed.cook.diff'
513 if [ -s $diff ]; then
514 deps=$(cat $diff | grep ^+[a-zA-Z0-9] | sed s/^+//)
515 nb=$(cat $diff | grep ^+[a-zA-Z0-9] | wc -l)
516 _n 'Build dependencies to remove:'; echo " $nb"
517 [ -n "$root" ] && echo "root=\"$root\""
518 _n 'Removing:'
519 for dep in $deps; do
520 echo -n " $dep"
521 echo 'y' | tazpkg remove $dep --root=$root >/dev/null
522 done
523 newline; newline
524 # Keep the last diff for debug and info.
525 mv -f $diff $CACHE/installed.diff
526 fi | fold -sw80
527 }
530 # The main cook function.
532 cookit() {
533 if [ -n "$SETUP_MD5" ] && [ "$SETUP_MD5" != "$(ls $root$INSTALLED | \
534 md5sum | cut -c1-32)" ]; then
535 _ 'ERROR: Broken setup. Abort.'
536 return
537 fi
539 title 'Cook: %s' "$PACKAGE $VERSION"
540 set_paths
542 # Handle cross-tools.
543 case "$ARCH" in
544 arm*|x86_64)
545 # CROSS_COMPILE is used by at least Busybox and the kernel to set
546 # the cross-tools prefix. Sysroot is the root of our target arch
547 sysroot="$CROSS_TREE/sysroot"
548 tools="$CROSS_TREE/tools"
549 # Set root path when cross compiling. ARM tested but not x86_64
550 # When cross compiling we must install build deps in $sysroot.
551 arch="-$ARCH"
552 root="$sysroot"
553 _ '%s sysroot: %s' "$ARCH" "$sysroot"
554 _ 'Adding "%s" to PATH' "$tools/bin"
555 export PATH="$PATH:$tools/bin"
556 export PKG_CONFIG_PATH="$sysroot/usr/lib/pkgconfig"
557 export CROSS_COMPILE="$HOST_SYSTEM-"
558 _ 'Using cross-tools: %s' "$CROSS_COMPILE"
559 if [ "$ARCH" == 'x86_64' ]; then
560 export CC="$HOST_SYSTEM-gcc -m64"
561 export CXX="$HOST_SYSTEM-g++ -m64"
562 else
563 export CC="$HOST_SYSTEM-gcc"
564 export CXX="$HOST_SYSTEM-g++"
565 fi
566 export AR="$HOST_SYSTEM-ar"
567 export AS="$HOST_SYSTEM-as"
568 export RANLIB="$HOST_SYSTEM-ranlib"
569 export LD="$HOST_SYSTEM-ld"
570 export STRIP="$HOST_SYSTEM-strip"
571 export LIBTOOL="$HOST_SYSTEM-libtool" ;;
572 esac
574 [ -n "$QA" ] && receipt_quality
575 cd $pkgdir
576 [ -z "$continue" ] && rm -rf source 2>/dev/null
577 rm -rf install taz 2>/dev/null
579 # Disable -pipe if less than 512 MB free RAM.
580 free=$(awk '/^MemFree|^Buffers|^Cached/{s+=$2}END{print int(s/1024)}' /proc/meminfo)
581 if [ "$free" -lt 512 ] && [ "$CFLAGS" != "${CFLAGS/-pipe}" ]; then
582 _ 'Disabling -pipe compile flag: %d MB RAM free' "$free"
583 CFLAGS="${CFLAGS/-pipe}"; CFLAGS=$(echo "$CFLAGS" | tr -s ' ')
584 CXXFLAGS="${CXXFLAGS/-pipe}"; CXXFLAGS=$(echo "$CXXFLAGS" | tr -s ' ')
585 fi
586 unset free
588 # Export flags and path to be used by make and receipt.
589 DESTDIR="$pkgdir/install"
590 # FIXME: L10n: Is this the right time for 'LC_ALL=C LANG=C'?
591 export DESTDIR MAKEFLAGS CFLAGS CXXFLAGS CONFIG_SITE LC_ALL=C LANG=C
592 #LDFLAGS
594 # Check for build deps and handle implicit depends of *-dev packages
595 # (ex: libusb-dev :: libusb).
596 rm -f $CACHE/installed.local $CACHE/installed.web $CACHE/missing.dep
597 touch $CACHE/installed.local $CACHE/installed.web
598 [ -n "$BUILD_DEPENDS" ] && _ 'Checking build dependencies...'
599 [ -n "$root" ] && _ 'Using packages DB: %s' "$root$DB"
600 for dep in $BUILD_DEPENDS; do
601 implicit="${dep%-dev}"
602 # Don't add implicit dependency if it defined in DEPENDS
603 # echo '' $DEPENDS '' | fgrep -q " $implicit " && implicit=''
604 for i in $dep $implicit; do
605 if [ ! -f "$root$INSTALLED/$i/receipt" ]; then
606 # Try local package first. In some cases implicit doesn't exist, ex:
607 # libboost-dev exists but not libboost, so check if we got vers.
608 unset vers
609 vers=$(. $WOK/$i/receipt 2>/dev/null ; echo $VERSION)
610 # We may have a local package.
611 if [ -z "$vers" ]; then
612 vers=$(awk -F$'\t' -vp="$i" '$1==p{print $2; quit}' $PKGS/packages.info 2> /dev/null)
613 fi
614 debug "bdep: $i version: $vers"
615 if [ -f "$PKGS/$i-$vers$arch.tazpkg" ]; then
616 echo $i-$vers$arch.tazpkg >> $CACHE/installed.local
617 else
618 # Priority to package version in wok (maybe more up-to-date)
619 # than the mirrored one.
620 if [ -n "$vers" ]; then
621 if fgrep -q $i-$vers$arch $root$DB/packages.list; then
622 echo $i >> $CACHE/installed.web
623 else
624 # So package exists in wok but not available.
625 _ 'Missing dep (wok/pkg): %s' "$i $vers"
626 echo $i >> $CACHE/missing.dep
627 fi
628 else
629 # Package is not in wok but may be in online repo.
630 if fgrep -q $i-$vers$arch $root$DB/packages.list; then
631 echo $i >> $CACHE/installed.web
632 else
633 _ 'ERROR: unknown dep "%s"' "$i"
634 exit 1
635 fi
636 fi
637 fi
638 fi
639 done
640 done
642 # Get the list of installed packages
643 cd $root$INSTALLED; ls -1 > $CACHE/installed.list
645 # Have we a missing build dep to cook?
646 if [ -s "$CACHE/missing.dep" ] && [ -n "$AUTO_COOK" ]; then
647 _ 'Auto cook config is set: %s' "$AUTO_COOK"
648 cp -f $LOGS/$PACKAGE.log $LOGS/$PACKAGE.log.$$
649 for i in $(uniq $CACHE/missing.dep); do
650 (_ 'Building dep (wok/pkg) : %s' "$i $vers") | \
651 tee -a $LOGS/$PACKAGE.log.$$
652 # programmers: next two messages are exact copy from remove_deps()
653 togrep1=$(_n 'Build dependencies to remove:')
654 togrep2=$(_n 'Removing:')
655 cook $i || (_ "ERROR: can't cook dep \"%s\"" "$i" && newline && \
656 fgrep $togrep1 $LOGS/$i.log && \
657 fgrep $togrep2 $LOGS/$i.log && newline) | \
658 tee -a $LOGS/$PACKAGE.log.$$ && break
659 done
660 rm -f $CACHE/missing.dep
661 mv $LOGS/$PACKAGE.log.$$ $LOGS/$PACKAGE.log
662 fi
664 # QA: Exit on missing dep errors. We exit in both cases, if AUTO_COOK
665 # is enabled and cook fails we have ERROR in log, if no auto cook we have
666 # missing dep in cached file.
667 lerror=$(_n 'ERROR')
668 if fgrep -q ^$lerror $LOGS/$pkg.log || [ -s "$CACHE/missing.dep" ]; then
669 [ -s "$CACHE/missing.dep" ] && nb=$(cat $CACHE/missing.dep | wc -l)
670 _p 'ERROR: missing %d dependency' 'ERROR: missing %d dependencies' "$nb" "$nb"
671 exit 1
672 fi
674 # Install local packages: package-version$arch
675 cd $PKGS
676 for i in $(uniq $CACHE/installed.local); do
677 # _ 'Installing dep (pkg/local): %s' "$i"
678 tazpkg install $i --root=$root --local --quiet --cookmode
679 done
681 # Install web or cached packages (if mirror is set to $PKGS we only
682 # use local packages).
683 for i in $(uniq $CACHE/installed.web); do
684 # _ 'Installing dep (web/cache): %s' "$i"
685 tazpkg get-install $i --root=$root --quiet --cookmode
686 done
688 update_installed_cook_diff
690 # Get source tarball and make sure we have source dir named:
691 # $PACKAGE-$VERSION to be standard in receipts. Here we use tar.lzma
692 # tarball if it exists.
693 if [ -n "$WGET_URL" ] && [ ! -f "$SRC/$TARBALL" ]; then
694 if [ -f "$SRC/${SOURCE:-$PACKAGE}-$VERSION.tar.lzma" ]; then
695 TARBALL="${SOURCE:-$PACKAGE}-$VERSION.tar.lzma"
696 LZMA_SRC=''
697 else
698 get_source || exit 1
699 fi
700 fi
701 if [ -z "$WANTED" ] && [ -n "$TARBALL" ] && [ ! -d "$src" ]; then
702 mkdir -p $pkgdir/source/tmp; cd $pkgdir/source/tmp
703 if ! extract_source ; then
704 get_source
705 extract_source || exit 1
706 fi
707 if [ -n "$LZMA_SRC" ]; then
708 cd $pkgdir/source
709 if [ "$(ls -A tmp | wc -l)" -gl 1 ] || [ -f "$(echo tmp/*)" ]; then
710 mv tmp tmp-1; mkdir tmp
711 mv tmp-1 tmp/${SOURCE:-$PACKAGE}-$VERSION
712 fi
713 if [ -d "tmp/${SOURCE:-$PACKAGE}-$VERSION" ]; then
714 cd tmp; tar -c * | lzma e $SRC/$TARBALL -si
715 fi
716 fi
717 cd $pkgdir/source/tmp
718 # Some archives are not well done and don't extract to one dir (ex lzma).
719 files=$(ls | wc -l)
720 [ "$files" == 1 ] && [ -d "$(ls)" ] && mv * ../$PACKAGE-$VERSION
721 [ "$files" == 1 ] && [ -f "$(ls)" ] && mkdir -p ../$PACKAGE-$VERSION && \
722 mv * ../$PACKAGE-$VERSION/$TARBALL
723 [ "$files" -gt 1 ] && mkdir -p ../$PACKAGE-$VERSION && \
724 mv * ../$PACKAGE-$VERSION
725 cd ..; rm -rf tmp
726 fi
728 # Libtool shared libs path hack.
729 case "$ARCH" in
730 arm*) cross libhack ;;
731 esac
733 # Execute receipt rules.
734 if grep -q ^compile_rules $receipt; then
735 _ 'Executing: %s' 'compile_rules'
736 echo "CFLAGS : $CFLAGS"
737 #echo "LDFLAGS : $LDFLAGS"
738 [ -d "$src" ] && cd $src
739 compile_rules $@ || exit 1
740 # Stay compatible with _pkg
741 [ -d "$src/_pkg" ] && mv $src/_pkg $install
742 # QA: compile_rules success so valid.
743 mkdir -p $install
744 else
745 # QA: no compile_rules so no error, valid.
746 mkdir -p $install
747 fi
749 # Actions to do after compiling the package
750 # Skip all for split packages (already done in main package)
751 if [ -z "$WANTED" ]; then
752 footer
753 export COOKOPTS ARCH install; @@PREFIX@@/libexec/cookutils/compressor install
754 fi
755 footer
757 # Execute testsuite.
758 if grep -q ^testsuite $receipt; then
759 title 'Running testsuite'
760 testsuite $@ || exit 1
761 footer
762 fi
764 update_installed_cook_diff force
765 }
768 # Cook quality assurance.
770 cookit_quality() {
771 if [ ! -d "$WOK/$pkg/install" ] && [ -z "$WANTED" ]; then
772 _ 'ERROR: cook failed' | tee -a $LOGS/$pkg.log
773 fi
774 # ERROR can be echoed any time in cookit()
775 lerror=$(_n 'ERROR')
776 if grep -Ev "(conftest|configtest)" $LOGS/$pkg.log | \
777 grep -Eq "(^$lerror|undefined reference to)" ; then
778 debug_info | tee -a $LOGS/$pkg.log
779 rm -f $command
780 exit 1
781 fi
782 }
785 # Create the package. Wanted to use TazPkg to create a tazpkg package at first,
786 # but it doesn't handle EXTRAVERSION.
788 packit() {
789 set_paths
791 # Handle cross compilation
792 case "$ARCH" in
793 arm*|x86_64) arch="-$ARCH" ;;
794 esac
796 title 'Pack: %s' "$PACKAGE $VERSION$arch"
798 if grep -q ^genpkg_rules $receipt; then
799 _ 'Executing: %s' 'genpkg_rules'
800 set -e; cd $pkgdir; mkdir -p $fs
801 genpkg_rules || (newline; _ 'ERROR: genpkg_rules failed'; newline) >> \
802 $LOGS/$pkg.log
803 else
804 _ 'No packages rules: meta package'
805 mkdir -p $fs
806 fi
808 # Check CONFIG_FILES
809 if [ -n "$CONFIG_FILES" ]; then
810 for i in $CONFIG_FILES; do
811 if [ ! -e $fs$i ]; then
812 case $i in
813 */) mkdir -p $fs$i ;;
814 *) mkdir -p $fs$(dirname $i); touch $fs$i ;;
815 esac
816 fi
817 done
818 fi
820 # First QA check to stop now if genpkg_rules failed.
821 lerror=$(_n 'ERROR')
822 if fgrep -q ^$lerror $LOGS/$pkg.log; then
823 exit 1
824 fi
826 cd $taz
827 for file in receipt description.txt; do
828 [ ! -f "../$file" ] && continue
829 action 'Copying "%s"...' "$file"
830 cp -f ../$file $pack; chown 0.0 $pack/$file; status
831 done
832 copy_generic_files
834 # Strip and stuff files.
835 export COOKOPTS ARCH HOST_SYSTEM LOCALE fs; @@PREFIX@@/libexec/cookutils/compressor fs
837 # Create files.list with redirecting find output.
838 action 'Creating the list of files...'
839 cd $fs
840 find . -type f -print > ../files.list
841 find . -type l -print >> ../files.list
842 cd ..; sed -i s/'^.'/''/ files.list
843 status
845 # Md5sum of files.
846 action 'Creating md5sum of files...'
847 while read file; do
848 [ -L "fs$file" ] && continue
849 [ -f "fs$file" ] || continue
850 case "$file" in
851 /lib/modules/*/modules.*|*.pyc) continue ;;
852 esac
853 md5sum "fs$file" | sed 's/ fs/ /'
854 done < files.list > md5sum
855 status
857 UNPACKED_SIZE=$(du -chs fs receipt files.list md5sum description.txt \
858 2>/dev/null | awk 'END{ print $1 }')
860 # Build cpio archives.
861 action 'Compressing the FS...'
862 find fs -newer $receipt -exec touch -hr $receipt {} \;
863 find fs | cpio -o -H newc --quiet | lzma e fs.cpio.lzma -si
864 rm -rf fs
865 status
867 PACKED_SIZE=$(du -chs fs.cpio.lzma receipt files.list md5sum description.txt \
868 2>/dev/null | awk 'END{ print $1 }')
870 action 'Updating receipt sizes...'
871 sed -i s/^PACKED_SIZE.*$// receipt
872 sed -i s/^UNPACKED_SIZE.*$// receipt
873 sed -i "s/^PACKAGE=/PACKED_SIZE=\"$PACKED_SIZE\"\nUNPACKED_SIZE=\"$UNPACKED_SIZE\"\nPACKAGE=/" receipt
874 status
876 # Set extra version.
877 if [ -n "$EXTRAVERSION" ]; then
878 action 'Updating receipt EXTRAVERSION: %s' "$EXTRAVERSION"
879 sed -i s/^EXTRAVERSION.*$// receipt
880 sed -i "s/^VERSION=/EXTRAVERSION=\"$EXTRAVERSION\"\nVERSION=/" receipt
881 status
882 fi
884 # Compress.
885 action 'Creating full cpio archive...'
886 find . -print | cpio -o -H newc --quiet > \
887 ../$PACKAGE-$VERSION$EXTRAVERSION$arch.tazpkg
888 status
890 action 'Restoring original package tree...'
891 unlzma -c fs.cpio.lzma | cpio -idm --quiet
892 status
894 rm fs.cpio.lzma; cd ..
896 # QA and give info.
897 tazpkg=$(ls *.tazpkg)
898 packit_quality
899 footer "$(_ 'Package "%s" created' "$tazpkg")"
900 }
903 # Verify package quality and consistency.
905 packit_quality() {
906 #action 'QA: checking for broken link...'
907 #link=$(find $fs/usr -type l -follow)
908 #[ "$link" ] && echo -e "\nERROR: broken link in filesystem"
909 #status
911 # Exit if any error found in log file.
912 lerror=$(_n 'ERROR')
913 if fgrep -q ^$lerror $LOGS/$pkg.log; then
914 rm -f $command
915 exit 1
916 fi
918 action 'QA: checking for empty package...'
919 files=$(cat $WOK/$pkg/taz/$pkg-*/files.list | wc -l)
920 if [ "$files" -eq 0 -a "$CATEGORY" != 'meta' ]; then
921 newline; _ 'ERROR: empty package'
922 rm -f $command
923 exit 1
924 else
925 :; status
926 # Find and remove old package(s)
927 tempd="$(mktemp -d)"; cd "$tempd"
928 for testpkg in $(ls $PKGS/$pkg-*.tazpkg 2> /dev/null); do
929 # Extract receipt from each matched package
930 cpio -F "$testpkg" -i receipt >/dev/null 2>&1
931 name=$(. receipt; echo $PACKAGE)
932 rm receipt
933 if [ "$name" == "$pkg" ]; then
934 action 'Removing old package "%s"' "$(basename "$testpkg")"
935 rm -f "$testpkg"
936 status
937 fi
938 done
939 rm -r "$tempd"
940 mv -f $pkgdir/taz/$pkg-*.tazpkg $PKGS
941 sed -i /^${pkg}$/d $broken
942 #action 'Removing source tree...'
943 #rm -f $WOK/$pkg/source; status
944 fi
945 }
948 # Reverse "cat" command: prints input lines in the reverse order
950 tac() {
951 sed '1!G;h;$!d' $1
952 }
955 # Install package on --install or update the chroot.
957 install_package() {
958 case "$ARCH" in
959 arm*|x86_64)
960 arch="-$ARCH"
961 root="$CROSS_TREE/sysroot" ;;
962 esac
963 # Install package if requested but skip install if target host doesn't
964 # match build system or it will break the build chroot.
965 build=$(echo $BUILD_SYSTEM | cut -d- -f1)
966 if [ -n "$inst" ] && [ "$build" == "$ARCH" ]; then
967 if [ -f "$PKGS/$PACKAGE-$VERSION$EXTRAVERSION.tazpkg" ]; then
968 cd $PKGS
969 tazpkg install $PACKAGE-$VERSION$EXTRAVERSION.tazpkg --forced
970 else
971 _ 'Unable to install package, build has failed.'; newline
972 exit 1
973 fi
974 fi
976 # Install package if part of the chroot to keep env up-to-date.
977 if [ -d "$root$INSTALLED/$pkg" ]; then
978 . /etc/slitaz/cook.conf
979 . $WOK/$pkg/taz/$pkg-*/receipt
980 _ 'Updating %s chroot environment...' "$ARCH"
981 _ 'Updating chroot: %s' "$pkg ($VERSION$EXTRAVERSION$arch)" | log
982 cd $PKGS
983 tazpkg install $pkg-$VERSION$EXTRAVERSION$arch.tazpkg --forced --root=$root
984 fi
985 }
988 # remove chroot jail
990 umount_aufs() {
991 tac ${1}rw/aufs-umount.sh | sh
992 rm -rf ${1}rw
993 umount ${1}root
994 rmdir ${1}r*
995 }
998 # Launch the cook command into a chroot jail protected by aufs.
999 # The current filesystems are used read-only and updates are
1000 # stored in a separate branch.
1002 try_aufs_chroot() {
1004 base="/dev/shm/aufsmnt$$"
1006 # Can we setup the chroot? Is it already done?
1007 grep -q ^AUFS_NOT_SUPPORTED $receipt && return
1008 grep -q ^AUFS_NOT_RAMFS $receipt && base="/mnt/aufsmnt$$"
1009 [ -n "$AUFS_MOUNTS" -a ! -f /aufs-umount.sh ] || return
1010 grep -q ^aufs /proc/modules || modprobe aufs 2> /dev/null || return
1011 mkdir ${base}root ${base}rw || return
1013 _ 'Setup aufs chroot...'
1015 # Sanity check
1016 for i in / /proc /sys /dev/shm /home ; do
1017 case " $AUFS_MOUNTS " in
1018 *\ $i\ *) ;;
1019 *) AUFS_MOUNTS="$AUFS_MOUNTS $i" ;;
1020 esac
1021 done
1022 for mnt in $(ls -d $AUFS_MOUNTS | sort | uniq); do
1023 mount --bind $mnt ${base}root$mnt
1024 if [ $mnt == / ] && ! mount -t aufs -o br=${base}rw:/ none ${base}root; then
1025 _ 'Aufs mount failure'
1026 umount ${base}root
1027 rm -rf ${base}r*
1028 return
1029 fi
1030 echo "umount ${base}root$mnt" >> ${base}rw/aufs-umount.sh
1031 done
1032 trap "umount_aufs ${base}" INT
1034 chroot ${base}root $(cd $(dirname $0); pwd)/$(basename $0) "$@"
1035 status=$?
1037 _ 'Leaving aufs chroot...'
1038 umount_aufs $base
1039 # Install package outside the aufs jail
1040 install_package
1041 exit $status
1042 }
1045 # Encode predefined XML entities
1047 xml_ent() {
1048 sed -e 's|&|\&|g; s|<|\<|g; s|>|\>|g; s|"|\"|g' -e "s|'|\'|g"
1049 }
1052 # Create a XML feed for freshly built packages.
1054 gen_rss() {
1055 pubdate=$(date '+%a, %d %b %Y %X')
1056 cat > $FEEDS/$pkg.xml <<EOT
1057 <item>
1058 <title>$PACKAGE $VERSION$EXTRAVERSION</title>
1059 <link>${COOKER_URL}?pkg=$PACKAGE</link>
1060 <guid>$PACKAGE-$VERSION$EXTRAVERSION</guid>
1061 <pubDate>$pubdate</pubDate>
1062 <description>$(echo -n "$SHORT_DESC" | xml_ent)</description>
1063 </item>
1064 EOT
1065 }
1068 # Truncate stdout log file to $1 Mb.
1070 loglimit() {
1071 if [ -n "$DEFAULT_LOG_LIMIT" ]; then
1072 tee /dev/stderr | head -qc ${1:-$DEFAULT_LOG_LIMIT}m
1073 else
1074 tee /dev/stderr
1075 fi
1076 }
1079 #
1080 # Receipt functions to ease packaging
1081 #
1083 get_dev_files() {
1084 action 'Getting standard devel files...'
1085 mkdir -p $fs/usr/lib
1086 cp -a $install/usr/lib/pkgconfig $fs/usr/lib
1087 cp -a $install/usr/lib/*a $fs/usr/lib
1088 cp -a $install/usr/include $fs/usr
1089 status
1090 }
1093 # Function to use in compile_rules() to copy man page from $src to $install
1095 cook_pick_manpages() {
1096 local name section
1097 action 'Copying man pages...'
1099 for i in $@; do
1100 name=$(echo $i | sed 's|\.[gbx]z2*$||')
1101 section=${name##*/}; section=${section##*.}
1102 mkdir -p $install/usr/share/man/man$section
1103 copy $i $install/usr/share/man/man$section
1104 done
1105 status
1106 }
1109 # Function to use in genpkg_rules() to copy specified files from $install to $fs
1111 cook_copy_files() {
1112 action 'Copying files...'
1113 cd $install
1114 local i j
1115 IFS=$'\n'
1116 for i in $@; do
1117 for j in $(find . -name $i ! -type d); do
1118 mkdir -p $fs$(dirname ${j#.})
1119 copy $j $fs$(dirname ${j#.})
1120 done
1121 done
1122 cd - >/dev/null
1123 status
1124 }
1127 # Function to use in genpkg_rules() to copy specified folders from $install to $fs
1129 cook_copy_folders() {
1130 action 'Copying folders...'
1131 cd $install
1132 local i j
1133 IFS=$'\n'
1134 for i in $@; do
1135 for j in $(find . -name $i -type d); do
1136 mkdir -p $fs$(dirname ${j#.})
1137 copy $j $fs$(dirname ${j#.})
1138 done
1139 done
1140 cd - >/dev/null
1141 status
1142 }
1145 # Function to use in genpkg_rules() to copy hicolor icons in specified sizes
1146 # (default: 16 and 48) from $install to $fs
1148 cook_copy_icons() {
1149 local sizes=$@
1150 action 'Copying hicolor icons...'
1151 mkdir -p $fs/usr/share/icons/hicolor
1152 for i in ${sizes:-16 48}; do
1153 [ ! -e "$install/usr/share/icons/hicolor/${i}x$i" ] ||
1154 copy $install/usr/share/icons/hicolor/${i}x$i \
1155 $fs/usr/share/icons/hicolor
1156 done
1157 status
1158 }
1163 #
1164 # Commands
1165 #
1167 case "$1" in
1168 usage|help|-u|-h)
1169 usage ;;
1171 list-wok)
1172 title 'List of %s packages in "%s"' "$ARCH" "$WOK"
1173 cd $WOK
1174 if [ "$ARCH" != 'i486' ]; then
1175 count=0
1176 for pkg in $(fgrep 'HOST_ARCH=' */receipt | egrep "$ARCH|any" | cut -d: -f1)
1177 do
1178 unset HOST_ARCH
1179 . $pkg
1180 count=$(($count + 1))
1181 colorize 34 "$PACKAGE"
1182 done
1183 else
1184 count=$(ls | wc -l)
1185 ls -1
1186 fi
1187 footer "$(_p '%s package' '%s packages' "$count" "$(colorize 32 "$count")")"
1188 ;;
1190 activity)
1191 cat $activity ;;
1193 search)
1194 # Just a simple search function, we dont need more actually.
1195 query="$2"
1196 title 'Search results for "%s"' "$query"
1197 cd $WOK; ls -1 | grep "$query"
1198 footer ;;
1200 setup)
1201 # Setup a build environment
1202 check_root
1203 _ 'Cook: setup environment' | log
1204 title 'Setting up your environment'
1205 [ -d $SLITAZ ] || mkdir -p $SLITAZ
1206 cd $SLITAZ
1207 init_db_files
1208 _ 'Checking for packages to install...'
1209 # Use setup pkgs from cross.conf or cook.conf. When cross compiling
1210 # ARCH-setup or 'cross check' should be used before: cook setup
1211 case "$ARCH" in
1212 arm*|x86_64)
1213 if [ ! -x '/usr/bin/cross' ]; then
1214 _ 'ERROR: %s is not installed' 'cross'
1215 exit 1
1216 fi
1217 _ 'Using config file: %s' '/etc/slitaz/cross.conf'
1218 . /etc/slitaz/cross.conf ;;
1219 esac
1220 for pkg in $SETUP_PKGS; do
1221 if [ -n "$forced" ]; then
1222 tazpkg -gi $pkg --forced
1223 else
1224 [ ! -d "$INSTALLED/$pkg" ] && tazpkg get-install $pkg
1225 fi
1226 done
1228 # Handle --options
1229 case "$2" in
1230 --wok) hg clone $WOK_URL wok || exit 1 ;;
1231 --stable) hg clone $WOK_URL-stable wok || exit 1 ;;
1232 --undigest) hg clone $WOK_URL-undigest wok || exit 1 ;;
1233 --tiny) hg clone $WOK_URL-tiny wok || exit 1 ;;
1234 esac
1236 # SliTaz group and permissions
1237 if ! grep -q ^slitaz /etc/group; then
1238 _ 'Adding group "%s"' 'slitaz'
1239 addgroup slitaz
1240 fi
1241 _ 'Setting permissions for group "%s"...' 'slitaz'
1242 find $SLITAZ -maxdepth 2 -exec chown root.slitaz {} \;
1243 find $SLITAZ -maxdepth 2 -exec chmod g+w {} \;
1244 footer "$(_ 'All done, ready to cook packages :-)')" ;;
1246 *-setup)
1247 # Setup for cross compiling.
1248 arch="${1%-setup}"
1249 check_root
1250 . /etc/slitaz/cook.conf
1251 for pkg in $CROSS_SETUP; do
1252 if [ -n "$forced" ]; then
1253 tazpkg -gi $pkg --forced
1254 else
1255 [ ! -d "$INSTALLED/$pkg" ] && tazpkg -gi $pkg
1256 fi
1257 done
1259 _ 'Cook: setup %s cross environment' "$arch" | log
1260 title 'Setting up your %s cross environment' "$arch"
1261 init_db_files
1262 sed -i \
1263 -e s"/ARCH=.*/ARCH=\"$arch\"/" \
1264 -e s"/CROSS_TREE=.*/CROSS_TREE=\"\/cross\/$arch\"/" \
1265 -e s'/BUILD_SYSTEM=.*/BUILD_SYSTEM=i486-slitaz-linux/' \
1266 /etc/slitaz/cook.conf
1267 case "$arch" in
1268 arm)
1269 flags='-O2 -march=armv6'
1270 host="$ARCH-slitaz-linux-gnueabi" ;;
1271 armv6hf)
1272 flags='-O2 -march=armv6j -mfpu=vfp -mfloat-abi=hard'
1273 host="$ARCH-slitaz-linux-gnueabi" ;;
1274 armv7)
1275 flags='-Os -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -pipe'
1276 host="$ARCH-slitaz-linux-gnueabi" ;;
1277 x86_64)
1278 flags='-O2 -mtune=generic -pipe'
1279 host="$ARCH-slitaz-linux" ;;
1280 esac
1281 sed -i \
1282 -e s"/CFLAGS=.*/CFLAGS=\"$flags\"/" \
1283 -e s"/HOST_SYSTEM=.*/HOST_SYSTEM=$host/" /etc/slitaz/cook.conf
1284 . /etc/slitaz/cook.conf
1285 sysroot="$CROSS_TREE/sysroot"
1286 tools="/cross/$arch/tools"
1287 root="$sysroot"
1288 # L10n: keep the same width of translations to get a consistent view
1289 _ 'Target arch : %s' "$ARCH"
1290 _ 'Configure args : %s' "$CONFIGURE_ARGS"
1291 _ 'Build flags : %s' "$flags"
1292 _ 'Arch sysroot : %s' "$sysroot"
1293 _ 'Tools prefix : %s' "$tools/bin"
1294 # Tell the packages manager where to find packages.
1295 _ 'Packages DB : %s' "$root$DB"
1296 mkdir -p $root$INSTALLED
1297 cd $root$DB; rm -f *.bak
1298 for list in packages.list packages.desc packages.equiv packages.md5; do
1299 rm -f $list
1300 ln -s $SLITAZ/packages/$list $list
1301 done
1302 # We must have the cross compiled glibc-base installed or default
1303 # i486 package will be used as dep by tazpkg and then break the
1304 # cross environment
1305 if [ ! -f "$root$INSTALLED/glibc-base/receipt" ]; then
1306 colorize 36 $(_ 'WARNING: %s is not installed in sysroot' '(e)glibc-base')
1307 fi
1308 # Show GCC version or warn if not yet compiled.
1309 if [ -x "$tools/bin/$HOST_SYSTEM-gcc" ]; then
1310 _ 'Cross compiler : %s' "$HOST_SYSTEM-gcc"
1311 else
1312 colorize 36 $(_ 'C compiler "%s" is missing' "$HOST_SYSTEM-gcc")
1313 _ 'Run "%s" to cook a toolchain' 'cross compile'
1314 fi
1315 footer ;;
1317 test)
1318 # Test a cook environment.
1319 _ 'Cook test: testing the cook environment' | log
1320 [ ! -d "$WOK" ] && exit 1
1321 [ ! -d "$WOK/cooktest" ] && cp -r $DATA/cooktest $WOK
1322 cook cooktest ;;
1324 new)
1325 # Create the package folder and an empty receipt.
1326 pkg="$2"
1327 [ -z "$pkg" ] && usage
1328 newline
1329 if [ -d "$WOK/$pkg" ]; then
1330 _ 'Package "%s" already exists.' "$pkg"
1331 exit 1
1332 fi
1334 action 'Creating folder "%s"' "$WOK/$pkg"
1335 mkdir $WOK/$pkg; cd $WOK/$pkg; status
1337 action 'Preparing the package receipt...'
1338 cp $DATA/receipt .
1339 sed -i s"/^PACKAGE=.*/PACKAGE=\"$pkg\"/" receipt
1340 status; newline
1342 # Interactive mode, asking and seding.
1343 case "$3" in
1344 --interactive|-x)
1345 _ 'Entering interactive mode...'
1346 separator
1347 _ 'Package : %s' "$pkg"
1349 _n 'Version : ' ; read answer
1350 sed -i s/'VERSION=\"\"'/"VERSION=\"$answer\""/ receipt
1352 _n 'Category : ' ; read answer
1353 sed -i s/'CATEGORY=\"\"'/"CATEGORY=\"$answer\""/ receipt
1355 # L10n: Short description
1356 _n 'Short desc : ' ; read answer
1357 sed -i s/'SHORT_DESC=\"\"'/"SHORT_DESC=\"$answer\""/ receipt
1359 _n 'Maintainer : ' ; read answer
1360 sed -i s/'MAINTAINER=\"\"'/"MAINTAINER=\"$answer\""/ receipt
1362 _n 'License : ' ; read answer
1363 sed -i s/'LICENSE=\"\"'/"LICENSE=\"$answer\""/ receipt
1365 _n 'Web site : ' ; read answer
1366 sed -i s#'WEB_SITE=\"\"'#"WEB_SITE=\"$answer\""# receipt
1367 newline
1369 # Wget URL.
1370 _ 'Wget URL to download source tarball.'
1371 _n 'Example : ' ; echo '$GNU_MIRROR/$PACKAGE/$TARBALL'
1372 _n 'Wget url : ' ; read answer
1373 sed -i "s|WGET_URL=.*|WGET_URL=\"$answer\"|" receipt
1375 # Ask for a stuff dir.
1376 confirm "$(_n 'Do you need a stuff directory? (y/N)')"
1377 if [ "$?" -eq 0 ]; then
1378 action 'Creating the stuff directory...'
1379 mkdir $WOK/$pkg/stuff; status
1380 fi
1382 # Ask for a description file.
1383 confirm "$(_n 'Are you going to write a description? (y/N)')"
1384 if [ "$?" -eq 0 ]; then
1385 action 'Creating the "%s" file...' 'description.txt'
1386 touch $WOK/$pkg/description.txt; status
1387 fi
1389 footer "$(_ 'Receipt is ready to use.')" ;;
1390 esac ;;
1392 list)
1393 # Cook a list of packages (better use the Cooker since it will order
1394 # packages before executing cook).
1395 check_root
1396 if [ -z "$2" ]; then
1397 newline; _ 'No list in argument.'; newline
1398 exit 1
1399 fi
1400 if [ ! -f "$2" ]; then
1401 newline; _ 'List "%s" not found.' "$2"; newline
1402 exit 1
1403 fi
1405 _ 'Starting cooking the list "%s"' "$2" | log
1407 for pkg in $(cat $2); do
1408 cook $pkg || broken
1409 done ;;
1411 clean-wok)
1412 check_root
1413 newline; action 'Cleaning all packages files...'
1414 rm -rf $WOK/*/taz $WOK/*/install $WOK/*/source
1415 status; newline ;;
1417 clean-src)
1418 check_root
1419 newline; action 'Cleaning all packages sources...'
1420 rm -rf $WOK/*/source
1421 status; newline ;;
1423 uncook)
1424 cd $WOK
1425 count=0
1426 title 'Checking for uncooked packages'
1428 for pkg in *; do
1429 unset HOST_ARCH EXTRAVERSION
1430 [ ! -e $pkg/receipt ] && continue
1431 . $pkg/receipt
1432 # Source cooked pkg receipt to get EXTRAVERSION
1433 if [ -d "$WOK/$pkg/taz" ]; then
1434 cd $WOK/$pkg/taz/$pkg-*
1435 . receipt; cd $WOK
1436 fi
1437 case "$ARCH" in
1438 i486)
1439 debug "$(_ 'Package "%s"' "$PKGS/$PACKAGE-$VERSION$EXTRAVERSION.tazpkg")"
1440 if [ ! -f "$PKGS/$PACKAGE-$VERSION$EXTRAVERSION.tazpkg" ]; then
1441 count=$(($count + 1))
1442 colorize 34 "$pkg"
1443 fi ;;
1444 arm*)
1445 # Check only packages included in arch
1446 if echo "$HOST_ARCH" | egrep -q "$ARCH|any"; then
1447 # *.tazpkg
1448 if [ ! -f "$PKGS/$PACKAGE-$VERSION$EXTRAVERSION-$ARCH.tazpkg" ]; then
1449 count=$(($count + 1))
1450 colorize 34 "$pkg"
1451 fi
1452 fi ;;
1453 esac
1454 done
1456 if [ "$count" -gt "0" ]; then
1457 footer "$(_p '%s uncooked package' '%s uncooked packages' "$count" "$(colorize 31 "$count")")"
1458 else
1459 _ 'All packages are cooked :-)'
1460 newline
1461 fi
1462 ;;
1464 pkgdb)
1465 # Create suitable packages list for TazPkg and only for built packages
1466 # as well as flavors files for TazLiTo. We don't need logs since we do it
1467 # manually to ensure everything is fine before syncing the mirror.
1468 @@PREFIX@@/libexec/cookutils/pkgdb "$2"
1469 ;;
1471 *)
1472 # Just cook and generate a package.
1473 check_root
1474 time=$(date +%s)
1475 pkg="$1"
1476 [ -z "$pkg" ] && usage
1477 lastcooktime=$(sed '/^Cook time/!d;s|.*: *\([0-9]*\)s.*|\1|' \
1478 $LOGS/$pkg.log 2> /dev/null | sed '$!d')
1479 receipt="$WOK/$pkg/receipt"
1480 check_pkg_in_wok
1481 newline
1483 unset inst
1484 unset_receipt
1485 . $receipt
1487 # Handle cross compilation.
1488 case "$ARCH" in
1489 arm*)
1490 if [ -z "$HOST_ARCH" ]; then
1491 _ 'cook: HOST_ARCH is not set in "%s" receipt' "$pkg"
1492 error="$(_ 'package "%s" is not included in %s' "$pkg" "$ARCH")"
1493 _ 'cook: %s' "$error"
1494 [ -n "$CROSS_BUGS" ] && _ 'bugs: %s' "$CROSS_BUGS"
1495 _ 'Cook skip: %s' "$error" | log
1496 newline
1497 exit 1
1498 fi ;;
1499 esac
1501 # Some packages are not included in some arch or fail to cross compile.
1502 : ${HOST_ARCH=i486}
1503 debug "$(_ 'Host arch %s' "$HOST_ARCH")"
1504 # Handle arm{v6hf,v7,..}
1505 if ! $(echo "$HOST_ARCH" | egrep -q "${ARCH%v[0-9]*}|any"); then
1506 _ 'cook: %s' "HOST_ARCH=$HOST_ARCH"
1507 error="$(_ "package \"%s\" doesn't cook or is not included in %s" "$pkg" "$ARCH")"
1508 _ 'cook: %s' "error"
1509 [ -n "$CROSS_BUGS" ] && _ 'bugs: %s' "$CROSS_BUGS"
1510 _ 'Cook skip: %s' "$error" | log
1511 sed -i /^${pkg}$/d $broken
1512 newline
1513 exit 0
1514 fi
1516 # Skip blocked, 3 lines also for the Cooker.
1517 if grep -q "^$pkg$" $blocked && [ "$2" != '--unblock' ]; then
1518 _ 'Package "%s" is blocked' "$pkg"; newline
1519 exit 0
1520 fi
1522 try_aufs_chroot "$@"
1524 # Log and source receipt.
1525 _ 'Cook started for: %s' "<a href='cooker.cgi?pkg=$pkg'>$pkg</a>" | log
1526 echo "cook:$pkg" > $command
1527 [ "$lastcooktime" ] &&
1528 echo "cook:$pkg $lastcooktime $(date +%s)" >> $cooktime
1529 while read cmd duration start; do
1530 [ $(($start + $duration)) -lt $(date +%s) ] &&
1531 echo "sed -i '/^$cmd $duration/d' $cooktime"
1532 done < $cooktime | sh
1534 # Display and log info if cook process stopped.
1535 # FIXME: gettext not working (in single quotes) here!
1536 trap '_ "\n\nCook stopped: control-C\n\n" | \
1537 tee -a $LOGS/$pkg.log' INT
1539 # Handle --options
1540 case "$2" in
1541 --clean|-c)
1542 action 'Cleaning "%s"' "$pkg"
1543 cd $WOK/$pkg; rm -rf install taz source
1544 status; newline
1545 exit 0 ;;
1547 --install|-i)
1548 inst='yes' ;;
1550 --getsrc|-gs)
1551 title 'Getting source for "%s"' "$pkg"
1552 get_source
1553 _ 'Tarball: %s' "$SRC/$TARBALL"; newline
1554 exit 0 ;;
1556 --block|-b)
1557 action 'Blocking package "%s"' "$pkg"
1558 [ $(grep "^$pkg$" $blocked) ] || echo "$pkg" >> $blocked
1559 status; newline
1560 exit 0 ;;
1562 --unblock|-ub)
1563 action 'Unblocking package "%s"' "$pkg"
1564 sed -i "/^${pkg}$/"d $blocked
1565 status; newline
1566 exit 0 ;;
1568 --pack)
1569 if [ -d $WOK/$pkg/taz ]; then
1570 rm -rf $WOK/$pkg/taz
1571 [ -f $LOGS/$pkg-pack.log ] && rm -rf $LOGS/$pkg-pack.log
1572 packit 2>&1 | tee -a $LOGS/$pkg-pack.log
1573 clean_log
1574 else
1575 _ 'Need to build "%s"' "$pkg"
1576 exit 0
1577 fi
1578 exit 0 ;;
1580 --cdeps)
1581 @@PREFIX@@/libexec/cookutils/cdeps $pkg
1582 esac
1584 # Rotate log
1585 for i in $(seq 9 -1 1); do
1586 j=$(($i - 1))
1587 [ -e $LOGS/$pkg.log.$j ] && mv -f $LOGS/$pkg.log.$j $LOGS/$pkg.log.$i
1588 done
1589 [ -e $LOGS/$pkg.log ] && mv $LOGS/$pkg.log $LOGS/$pkg.log.0
1591 # Check if wanted is built now so we have separate log files.
1592 for wanted in $WANTED ; do
1593 if grep -q "^$wanted$" $blocked; then
1594 _ 'WANTED package "%s" is blocked' "$wanted" | tee $LOGS/$pkg.log
1595 newline
1596 rm -f $command
1597 exit 1
1598 fi
1599 if grep -q "^$wanted$" $broken; then
1600 _ 'WANTED package "%s" is broken' "$wanted" | tee $LOGS/$pkg.log
1601 newline
1602 rm -f $command
1603 exit 1
1604 fi
1605 if [ ! -d "$WOK/$wanted/install" ]; then
1606 cook "$wanted" || exit 1
1607 fi
1608 done
1610 # Cook and pack or exit on error and log everything.
1611 cookit $@ 2>&1 | loglimit 50 > $LOGS/$pkg.log
1612 remove_deps | tee -a $LOGS/$pkg.log
1613 cookit_quality
1614 packit 2>&1 | loglimit 5 >> $LOGS/$pkg.log
1615 clean_log
1617 # Exit if any error in packing.
1618 lerror=$(_n 'ERROR')
1619 if grep -Ev "(/root/.cvspass|conftest|df: /|rm: can't remove)" $LOGS/$pkg.log | \
1620 grep -Eq "(^$lerror|: No such file or directory|not remade because of errors|ake: \*\*\* .* Error)"; then
1621 debug_info | tee -a $LOGS/$pkg.log
1622 rm -f $command
1623 exit 1
1624 fi
1626 # Create an XML feed
1627 gen_rss
1629 # Time and summary
1630 time=$(($(date +%s) - $time))
1631 summary | tee -a $LOGS/$pkg.log
1632 newline
1634 # We may want to install/update (outside aufs jail !).
1635 [ -s /aufs-umount.sh ] ||
1636 install_package
1638 # Finally we DON'T WANT to build the *-dev or packages with WANTED="$pkg"
1639 # You want automation: use the Cooker Build Bot.
1640 rm -f $command ;;
1641 esac
1643 exit 0