cookutils rev 1
Added: cook
author | Christophe Lincoln <pankso@slitaz.org> |
---|---|
date | Tue May 03 22:30:38 2011 +0200 (2011-05-03) |
parents | 2c9e9e81dd35 |
children | c8f38891a28d |
files | cook |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/cook Tue May 03 22:30:38 2011 +0200 1.3 @@ -0,0 +1,498 @@ 1.4 +#!/bin/sh 1.5 +# 1.6 +# Cook - A tool to cook and generate SliTaz packages. Read the README 1.7 +# before adding or modifing any code in cook! 1.8 +# 1.9 +# Copyright (C) SliTaz GNU/Linux - GNU gpl v3 1.10 +# Author: Christophe Lincoln <pankso@slitaz.org> 1.11 +# 1.12 + 1.13 +[ -f "/etc/slitaz/cook.conf" ] && . /etc/slitaz/cook.conf 1.14 +[ -f "cook.conf" ] && . ./cook.conf 1.15 + 1.16 +# 1.17 +# Functions 1.18 +# 1.19 + 1.20 +usage() { 1.21 + cat << EOT 1.22 + 1.23 +$(echo -e "\033[1m$(gettext "Usage:")\033[0m") cook [package|command|list] [--option] 1.24 + 1.25 +$(echo -e "\033[1m$(gettext "Commands:")\033[0m") 1.26 + usage|help $(gettext "Display this short usage.") 1.27 + list-wok $(gettext "List packages in the wok.") 1.28 + setup $(gettext "Setup your build environment.") 1.29 + new $(gettext "Create a new package with receipt".) 1.30 + list $(gettext "Cook a list of packages.") 1.31 + clean-wok $(gettext "Clean-up all packages files.") 1.32 + clean-src $(gettext "Clean-up all packages source.") 1.33 + pkglist $(gettext "Create all packages.* lists.") 1.34 + 1.35 +$(echo -e "\033[1m$(gettext "Options:")\033[0m") 1.36 + --clean|-c $(gettext "Clean the package in the wok.") 1.37 + --install|-i $(gettext "Cook and install the package.") 1.38 + --wok|-w $(gettext "Setup also a wok from Hg repo.") 1.39 + 1.40 +EOT 1.41 + exit 0 1.42 +} 1.43 + 1.44 +# Be sure we root. 1.45 +check_root() { 1.46 + [ $(id -u) != 0 ] && gettext -e "\nYou must be root to cook.\n\n" && exit 0 1.47 +} 1.48 + 1.49 +separator() { 1.50 + echo "================================================================================" 1.51 +} 1.52 + 1.53 +status() { 1.54 + echo -en "\\033[70G[ " 1.55 + if [ $? = 0 ]; then 1.56 + echo -en "\\033[1;32mOK" 1.57 + else 1.58 + echo -en "\\033[1;31mFailed" 1.59 + fi 1.60 + echo -e "\\033[0;39m ]" 1.61 +} 1.62 + 1.63 +clean_log() { 1.64 + sed -i -e s'|\[70G\[ \[1;32m| |' \ 1.65 + -e s'|\[0;39m \]||' $LOGS/$pkg.log 1.66 +} 1.67 + 1.68 +unset_receipt() { 1.69 + unset DEPENDS BUILD_DEPENDS WANTED EXTRAVERSION WGET_URL PROVIDE 1.70 +} 1.71 + 1.72 +# Be sure package exist in wok. 1.73 +check_pkg_in_wok() { 1.74 + if [ ! -d "$WOK/$pkg" ]; then 1.75 + gettext -e "\nUnable to find package in the wok:" 1.76 + echo -e " $pkg\n" && exit 1 1.77 + fi 1.78 +} 1.79 + 1.80 +# Path's used in receipt and by cook itself. 1.81 +set_paths() { 1.82 + pkgdir=$WOK/$PACKAGE 1.83 + src=$pkgdir/source/$PACKAGE-$VERSION 1.84 + pack=$pkgdir/taz/$PACKAGE-${VERSION}${EXTRAVERSION} 1.85 + fs=$pack/fs 1.86 + stuff=$pkgdir/stuff 1.87 + install=$pkgdir/install 1.88 + if [ "$WANTED" ]; then 1.89 + src=$WOK/$WANTED/source/$WANTED-$VERSION 1.90 + install=$WOK/$WANTED/install 1.91 + fi 1.92 + # Old way compatibility 1.93 + _pkg=$install 1.94 +} 1.95 + 1.96 +# Get package source 1.97 +get_source() { 1.98 + wget -P $SRC $WGET_URL 1.99 +} 1.100 + 1.101 +# Extract source package 1.102 +extract_source() { 1.103 + gettext "Extracting:"; echo " $TARBALL" 1.104 + case "$TARBALL" in 1.105 + *.tar.gz|*.tgz) tar xzf $SRC/$TARBALL ;; 1.106 + *.tar.bz2) tar xjf $SRC/$TARBALL ;; 1.107 + *.tar.lzma) tar xaf $SRC/$TARBALL ;; 1.108 + *.zip) unzip $SRC/$TARBALL ;; 1.109 + esac 1.110 +} 1.111 + 1.112 +# Display cooked package summary 1.113 +summary() { 1.114 + cd $WOK/$pkg 1.115 + [ -d install ] && prod=$(du -sh install | awk '{print $1}' 2>/dev/null) 1.116 + fs=$(du -sh taz/* | awk '{print $1}') 1.117 + size=$(du -sh $PKGS/$PACKAGE-${VERSION}${EXTRAVERSION}.* | awk '{print $1}') 1.118 + files=$(cat taz/$PACKAGE-*/files.list | wc -l) 1.119 + gettext "Summary for:"; echo " $PACKAGE $VERSION" 1.120 + separator 1.121 + [ "$prod" ] && echo "Produce : $prod" 1.122 + cat << EOT 1.123 +Packed : $fs 1.124 +Compressed : $size 1.125 +Files : $files 1.126 +Cook time : ${time}s 1.127 +$(separator) 1.128 + 1.129 +EOT 1.130 +} 1.131 + 1.132 +# Copy all generic files (locale, pixmaps, .desktop). We use standard paths, 1.133 +# so some packages need to copy these files with the receipt and genpkg_rules. 1.134 +copy_generic_files() 1.135 +{ 1.136 + # $LOCALE is set in cook.conf 1.137 + if [ "$LOCALE" ]; then 1.138 + if [ -d "$_pkg/usr/share/locale" ]; then 1.139 + mkdir -p $fs/usr/share/locale 1.140 + for i in $LOCALE 1.141 + do 1.142 + if [ -d "$_pkg/usr/share/locale/$i" ]; then 1.143 + cp -a $_pkg/usr/share/locale/$i $fs/usr/share/locale 1.144 + fi 1.145 + done 1.146 + fi 1.147 + fi 1.148 + 1.149 + # Generic pixmaps copy can be disabled with GENERIC_PIXMAPS="no" 1.150 + if [ "$GENERIC_PIXMAPS" != "no" ]; then 1.151 + if [ -d "$_pkg/usr/share/pixmaps" ]; then 1.152 + mkdir -p $fs/usr/share/pixmaps 1.153 + cp -a $_pkg/usr/share/pixmaps/$PACKAGE.png \ 1.154 + $fs/usr/share/pixmaps 2>/dev/null 1.155 + cp -a $_pkg/usr/share/pixmaps/$PACKAGE.xpm \ 1.156 + $fs/usr/share/pixmaps 2>/dev/null 1.157 + fi 1.158 + 1.159 + # Custom or homemade PNG pixmap can be in stuff. 1.160 + if [ -f "$stuff/$PACKAGE.png" ]; then 1.161 + mkdir -p $fs/usr/share/pixmaps 1.162 + cp -a $stuff/$PACKAGE.png $fs/usr/share/pixmaps 1.163 + fi 1.164 + fi 1.165 + 1.166 + # Desktop entry (.desktop). 1.167 + if [ -d "$_pkg/usr/share/applications" ]; then 1.168 + cp -a $_pkg/usr/share/applications $fs/usr/share 1.169 + fi 1.170 + 1.171 + # Homemade desktop file(s) can be in stuff. 1.172 + if [ -d "$stuff/applications" ]; then 1.173 + mkdir -p $fs/usr/share 1.174 + cp -a $stuff/applications $fs/usr/share 1.175 + fi 1.176 + if [ -f "$stuff/$PACKAGE.desktop" ]; then 1.177 + mkdir -p $fs/usr/share/applications 1.178 + cp -a $stuff/$PACKAGE.desktop $fs/usr/share/applications 1.179 + fi 1.180 +} 1.181 + 1.182 +# Find and strip : --strip-all (-s) or --strip-debug on static libs. 1.183 +strip_package() 1.184 +{ 1.185 + gettext "Executing strip on all files" 1.186 + for dir in $fs/bin $fs/sbin $fs/usr/bin $fs/usr/sbin $fs/usr/games 1.187 + do 1.188 + if [ -d "$dir" ]; then 1.189 + find $dir -type f -exec strip -s '{}' 2>/dev/null \; 1.190 + fi 1.191 + done 1.192 + find $fs -name "*.so*" -exec strip -s '{}' 2>/dev/null \; 1.193 + find $fs -name "*.a" -exec strip --strip-debug '{}' 2>/dev/null \; 1.194 + status 1.195 +} 1.196 + 1.197 +# Verify package quality and consitensy. 1.198 +packit_quality() { 1.199 + if grep -q ^ERROR $LOGS/$pkg.log; then 1.200 + exit 1 1.201 + fi 1.202 + if ! grep -q ^/ $WOK/$pkg/taz/$pkg-*/files.list; then 1.203 + echo -e "ERROR: empty package\n" | tee -a $LOGS/$pkg.log && exit 1 1.204 + else 1.205 + mv -f $WOK/$pkg/taz/$pkg-*.tazpkg $PKGS 1.206 + fi 1.207 +} 1.208 + 1.209 +# The main cook function. 1.210 +cookit() { 1.211 + set_paths 1.212 + unset error 1.213 + echo "Cooking: $PACKAGE $VERSION" 1.214 + separator 1.215 + rm -rf install taz source $CACHE/error 1.216 + 1.217 + # Disable -pipe if less than 512Mb free RAM. 1.218 + free=$(free | fgrep '/+ buffers' | tr -s ' ' | cut -f 4 -d ' ') 1.219 + if [ "$free" -lt 524288 ] && [ "$CFLAGS" != "${CFLAGS/-pipe}" ]; then 1.220 + gettext -e "Disabling -pipe compile flag: $free RAM\n" 1.221 + CFLAGS="${CFLAGS/-pipe}" && CFLAGS=$(echo "$CFLAGS" | tr -s ' ') 1.222 + CXXFLAGS="${CXXFLAGS/-pipe}" && CXXFLAGS=$(echo "$CXXFLAGS" | tr -s ' ') 1.223 + fi 1.224 + unset free 1.225 + 1.226 + # Export flags and path to be used by make 1.227 + DESTDIR=$WOK/$PACKAGE/install 1.228 + export DESTDIR MAKEFLAGS CFLAGS CXXFLAGS BUILD_HOST CONFIG_SITE 1.229 + local LC_ALL=POSIX LANG=POSIX 1.230 + 1.231 + # Check for build dep. 1.232 + cd $INSTALLED && ls -1 > $CACHE/installed.list 1.233 + [ "$DEPENDS" ] && gettext -e "Checking build dependencies...\n" 1.234 + for dep in $BUILD_DEPENDS 1.235 + do 1.236 + if [ ! -d "$INSTALLED/$dep" ]; then 1.237 + # Try local package first 1.238 + if [ -f "$PKGS/$dep-*.tazpkg" ]; then 1.239 + gettext "Installing dep (local):"; echo " $dep" 1.240 + cd $PKGS && tazpkg install $dep-*.tazpkg >/dev/null 1.241 + else 1.242 + gettext "Installing dep (web/cache):"; echo " $dep" 1.243 + tazpkg get-install $dep >/dev/null 1.244 + fi 1.245 + fi 1.246 + done 1.247 + ls -1 > $CACHE/installed.cook && cd $CACHE 1.248 + diff installed.list installed.cook | \ 1.249 + grep ^+[a-zA-Z0-9] | sed s/^+// > installed.deps 1.250 + deps=$(cat installed.deps | wc -l) 1.251 + 1.252 + # Get source tarball and make sure we have source dir named: 1.253 + # $PACKAGE-$VERSION to be standard in receipts. Her we use tar.lzma 1.254 + # tarball if it exist. 1.255 + if [ "$WGET_URL" ] && [ ! -f "$SRC/$TARBALL" ]; then 1.256 + if [ -f "$SRC/${SOURCE:-$PACKAGE}-$VERSION.tar.lzma" ]; then 1.257 + TARBALL=$SRC/${SOURCE:-$PACKAGE}-$VERSION.tar.lzma 1.258 + else 1.259 + get_source || exit 1 1.260 + fi 1.261 + fi 1.262 + if [ ! "$WANTED" ] && [ ! -d "$src" ]; then 1.263 + mkdir -p $pkgdir/source/tmp && cd $pkgdir/source/tmp 1.264 + extract_source || exit 1 1.265 + mv * ../$PACKAGE-$VERSION 1.266 + cd .. && rm -rf tmp 1.267 + fi 1.268 + 1.269 + # Execute receipt rules and stay compatible with _pkg. 1.270 + if grep -q ^compile_rules $pkgdir/receipt; then 1.271 + gettext -e "Executing: compile_rules\n" 1.272 + cd $src && compile_rules || exit 1 1.273 + [ -d $src/_pkg ] && mv $src/_pkg $install 1.274 + fi 1.275 + if grep -q ^genpkg_rules $pkgdir/receipt; then 1.276 + gettext -e "Executing: genpkg_rules\n" 1.277 + mkdir -p $fs && genpkg_rules || ( echo -e \ 1.278 + "\nERROR: genpkg_rules failed\n" | \ 1.279 + tee -a $LOGS/$pkg.log && exit 1 ) 1.280 + fi 1.281 + 1.282 + # Now remove installed build deps. 1.283 + if [ "$deps" -gt 0 ]; then 1.284 + gettext "Removing build dependencies:"; echo " $deps" 1.285 + for dep in $(cat $CACHE/installed.deps) 1.286 + do 1.287 + yes | tazpkg remove $dep >/dev/null 1.288 + done 1.289 + fi 1.290 + separator && echo "" 1.291 +} 1.292 + 1.293 +# Cook quality assurance. 1.294 +cookit_quality() { 1.295 + if grep -q ^ERROR $LOGS/$pkg.log; then 1.296 + exit 1 1.297 + fi 1.298 + if [ ! -d "$WOK/$pkg/install" ] && [ ! "$WANTED" ]; then 1.299 + echo -e "ERROR: cook failed\n" | \ 1.300 + tee -a $LOGS/$pkg.log && exit 1 1.301 + fi 1.302 +} 1.303 + 1.304 +# Create the package. 1.305 +packit() { 1.306 + set_paths 1.307 + echo "Packing: $PACKAGE ${VERSION}${EXTRAVERSION}" 1.308 + separator 1.309 + cd $pkgdir/taz 1.310 + strip_package 1.311 + for file in receipt description.txt 1.312 + do 1.313 + [ ! -f "../$file" ] && continue 1.314 + gettext "Copying"; echo -n " $file..." 1.315 + cp -f ../$file $pack && chown 0.0 $pack/$file && status 1.316 + done 1.317 + copy_generic_files 1.318 + # Use Tazpkg to create a tazpkg package... 1.319 + tazpkg pack $PACKAGE-${VERSION}${EXTRAVERSION} | grep "\[*\]" 1.320 + separator && echo "" 1.321 +} 1.322 + 1.323 +# 1.324 +# Commands 1.325 +# 1.326 + 1.327 +case "$1" in 1.328 + usage|help) 1.329 + usage ;; 1.330 + list-wok) 1.331 + gettext "List of packages in:"; echo " $WOK" 1.332 + separator 1.333 + cd $WOK && ls -1 1.334 + separator 1.335 + echo -n "Packages: " && ls | wc -l 1.336 + echo "" ;; 1.337 + setup) 1.338 + # Setup a build environment 1.339 + check_root 1.340 + gettext -e "\nSetting up your environment\n" 1.341 + separator && cd $SLITAZ 1.342 + gettext "Creating directories structure in:"; echo " $SLITAZ" 1.343 + mkdir -p $WOK $PKGS $SRC $CACHE $LOGS 1.344 + gettext -e "Checking for packages to install...\n" 1.345 + for pkg in slitaz-toolchain tazdev intltool gettext 1.346 + do 1.347 + [ ! -d "$INSTALLED/$pkg" ] && tazpkg get-install $pkg 1.348 + done 1.349 + 1.350 + # Handle --options 1.351 + case "$2" in 1.352 + --wok) 1.353 + [ ! -d "$INSTALLED/mercurial" ] && tazpkg get-install mercurial 1.354 + [ -d "$WOK" ] && echo -e "A wok already exist.\n" && exit 1 1.355 + hg clone $HG_URL ;; 1.356 + --chroot) 1.357 + echo "TODO: create a chroot with tazdev" ;; 1.358 + esac 1.359 + 1.360 + # SliTaz group and permissions 1.361 + if ! grep -q ^slitaz /etc/group; then 1.362 + gettext -e "Adding group: slitaz\n" 1.363 + addgroup slitaz 1.364 + fi 1.365 + gettext -e "Setting permissions for slitaz group...\n" 1.366 + chown -R root.slitaz $SLITAZ 1.367 + chmod -R g+w $SLITAZ 1.368 + separator 1.369 + gettext -e "All done, ready to cook packages :-)\n\n" ;; 1.370 + new) 1.371 + # Create the package folder and an empty receipt. 1.372 + pkg="$2" 1.373 + [ "$pkg" ] || usage 1.374 + echo "" 1.375 + if [ -d "$WOK/$pkg" ]; then 1.376 + echo -n "$pkg " && gettext "package already exist." 1.377 + echo -e "\n" && exit 1 1.378 + fi 1.379 + gettext "Creating"; echo -n " $WOK/$pkg" 1.380 + mkdir $WOK/$pkg && cd $WOK/$pkg && status 1.381 + gettext "Preparing the package receipt..." 1.382 + cp $DATA/receipt . 1.383 + sed -i s"/^PACKAGE=.*/PACKAGE=\"$pkg\"/" receipt 1.384 + status && echo "" ;; 1.385 + list) 1.386 + # Cook a list of packages (better use the Cooker since it will order 1.387 + # packages before executing cook). 1.388 + check_root 1.389 + [ -z "$2" ] && gettext -e "\nNo list in argument.\n\n" && exit 1 1.390 + [ ! -f "$2" ] && gettext -e "\nNo list found:" && \ 1.391 + echo -e " $2\n" && exit 1 1.392 + for pkg in $(cat $2) 1.393 + do 1.394 + cook $pkg || broken 1.395 + done ;; 1.396 + clean-wok) 1.397 + check_root 1.398 + gettext -e "\nCleaning all packages files..." 1.399 + rm -rf $WOK/*/taz $WOK/*/install $WOK/*/source 1.400 + status && echo "" ;; 1.401 + clean-src) 1.402 + check_root 1.403 + gettext -e "\nCleaning all packages source..." 1.404 + rm -rf $WOK/*/source 1.405 + status && echo "" ;; 1.406 + pkglist) 1.407 + # Create suitable packages list for TazPKG and only for builded packages. 1.408 + [ "$2" ] && PKGS="$2" 1.409 + [ ! -d "$PKGS" ] && \ 1.410 + gettext -e "\nPackages directory dont exist\n\n" && exit 1 1.411 + cd $PKGS 1.412 + gettext -e "\nCreating lists for:"; echo " $PKGS" 1.413 + separator 1.414 + rm -f packages.* files.list* 1.415 + gettext -e "Creating: packages.list\n" 1.416 + ls -1 | sed s'/.tazpkg//' > $PKGS/packages.list 1.417 + gettext -e "Creating: packages.md5\n" 1.418 + md5sum *.tazpkg > $PKGS/packages.md5 1.419 + gettext -e "Creating: packages.desc\n" 1.420 + gettext -e "Creating: packages.equiv\n" 1.421 + cd $WOK 1.422 + for pkg in * 1.423 + do 1.424 + unset_receipt 1.425 + . $pkg/receipt 1.426 + # packages.desc let us search easily in DB 1.427 + if [ -f "$PKGS/$PACKAGE-${VERSION}${EXTRAVERSION}.tazpkg" ]; then 1.428 + cat >> $PKGS/packages.desc << EOT 1.429 +$PACKAGE | $VERSION$EXTRAVERSION | $SHORT_DESC | $CATEGORY | $WEB_SITE 1.430 +EOT 1.431 + # Packages.equiv is used by tazpkg install to check depends. 1.432 + for i in $PROVIDE; do 1.433 + DEST="" 1.434 + echo $i | fgrep -q : && DEST="${i#*:}:" 1.435 + if grep -qs ^${i%:*}= $PKGS/packages.equiv; then 1.436 + sed -i "s/^${i%:*}=/${i%:*}=$DEST$PACKAGE /" \ 1.437 + $PKGS/packages.equiv 1.438 + else 1.439 + echo "${i%:*}=$DEST$PACKAGE" >> $PKGS/packages.equiv 1.440 + fi 1.441 + done 1.442 + fi 1.443 + done 1.444 + # files.list.lzma 1.445 + #lzma e files.list files.list.lzma 1.446 + separator 1.447 + nb=$(ls $PKGS/*.tazpkg | wc -l) 1.448 + echo -e "Packages: $nb\n" ;; 1.449 + *) 1.450 + # Just cook and generate a package. 1.451 + check_root 1.452 + time=$(date +%s) 1.453 + pkg="$1" 1.454 + [ -z "$pkg" ] && usage 1.455 + check_pkg_in_wok && echo "" 1.456 + unset inst 1.457 + unset_receipt 1.458 + cd $WOK/$pkg && . ./receipt 1.459 + 1.460 + # Handle --options 1.461 + case "$2" in 1.462 + --clean|-c) 1.463 + gettext -e "Cleaning package:"; echo -n " $pkg" 1.464 + cd $WOK/$pkg && rm -rf install taz source 1.465 + status && echo "" && exit 0 ;; 1.466 + --install|-i) 1.467 + inst='yes' ;; 1.468 + esac 1.469 + 1.470 + # Check if wanted is build now so we have separate log files. 1.471 + if [ "$WANTED" ] && [ ! -d "$WOK/$WANTED/install" ]; then 1.472 + cook "$WANTED" 1.473 + fi 1.474 + 1.475 + # Cook and pack or exit on error and log everything. 1.476 + cookit | tee $LOGS/$pkg.log 1.477 + cookit_quality 1.478 + packit | tee -a $LOGS/$pkg.log 1.479 + clean_log 1.480 + packit_quality 1.481 + 1.482 + # Time and summary 1.483 + time=$(($(date +%s) - $time)) 1.484 + summary | tee -a $LOGS/$pkg.log 1.485 + 1.486 + # Install package if requested 1.487 + if [ "$inst" ]; then 1.488 + if [ -f "$PKGS/$PACKAGE-${VERSION}${EXTRAVERSION}.tazpkg" ]; then 1.489 + cd $PKGS && tazpkg install \ 1.490 + $PACKAGE-${VERSION}${EXTRAVERSION}.tazpkg --forced 1.491 + else 1.492 + gettext -e "Unable to install package, build have failed.\n\n" 1.493 + exit 1 1.494 + fi 1.495 + fi 1.496 + # Finally we may want to build the *-dev package 1.497 + #[ -d "$WOK/$pkg-dev" ] && cook $pkg-dev 1.498 + ;; 1.499 +esac 1.500 + 1.501 +exit 0