functions: changed pkginstalled() to use $* instead of "$@" when generating the pattern
[opensde-nopast.git] / lib / functions.in
blob74c27252b4ec81a771255f2309b7b050a18e7ed2
1 # --- SDE-COPYRIGHT-NOTE-BEGIN ---
2 # This copyright note is auto-generated by ./scripts/Create-CopyPatch.
4 # Filename: lib/functions.in
5 # Copyright (C) 2006 - 2008 The OpenSDE Project
6 # Copyright (C) 2004 - 2006 The T2 SDE Project
7 # Copyright (C) 1998 - 2003 Clifford Wolf
9 # More information can be found in the files COPYING and README.
11 # This program is free software; you can redistribute it and/or modify
12 # it under the terms of the GNU General Public License as published by
13 # the Free Software Foundation; version 2 of the License. A copy of the
14 # GNU General Public License can be found in the file COPYING.
15 # --- SDE-COPYRIGHT-NOTE-END ---
17 . ${SDEROOT:-.}/lib/core-functions.in
19 # This function returns a "uniqe id" as output
21 get_unique() {
22         local hostsum=`hostname 2>/dev/null | tr '()' _`
23         if [ -z "$hostsum" -a -x /sbin/ip ]; then
24                 hostsum=`/sbin/ip link show eth0 |
25                 sed -e '/link\//!d' -e 's,.*link[^ ]* \([^ ]*\) .*,\1,'`
26         fi
27         if [ -z "$hostsum" -a -f /sbin/ifconfig ]; then
28                 hostsum=`/sbin/ifconfig eth0 |
29                 sed -e '/HWaddr/!d' -e 's/.* HWaddr \([^ ]*\)/\1/'`
30         fi
31         if [ -z "$hostsum" -a -x /usr/bin/hostid ]; then
32                 hostsum=`/usr/bin/hostid`
33         fi
34         date "+%Y%m%d.%H%M%S.$$.$hostsum"
37 # this functions expands an string replacing % with all possible values
38 # listed after
39 case "$BASH_VERSION" in  # damn workaround for different syntax in both versions
40     2*)
41 get_expanded() {
42         local string="$1"; shift
43         while [ $# -gt 0 ]; do
44                 echo "${string//\\%/$1}"
45                 shift
46         done
49 3*)
50 get_expanded() {
51         local string="$1"; shift
52         while [ $# -gt 0 ]; do
53                 echo "${string//\%/$1}"
54                 shift
55         done
58 esac
60 # atstage <stagename> ...
61 # returns true if the build is on a stage related to the given name
63 atstage() {
64         local x=
65         for x; do
66                 case "$x" in
67                         toolchain)
68                                 [ $stagelevel -gt 0 ] || return 0       ;;
69                         cross|crossbuild|crosscompile)
70                                 [ $stagelevel -ne 1 ] || return 0       ;;
71                         rebuild)
72                                 [ $stagelevel -ne 9 ] || return 0       ;;
73                         native)
74                                 [ $stagelevel -lt 2 ] || return 0       ;;
75                         *)
76                                 echo "atstage: '$x' stagename is not supported." >&2
77                                 break   ;;
78                 esac
79         done
80         return 1
83 # hasflag FLAG
85 hasflag() {
86         local flag=
87         for flag; do
88                 if ! echo "$desc_F" | grep -q -e "^\(.* \)\?$flag\( .*\)\?\$"; then
89                         return 1
90                 fi
91         done
92         return 0
95 # bz2filename [<filename>]
96 # outputs filename converted to .bz2. stdin and $1 inputs are accepted
98 bz2filename() {
99         local pattern='-e s,\.\(t\?\)\(gz\|Z\)$,.\1bz2,'
100         pattern="-e s,\.gpg$,, $pattern"
101         pattern="-e s,\.tar$,\.tar.bz2, $pattern"
103         if [ -n "$1" ]; then
104                 echo "$1" | sed $pattern
105         else
106                 sed $pattern
107         fi
110 # Hook variables
112 unset hook_functions hook_fcounter
113 declare -a hook_functions='()'
114 hook_fcounter=0
116 # This function adds a code fragment to a named hook with the named priority
118 # hook_add hook_name priority code
120 hook_add() {
121         hook_functions[hook_fcounter]="$3" # declare -a hookidx_$1
122         eval "hookidx_$1[\${#hookidx_$1[@]}]=\"$2 $hook_fcounter\""
123         eval "(( hookdirty_$1++ ))" || true ; (( hook_fcounter++ )) || true
126 # This function executes all code fragments from the named hook
128 # hook_eval hook_name
130 hook_eval() {
131         while read pri fnr ; do
132                 [ "$pri" ] && eval "${hook_functions[fnr]}"
133         done < <( IFS=$'\n' ; eval "echo \"\${hookidx_$1[*]}\"" | sort )
134         eval "unset hookdirty_$1"
137 # This function prints all hooks and their current contents
139 # hook_dump
141 hook_dump() {
142         for hook in ${!hookidx_*} ; do
143                 hook=${hook#hookidx_}
144                 echo ; echo "Contents of hook $hook:"
146                 while read pri fnr ; do
147                         echo ; echo "    $pri ($fnr)"
148                         echo "${hook_functions[fnr]}" | sed 's,^,       ,'
149                 done < <( IFS=$'\n'
150                           eval "echo \"\${hookidx_$hook[*]}\"" | sort )
151                 if eval "[ -n \"\$hookdirty_\$hook\" ]"; then
152                         echo ; echo -n "    Hook is marked as dirty: "
153                         eval "echo \"\${hookdirty_$hook}\""
154                 fi
155         done
156         echo
159 # This function can be used to duplicate a shell-function. E.g. when
160 # overwriting a shell-function but the old one should stay available under
161 # a new name:
163 #       copy_function set_confopt set_confopt_foobar_old
165 #       set_confopt() {
166 #               ....
167 #               set_confopt_foobar_old "$@"
168 #               ....
169 #       }
171 copy_function() {
172         eval "$( declare -f $1 | sed "1 s,$1,$2," )"
175 # | column_clean |
177 # convert tabs to spaces, transform multiple consecutive spaces to one,
178 # remove leading and trailing spaces
179 column_clean() {
180         tr '\t' ' ' | tr -s ' ' | sed -e 's,^[ ]*,,; s,[ ]*$,,;'
183 # | column_clean_tab |
185 # see column_clean, but with tabs
186 column_clean_tab() {
187         tr ' ' '\t' | tr -s '\t' | sed -e 's,^[\t]*,,; s,[\t]*$,,;'
190 # This function sets the 'confopt' and some other variables.
191 # Re-run it in the package .conf file if you modify $prefix
193 set_confopt() {
194         local x= z=
195         prefix=${prefix#/}
197         if atstage toolchain; then
198                 z="$root"
199         fi
201         confopt="--prefix=$z/$prefix"
203         for x in bindir sbindir libdir datadir includedir \
204             docdir infodir mandir sysconfdir localstatedir
205         do
206                 # bindir=/usr/bin
207                 eval "$x=`pkggetdir $x`"
208                 # --bindir=$root\$bindir
209                 confopt="$confopt --$x=$z\$$x"
211         done
213         export LIBSUFF=${libdir##*/lib}
215         if [ "$SDECFG_CONFIGURE_OPTS" ] ; then
216                 confopt="$confopt $SDECFG_CONFIGURE_OPTS"
217         fi
219         if [ "$SDECFG_DEBUG" = 0 ] ; then
220                 confopt="$confopt --disable-debug"
221         fi
223         if ! atstage native || [ "$SDECFG_DISABLE_NLS" = 1 ] ; then
224                 confopt="${confopt//--enable-nls/} --disable-nls"
225         fi
227         confopt="$confopt \$extraconfopt"
228         if atstage toolchain; then
229                 confopt="$confopt --target=\$arch_target --host=\$arch_build"
230         else
231                 confopt="$confopt --build=\$arch_build --host=\$arch_target"
232         fi
236 # eval_config_command $( eval echo $confopt )
238 function eval_config_command() {
239         local config_command=
240         local config_cache=$builddir/config.cache.$buildloop
242         for x in /usr/share/automake/*
243         do
244                 [ -x "$x" -a -f "$x" ] || continue
245                 x="$( basename "$x" )"
246                 if [ -L $x -a ! -e $x ] ; then
247                         echo "Fixing dead symlink $x."
248                         ln -sf /usr/share/automake/$x .
249                 fi
250         done
252         if [ -n "$configcache" ] || atstage cross; then
253                 if atstage cross; then
254                         create_config_cache >> $config_cache
255                 fi
257                 if [ -n "$configcache" ]; then
258                         cat <<-EOT
260                         # Some custom values
261                         EOT
262                         for x in $configcache; do
263                                 echo "$x"
264                         done
265                 fi >> $config_cache
267                 grep -q '.--cache-file=' $configscript &&
268                         set -- "$@" "--cache-file=$config_cache"
269                 export cache_file=$config_cache
270         fi
272         config_command="$configprefix $configscript"
273         sub_scripts="$( find $( dirname $configscript ) -name configure )"
275         if [ "$cleanconfopt" = "0" ]; then
276                 config_command="$config_command $@"
277         else
278         # remove unsupported config script options
279         for x ; do
280                 if grep -q "[[ ]${x%%=*}[]= ):]" $configscript $sub_scripts ; then
281                         config_command="$config_command $x"
282                 elif [[ $x = --*able-* ]] && egrep -q "\-\-(en|dis)able-\*" $configscript ||
283                      [[ $x = --with* ]] && egrep -q "\-\-with(|out)-\*" $configscript; then
284                         echo "Autodetection for option impossible: " \
285                              "$x passed thru."
286                         config_command="$config_command $x"
287                 else
288                         echo "Removing unsupported '$x' from" \
289                              "configure option string."
290                 fi
291         done
292         fi
294         echo Running "$config_command"
295         eval "$config_command"
298 # run 'make check' if Makefile supports it.
300 function run_check() {
301         if grep -q -e "^check:" ./Makefile; then
302                 echo "Running make check ..."
303                 $MAKE check
304         fi
305         if grep -q -e "^test:" ./Makefile; then
306                 echo "Running make test ..."
307                 $MAKE test
308         fi
311 # move the static libs from lib to usr/lib and correct the libdir used
312 # inside the .la file
314 postflist_static_lib() {
315         echo "Processing static lib corrections ..."
316         egrep '^(lib|lib64)/.*\.(a\..*|a|la)$' $builddir/flist.txt |
317         while read fn ; do
318                 [ -e $root/$fn -o -L $root/$fn ] || continue
320                 case "$fn" in
321                 *.la)
322                         sed "s,\([ =']\)/lib\(.*\),\1/usr/lib\2,g" \
323                                 $root/$fn > $root/usr/$fn
324                         so=${fn%.la}.so
325                         ln -svf $root/$so $root/usr/$so
326                         add_flist $root/usr/$so
327                         rm $root/$fn
328                         ;;
329                 *)
330                         mv -fv $root/$fn $root/usr/$fn
331                         ;;
332                 esac
333                 add_flist $root/usr/$fn
334         done
336         # this check might be removed in the future when we decide this is not
337         # an issue anymore ...
338         echo "Verifing the .la files ..."
339 #       defect_la="`egrep '(lib|lib64)/.*\.la$' $builddir/flist.txt |
340 #                   xargs egrep 'dependency_libs=.*-pthread.*' |
341 #                   cut -d : -f1 | sort -u | tr '\n' ' '`"
342 #       if [ "$defect_la" ] ; then
343 #               abort "-pthread in: $defect_la!"
344 #       fi
346         defect_la="`egrep '(lib|lib64)/.*\.la$' $builddir/flist.txt |
347                     xargs egrep "dependency_libs=.*(TOOLCHAIN|BACKUP|$SDECFG_ID).*" |
348                     cut -d : -f1 | sort -u | tr '\n' ' '`"
349         if [ "$defect_la" ]; then
350                 local la
351                 echo_warning "Detected problems in following libtool files:"
352                 for la in $defect_la; do
353                         echo_warning "  $la"
354                 done
355                 echo_warning "In absence of a proper fix (or replacement) for libtool and friends,"
356                 echo_warning "for now the .la files are automatically corrected."
358                 # Cleanup dependency_libs, remove build system path
359                 local dependency_libs
360                 local dlibsnew=
361                 local dlibtmp deplib
362                 local libsub=${libdir##*/}
363                 for la in $defect_la; do
364                         eval `grep ^dependency_libs= $root/$la`
366                         for deplib in $dependency_libs; do
367                                 if [ $libsub != lib ]; then
368                                         case "$deplib" in
369                                         */lib|*/lib/*)
370                                                 deplib="`echo $deplib | sed "s,/lib$,/$libsub,g; s,/lib/,/$libsub/,g"`"
371                                                 ;;
372                                         esac
373                                 fi
375                                 case "$deplib" in
376                                 *TOOLCHAIN*|*BACKUP*|*$SDECFG_ID*) ;;
377                                 *)
378                                         dlibtmp=$dlibsnew ; var_remove dlibtmp ' ' "$deplib"
379                                         [ "$dlibtmp" = "$dlibsnew" ] && var_append dlibsnew ' ' "$deplib"
380                                         ;;
382                                 esac
383                         done
385                         sed -i "s,^dependency_libs=.*,dependency_libs='$dlibsnew'," $root/$la
386                         dlibsnew=
387                 done
388         fi
391 # Parse the *.desc file. Use the description from etc/desc_format and
392 # save the tag data in $desc_*.
394 parse_desc() {
395         tag="`grep '^\[' $base/etc/desc_format |
396               sed 's, (\*),,; s,\] \[,|,g; s,\[,,; s,\],,;'`"
398         for tag in $tag ; do
399                 tagdata="`egrep "^\[($tag)\]" $confdir/$1.desc |
400                           cut -f2- -d']' | sed 's,^ ,,'`"
401                 tag="`echo $tag | cut -f1 -d'|' | tr - _`"
402                 eval "desc_$tag=\"\$tagdata\""
403         done
405         ver="`echo "$desc_V" | tail -n 1 | cut -f1 -d' '`"
406         extraver="`echo "$desc_V" | tail -n 1 | cut -s -f2- -d' '`"
407         [ -z "$extraver" ] && extraver="${sdever//DEV-*/DEV}"
410 # This function is used for forcing a file to be in the flist
412 add_flist() {
413         for addfile ; do
414                 echo "$addfile" | fl_wrparse -D -r "$xroot/" \
415                         >> $builddir/flist.txt
416         done
419 # This function is used for forcing a package to be in the dependency list
421 add_dependency() {
422         for addpackage ; do
423                 echo "$addpackage: add_dependency()" \
424                                         >> $builddir/dependencies.debug
425         done
428 # This function is used to subsitute some important variables
429 # using a D_ prefix thru m4 ...
430 rock_substitute() {
431         sed -e s,D_prefix,$prefix,g   -e s,D_sysconfdir,$sysconfdir,g \
432             -e s,D_docdir,$docdir,g   -e s,D_localstatedir,$localstatedir,g \
433             -e s,D_datadir,$datadir,g -e s,D_infodir,$infodir,g \
434             -e s,D_bindir,$bindir,g   -e s,D_sbindir,$sbindir,g \
435             -e s,D_libdir,$libdir,g   -e s,D_mandir,$mandir,g \
436             -e s,D_ver,$ver,g          $1
439 # This outputs a predefined config.cache file as it needed by some
440 # packages to cross-build correctly in stages 0 and 1.
442 create_config_cache() {
443         cat $base/architecture/share/config.cache
445         if [ $createarchcache -eq 1 ]; then
446                 cat  <<-EOT
447                 # Architecture specific stuff
448                 #
449                 arch_sizeof_char=1
450                 ac_cv_sizeof_short=$arch_sizeof_short
451                 ac_cv_sizeof_int=$arch_sizeof_int
452                 ac_cv_sizeof_long=$arch_sizeof_long
453                 ac_cv_sizeof_long_long=$arch_sizeof_long_long
454                 ac_cv_sizeof_char_p=$arch_sizeof_char_p
455                 ac_cv_sizeof_void_p=$arch_sizeof_char_p
456                 ac_cv_c_bigendian=$arch_bigendian
458                 EOT
459         fi
462 # Abort build before actual build starts
463 # (is overwritten in Build-Pkg)
465 abort() {
466         echo -e "The package build aborted with the following config" \
467              "error:\n$*" > $root/var/adm/logs/$stagelevel-$xpkg.err
468         echo_errorquote "`cat $root/var/adm/logs/$stagelevel-$xpkg.err`"
469         echo_pkg_abort $stagelevel $repository $xpkg
470         exit 1
473 # Dump Environment
475 dump_env() {
477         # Dump $base - only set if there is not already an older value.
478         #
479         echo "base=\"\${base:-$base}\""
481         # Dump all variables including their flags, but skip read-only
482         # variables and $base.
483         #
484         # Substitute base directory with ${base}.
485         #
486         for name in ${!a*} ${!b*} ${!c*} ${!d*} ${!e*} ${!f*} ${!g*} ${!h*} \
487                     ${!i*} ${!j*} ${!k*} ${!l*} ${!m*} ${!n*} ${!o*} ${!p*} \
488                     ${!q*} ${!r*} ${!s*} ${!t*} ${!u*} ${!v*} ${!w*} ${!x*} \
489                     ${!y*} ${!z*}                                           \
490                     ${!A*} ${!B*} ${!C*} ${!D*} ${!E*} ${!F*} ${!G*} ${!H*} \
491                     ${!I*} ${!J*} ${!K*} ${!L*} ${!M*} ${!N*} ${!O*} ${!P*} \
492                     ${!Q*} ${!R*} ${!S*} ${!T*} ${!U*} ${!V*} ${!W*} ${!X*} \
493                     ${!Y*} ${!Z*} ${!_*}
494         do
495                 [ $name = base -o $name = PWD ] && continue
496                 if declare -p $name | head -n 1 | grep -qv '^declare -[a-z]*r'
497                 then
498                         declare -p $name | sed "s,\\(^\\|[\"=:]\\)$base\\([\"=:/]\\|\$\\),\\1\${base}\\2,g"
499                 fi
500         done
502         # Dump functions
503         #
504         declare -f | sed 's/^declare -f //; s/<<(/< <(/;'
506         # Dump aliases
507         #
508         alias
511 # Returns the value of a field of the .desc file of a package
513 pkgdesc() {
514         local pattern=
515         local descfile=$( ls -1d $base/package/*/$2/$2.desc 2> /dev/null )
517         case "$1" in
518                 ver)    pattern="V"     ;;
519                 *)      pattern="$1"    ;;
520         esac
522         if [ -s "$descfile" ]; then
523                 case "$1" in
524                 confdir)
525                         echo "${descfile%/*}"
526                         ;;
527                 *)
528                         sed -n "s,^\[$pattern\][ \t]\+\(.\+\)[ \t]*$,\1,p" "$descfile"
529                         ;;
530                 esac
531         else
532                 echo_error "pkgdesc: Package $2 not found."
533         fi
536 # Check if a package is already installed
538 # It does check the build-list if not in the rebuild stage - and
539 # the really installed package data for rebuilds (and so manual builds).
541 # space delimited list, -f as first arguent for effective check
543 pkginstalled() {
544         local effective=0
546         if [ $# -eq 0 ]; then
547                 return 1        # nothing
548         elif [ "$1" = "-f" ]; then
549                 effective=1; shift
550         elif atstage rebuild; then
551                 effective=1
552         fi
554         if [ $effective -eq 0 ]; then
555                 local pattern=
556                 [ $# -gt 0 ] || return 1        # we expect at least one package
558                 if [ $# -eq 1 ]; then
559                         pattern="$1"
560                 else
561                         pattern="($*)"
562                 fi
564                 pattern="${pattern//+/\\+}"
565                 egrep -q "^X.* ${pattern// /|} " $base/config/$config/packages
566                 # we return what egrep returns
567         else
568                 local pkg=
569                 # be happy if any package from the list is installed
570                 for pkg; do
571                         [ ! -f "$root/var/adm/packages/$pkg" ] || return 0
572                 done
573                 return 1
574         fi
577 # pkgprefix [-t] [<type>] <package>
578 # returns the prefix or the location of a 'type' of an already build package
580 pkgprefix() {
581         local type= pkg=
582         local dotest= abortmsg=
583         local prefix= value=
585         # -t : only see if it's possible to get the values
586         if [ "$1" = "-t" ]; then
587                 dotest=1; shift
588         fi
590         if [ $# -eq 2 ]; then
591                 type="$1"; shift
592         fi
593         pkg="$1"
595         # test usual error causes
596         if [ -z "$pkg" ]; then
597                 abortmsg="you must specify a package"
598         elif [ ! -f "$root/var/adm/packages/$pkg" ]; then
599                 abortmsg="package $pkg is not present"
600         elif grep -q "^Prefix:" "$root/var/adm/packages/$pkg"; then
601                 prefix=$( grep "^Prefix: " "$root/var/adm/packages/$pkg" | cut -d' ' -f2- )
602         else
603                 abortmsg=`echo "$pkg record is old, please rebuild the package $pkg. As an alternative, you can insert a line into the file $root/var/adm/packages/$pkg containing the text below:\n\nPrefix: <prefix>" | fmt -w 55 | sed 's,$,\\n,g'`
604         fi
606         if [ "$dotest" ]; then
607                 # test mode: abort or continue
608                 if [ "$abortmsg" ]; then
609                         abort "pkgprefix: $abortmsg"
610                 else
611                         return 0
612                 fi
613         elif [ "$abortmsg" ]; then
614                 echo "pkgprefix: $abortmsg" 1>&2
615         elif [ -z "$type" -o "$type" = "prefix" ]; then
616                 echo "$prefix"
617                 return 0
618         elif [ "$type" = "ver" ]; then
619                 value=$( grep "^Package Name and Version:" "$root/var/adm/packages/$pkg" | cut -d' ' -f6 )
620         else
621                 value=$( grep "^Location $type: " "$root/var/adm/packages/$pkg" | cut -d' ' -f3- )
622                 if [ -z "$value" ]; then
623                         # try default location for that $prefix
624                         value=$( xpkg="$pkg"; pkggetdir "$type" )
625                 fi
626         fi
627         echo "${value:-PKGPREFIX_ERROR}"
630 # pkggetdir <type>     (needs $prefix and $xpkg)
631 # returns the location for the file of a 'type' considering it's prefix
633 pkggetdir() {
634         local xprefix=${prefix:+/$prefix}
635         case "$1" in
636                 bindir)  echo "$xprefix/bin"    ;;
637                 sbindir) echo "$xprefix/sbin"   ;;
638                 libdir)
639                   if [ "$SDECFG_MULTILIB" = 1 ]; then
640                     case $arch_machine in
641                         powerpc64|sparc64|x86_64|mips64)
642                                 echo "$xprefix/lib64"   ;;
643                         *)
644                                 echo "$xprefix/lib"     ;;
645                     esac
646                   else
647                         echo "$xprefix/lib"
648                   fi
649                   ;;
650                 datadir) echo "${xprefix:-/usr}/share"  ;;
651                 infodir) echo "${xprefix:-/usr}/info"   ;;
652                 mandir) echo "${xprefix:-/usr}/man"     ;;
653                 docdir) echo "${xprefix:-/usr}/doc/$xpkg"       ;;
654                 includedir) echo "${xprefix:-/usr}/include"     ;;
655                 sysconfdir) echo "/etc${xprefix##/usr*}"        ;;
656                 localstatedir) echo "/var${xprefix##/usr*}"     ;;
657         esac
661 # This function generates the T2 package checksum of $confdir.
662 # The checksum includes the filenames and content (except of the .cache),
663 # including subdirs but without whitespaces and comments and some tag lines
664 # that are not vital for rebuilds during update checks.
666 # pkgchksum package-name | full-patch
668 pkgchksum() {
669   (
670         # expand to full patch if only a package name was specified
671         [[ $1 == */* ]] || set $base/package/*/$1/
672         cd $1
673         # find all files (without hidden (e.g. .svn) files)
674         find . ! -path '*/.*' ! -name '*.cache' -print -exec cat \{\} \; \
675         2>/dev/null |
676         # strip some unimportant stuff (e.g. comments, whitespaces, ...)
677         sed \
678         -e '/^[ ]*#.*/d' \
679         -e '/^\[COPY\]/d' \
680         -e '/^\[CV-*\]/d' \
681         -e '/^\[[T,I,U,A,M,L,S,C]\]/d' \
682         -e 's/[\t ]*//g' \
683         -e '/^ *$/d' |
684         md5sum | cut -d ' ' -f 1
685   )
688 # Create Package Database for gasgui install tool
690 create_package_db() {
691         rm -f $3.tmp
692         for file in $( echo $1/descs/* ) ; do
693                 [ -f "$file" ] || continue
694                 pkg="${file##*/}"
695                 # only include the package if a binary file is available
697                 if [ "$SDECFG_PKGFILE_VER" = 1 ] ; then
698                         v=-$(grep '^Package Name and Version' \
699                                 $1/packages/$pkg | cut -f6 -d' ')
700                 else
701                         v=
702                 fi
703                 bfile=${pkg}${v}.$SDECFG_PKGFILE_TYPE
705                 if [ -e $2/$bfile ] ; then
706                         [ "$pkg" = TRANS.TBL ] && continue
708                         ( echo -e "$pkg"
709                           echo -e "\027"
711                           cat $1/descs/$pkg | grep -v '\[COPY\]'
712                           echo -e "\027"
714                           cat $1/dependencies/$pkg
715                           echo -e "\027"
717                           cat $1/cksums/$pkg
718                           echo -e "\027"
720                           echo -e "\004"
721                         ) >> $3.tmp
722                 else
723                         echo_error "Binary file for $bfile not present." \
724                                    "Skipped in package database."
725                 fi
726         done
727         gzip -c $3.tmp > $3 ; rm -f $3.tmp
730 # Add files to the 'badfiles' list
732 register_badfiles() {
733         local x desc="$1"
734         shift
736         for x in "$@"; do
737                 var_append badfiles $'\n' " $x\$"
738                 badfiles_desc[$badfiles_nr]=" $x\$"$'\n'"$desc"
739                 (( badfiles_nr++ ))
740         done
743 # Detect the available patchfiles
745 detect_patchfiles()
747         local x= y=
748         patchfiles="`ls $confdir/*.patch{,.$arch} \
749                         $confdir/*.patch_$xpkg{.$arch} \
750                         2> /dev/null | tr '\n' ' '`"
752         for x in $( get_reverted $targetchain ); do
753                 for y in pkg_$pkg.patch{,.$arch} xpkg_$xpkg.patch{,.$arch}; do
754                         if [ -f $base/target/$x/$y ]; then
755                                 patchfiles="$patchfiles $base/target/$x/$y"
756                         fi
757                 done
758         done
761 # Apply the given $patchfiles
762 # [ hook called for each patch ] [ filter script ]
764 apply_patchfiles() {
765         local hook="$1"
766         local filter="$2"
767         [ "$filter" ] || filter=cat
768         for x in $patchfiles; do
769                 # correct the abolute path - e.g  for patchfiles supplied
770                 # in the .desc file
771                 # we assume relative path patches are mirrorables //mnemoc
772                 if [ ! -e "$x" -a -n "${x##*/*}" ] ; then
773                         x="$base/download/mirror/${x:0:1}/$x"
774                 fi
776                 # Apply the patch if the file does exist or issue a warning
777                 if [ -f "$x" ] ; then
778                         echo "Apply patch $x ..."
780                         if [[ $x = *.bz2 ]] ; then
781                                 patch_file=`mktemp` ; patch_del=1
782                                 bzcat $x > $patch_file
783                         else
784                                 patch_file=$x ; patch_del=0
785                         fi
787                         $filter $patch_file | patch $patchopt
789                         [ $patch_del = 1 ] && rm $patch_file
790                         eval "$hook"
791                 else
792                         echo_warning "Unable to apply patch: $x (File not found!)"
793                 fi
794         done
797 # -------------------------------------------------------------------
798 # The automatic extraction of archive (prior to building) supports
799 # multiple archive types. For every archive type we have a separate
800 # func that knows how to extract the archive. However, every func
801 # should deliver two file: untar.txt and xsrcdir.txt.
803 # untar.txt needs to contain all extracted files.
804 # xsrcdir.txt need to contain the top level extraction directories.
805 # -------------------------------------------------------------------
807 autoextract_tar_bz2() {
808         echo "Extracting $xsrctar ($taropt) ... "
809         tar -v $taropt $1 > untar.txt
812 autoextract_zip() {
813         echo "Extracting $xsrctar ($zipopt) ... "
814         unzip $zipopt $1 | sed 's,^.*/$,,' |
815                 cut -f4 -d" " | grep -v "^$" > untar.txt
818 # Main program for building a package
820 build_this_package() {
821         if [ ".$desc_SRC" = "." ] ; then
822                 # Autodetect source tar and extract it
823                 #
824                 if [ "$srctar" = auto ] ; then
825                         xsourceballs=$( echo "$desc_D" | head -n 1 | tr ' ' '\t' | tr -s '\t' |
826                                 cut -f2 | bz2filename )
827                         if [ -z "$xsourceballs" ] ; then
828                                 echo "Can't auto-detect srctar for package '$xpkg'!"
829                                 false
830                         fi
831                 else
832                         xsourceballs="$srctar"
833                 fi
834         elif [ "$srctar" = auto ] ; then
835                 sourceballs=$( echo "$desc_D" | tr ' ' '\t' | tr -s '\t' |
836                         cut -f2 | bz2filename )
837                 xsrcpattern=$( echo "$desc_SRC" | tr ' ' '\t' | tr -s '\t' | tr '\t' '\n' )
838                 xsourceballs=$( echo "$sourceballs" | grep -F "$xsrcpattern" )
839         else
840                 xsourceballs="$srctar"
841         fi
842         for xsrctar in $xsourceballs; do
843                 saved_patchfiles="$patchfiles"
844                 buildloop=1
845                 var_append patchfiles " " \
846                            "`ls $confdir/*.patch.${xsrctar/-[v0-9]*/} 2> /dev/null`"
847                 if [ "$xsrctar" != none -a "$autoextract" = 1 ]; then
848                         cd $builddir
849                         if [ -z "$custextract" ]; then
850                                 # No custom extraction, so determine what
851                                 # autoextraction to use.
852                                 case "$xsrctar" in
853                                 *.zip) custextract="autoextract_zip" ;;
854                                 *) custextract="autoextract_tar_bz2" ;; # *.tar.bz2|*.tbz2|*.tbz
855                                 esac
856                         fi
857                         if [ -n "$custextract" ]; then
858                                 # Do the actual extraction of the archive.
859                                 eval "$custextract $archdir/$xsrctar"
860                                 cat untar.txt |
861                                         sed 's,^\./,,' | cut -f1 -d/ |
862                                         sort -u > xsrcdir.txt
863                         fi
864                         #
865                         if [ "$srcdir" = auto ]; then
866                                 xsrcdir=${xsrctar%.tar.bz2}
867                                 xsrcdir=${xsrcdir%.tbz2}
868                                 xsrcdir=${xsrcdir%.tbz}
869                                 if [ ! -d $xsrcdir ] ; then
870                                         for x in $pkg-$ver ${pkg}_$ver $pkg \
871                                                  $xpkg-$ver ${xpkg}_$ver $xpkg \
872                                                  "$( cat xsrcdir.txt )"
873                                         do
874                                                 [ -d "$x" ] && xsrcdir="$x"
875                                         done
876                                 fi
877                         else
878                                 xsrcdir="$srcdir"
879                         fi
880                         #
881                         if [ "$chownsrcdir" = 1 ]; then
882                                 echo "Fixing ownership and permissions ..."
883                                 chown -R 0:0 $builddir/$xsrcdir
884                         fi
885                         #
886                         if [ "$nocvsinsrcdir" = 1 ]; then
887                                 echo "Removing CVS, .svn, .git, {arch} and .arch-ids directories ..."
888                                 egrep '(^|/)(CVS|\.svn|\.git|\{arch\}|\.arch-ids)(/|$)' untar.txt |
889                                 while read x; do
890                                         echo "Removing $x ..."
891                                         rm -rf "$x"
892                                 done
893                         fi
894                         #
895                         echo "Changeing into $builddir/$xsrcdir ..."
896                         cd $builddir/$xsrcdir
898                         # Apply patches
899                         #
900                         if [ $autopatch = 1 ]; then
901                                 hook_eval prepatch
902                                 apply_patchfiles
903                                 hook_eval postpatch
904                         fi
906                 else
907                         cd $builddir
908                 fi
910                 if [ "$createprefix" = 1 ]; then
911                         echo "Creating $root/$prefix/<..> if required ..."
912                         for x in $foodirlist; do
913                                 eval "x=\"$root\$$x\""
914                                 if [ ! -e $x ]; then
915                                         mkdir -p $x
916                                         rmemptydir="$rmemptydir $x"
917                                 fi
918                         done
919                 fi
921                 if [ -z "$custmain" ]; then
922                         while [ ${buildloop:-1} -le ${buildloops:-1} ]; do
923                         [ "${buildloops:-1}" = "1" ] || echo "loop ${buildloop:-1} of ${buildloops:-1} for $xsrctar."
925                         hook_eval preconf
927                         # Maybe generate a configure first
928                         #
929                         if [ $autogen -eq 1 -o \
930                              \( -f autogen.sh -a ! -f configure \) ] ; then
931                                 if [ -f autogen.sh ] ; then
932                                         echo "Running package autogen script."
933                                         sed -i '/^\.\/configure /d' autogen.sh
934                                         sh autogen.sh
935                                 else
936                                         echo "Running builtin autogen script."
937                                         libtoolize --force --automake ; aclocal
938                                         if grep AM_INIT_AUTOMAKE \
939                                            configure.[ia][nc]
940                                         then automake ; fi
941                                         autoconf
942                                 fi
943                         fi
944                         # Run configure scripts etc.
945                         #
946                         if [ $runconf = 1 ]; then
947                           if [ -n "$( type -p $configscript )" -o $autogen = 1 ]
948                           then
949                                 eval_config_command $( eval echo $confopt )
950                           fi
951                         fi
953                         # automated package build
955                         # styles without make run first:
956                         if [ -f setup.py -a $runpysetup = 1 ] ; then
957                                 pyconfopt="${pyconfopt:=--prefix $root/$prefix}"
958                                 hook_eval premake
959                                 eval ${pyscript:-python} setup.py build install $pyconfopt
960                                 hook_eval postmake
961                         else # styles that include a make run
962                                 if [ ! -f Makefile -a ! -f makefile -a \
963                                      -f Makefile.PL -a $runmkpl = 1 ]; then
964                                         perl Makefile.PL ${plconfopt:-INSTALLDIRS=perl}
965                                 fi
966                                 #
967                                 if [ ! -f Makefile -a ! -f makefile -a \
968                                      -f Imakefile -a $runxmkmf = 1 ]; then
969                                         xmkmf -a
970                                 fi
971                                 #
972                                 # Build it
973                                 #
974                                 hook_eval premake
975                                 if [ "$makeopt" ]; then
976                                         eval echo "Running $MAKE $makeopt"
977                                         eval "$MAKE $makeopt"
978                                 fi
979                                 hook_eval inmake
980                                 if [ "$makeinstopt" ]; then
981                                         eval echo "Running $MAKE $makeinstopt"
982                                         eval "$MAKE $makeinstopt"
983                                 fi
984                                 hook_eval postmake
985                         fi
986                         buildloop=$( expr ${buildloop:-1} + 1 )
987                         done
988                 else
989                         eval "$custmain"
990                         for x in preconf premake inmake postmake; do
991                                 if eval "[ -n \"\$hookdirty_$x\" ]"; then
992                                         echo "Hook $x is still marked as dirty ..."
993                                         hook_eval $x
994                                 fi
995                         done
996                 fi
998                 if [ "$createdocs" != 0 ]; then
999                         if [ ! -e $root$docdir ]; then
1000                                 mkdir -p $docdir
1001                                 rmemptydir="$rmemptydir $root$docdir"
1002                         fi
1003                         [ -z "$createdocs" ] && createdocs="$SDECFG_CREATE_DOCS"
1004                 fi
1006                 if [ "$createdocs" = 1 ]; then
1007                         echo "Trying to copy the default documentation ..."
1008                         for x in [A-Z][A-Z]* *.lsm ChangeLog* README LICENSE COPYING; do
1009                                 [ "${x#*.[cho0-9]}" ] || continue
1010                                 [ "${x#*.info*}"    ] || continue
1011                                 [ "${x#*.TAR*}"     ] || continue
1012                                 [ "${x#*akefile*}"     ] || continue
1013                                 [ -f $x ] && cp -v $x $root$docdir/$x
1014                         done
1016                         echo "Trying to copy even more documentation ..."
1017                         [ -d $builddir/$xsrcdir ] && cd $builddir/$xsrcdir
1018                         for x in `find -type d \( -name 'doc' -o -name 'docs' \
1019                                        -o -name '[Dd]ocumentation' \) ! -empty`
1020                         do
1021                                 if [ -d "$x" -a "`echo $x/*`" != "$x/*" ]
1022                                 then cp -rLv $x/* $root$docdir || true ; fi
1023                         done
1024                         for x in $confdir/*.doc; do
1025                                 if [ -f $x ]
1026                                 then cp -v $x $root$docdir/${x%.doc}; fi
1027                         done
1028                         find $root$docdir/ -name '*.[0-9]' -o -name '*.info*' \
1029                                 -o -name '[Mm]akefile*' |
1030                                 xargs -r rm -f 2> /dev/null || true
1031                         find $root$docdir/* -type d -empty 2> /dev/null |
1032                                 xargs -r rmdir 2> /dev/null || true
1033                 fi
1035                 hook_eval postdoc
1036                 if atstage native && [ -f /sbin/ldconfig ] ; then
1037                         echo "Running ldconfig ..."
1038                         ldconfig
1039                 fi
1040                 patchfiles="$saved_patchfiles"
1041         done
1043         if [ "$rmemptydir" ]; then
1044                 rmdir $rmemptydir 2> /dev/null || true
1045         fi
1047         return 0
1050 # source_file cksum file url
1052 # Create the file path from 'file' and 'url'.
1053 # cksum and url are ignored
1054 # ([D] tag compatible format)
1056 source_file() {
1057         local pre= file="$2" url="$3" mirror="mirror"
1059         # '-' as $url prefix means, nomirrorable
1060         [ "${url:0:1}" = "-" ] && mirror="local"
1062         # inside Build-Pkg $archdir is set
1063         if [ -n "$archdir" ]; then
1064                 pre=$base/; file="$( bz2filename $file )"
1065         fi
1067         echo ${pre}download/${mirror}/${file:0:1}/$file
1070 # match_source_file [-p] pattern [[package] ...]
1072 # returns path and name of a downloaded file from a list of packages, matching a grep pattern
1073 # without -p it only returns it's name, not the path.
1075 match_source_file() {
1076         local pattern= package= showpath=0
1077         local x= file= url= mirror=
1078         local found=1
1080         if [ "$1" = "-p" ]; then
1081                 showpath=1; shift
1082         fi
1083         pattern="$1"; shift
1085         for package in ${*:-$pkg}; do
1086                 while read x x file url x; do
1087                         file="$( bz2filename $file )"
1088                         found=0
1090                         if [ $showpath -eq 0 ]; then
1091                                 echo $file
1092                         else
1093                                 [ "${url:0:1}" = "-" ] && mirror="local" || mirror="mirror"
1094                                 echo $base/download/${mirror}/${file:0:1}/$file
1095                         fi
1096                 done < <( grep -e "^\[D\].*$pattern" $base/package/*/$package/$package.desc )
1097         done
1098         return $found
1101 # create the virtual $archdir symlinks
1103 populate_archdir()
1105         local x= missing=0
1106         for x in `match_source_file -p .`; do
1107                 if [ ! -f $x ]; then
1108                         echo_warning "File not found: ${x#$base/}"
1109                         missing=1
1110                 elif [ ! -e "$builddir/archdir/${x##*/}" ]; then
1111                         ln -vs $x $builddir/archdir/
1112                 fi
1113         done
1114         if [ $missing -eq 1 ]; then
1115                 echo_warning "Did you run download for this package?"
1116                 false
1117         fi
1120 # search for the package confdir
1122 detect_confdir()
1124         confdir=
1125         if [ -z "$pkgdir" ] ; then
1126           for x in package/*/$pkg/$pkg.desc ; do
1127                 if [ -f "$x" ] ; then
1128                   if [ "$confdir" ] ; then
1129                         echo_pkg_deny $stagelevel $pkg "in multiple trees"
1130                         echo "Package in multiple trees: $pkg !" \
1131                           > $root/var/adm/logs/$stagelevel-$xpkg.err
1132                         exit 1
1133                   fi
1134                   x=${x#package/}; x=${x%%/*}
1135                   confdir="$base/package/$x/$pkg"
1136                   repository=$x
1137                 fi
1138           done
1139         else
1140           if [ -f "$pkgdir/$pkg.desc" ] ; then
1141                 confdir="$pkgdir"
1142                 repository=extern
1143           fi
1144         fi
1147 # initialize standard vars and hooks
1149 init_vars_and_hooks()
1151         makeopt='CC="$CC" CPP="$CPP" CXX="$CXX"'
1153         if atstage toolchain; then
1154                 makeopt="$makeopt"' prefix="$root/$prefix"'
1155         else
1156                 makeopt="$makeopt"' prefix="/$prefix"'
1157         fi
1159         if ! atstage native; then
1160                 makeopt="$makeopt"' CC_FOR_BUILD="$BUILDCC"'
1161                 makeopt="$makeopt"' BUILDCC="$BUILDCC" BUILD_CC="$BUILD_CC"'
1162                 makeopt="$makeopt"' HOSTCC="$HOSTCC"   HOST_CC="$HOST_CC"'
1163                 makeopt="$makeopt"' STRIP="$STRIP" AR="$AR" LD="$LD"'
1164                 makeopt="$makeopt"' RANLIB="$RANLIB" NM="$NM"'
1165         fi
1167         if atstage native; then
1168                 flistdel="$flistdel|`echo $base | sed s,^/,,`/.*"
1169         fi
1171         if atstage cross; then
1172                 makeopt="$makeopt"' INSTALL_PREFIX="$root"'
1173                 makeopt="$makeopt"' DESTDIR="$root" DEST_DIR="$root"'
1174                 makeopt="$makeopt"' INSTROOT="$root" INSTALLROOT="$root"'
1175         fi
1176         makeinstopt="$makeopt"' install'
1178         custmain=
1179         buildloop=1 buildloops=1
1181         [ "$SDECFG_DO_CHECK" = 1 ] && hook_add inmake 6 'run_check'
1182         hook_add postflist 3 'postflist_static_lib'
1184         createarchcache=0
1186         configprefix=; configcache= ; autogen=0
1187         configscript="./configure" ; extraconfopt=
1189         srcdir=auto ; srctar=auto
1190         taropt="--use-compress-program=bzip2 -xf"
1192         mainfunction="build_this_package"
1193         runconf=1 ; runxmkmf=1 ; runmkpl=1 ; runpysetup=1 ; autopatch=1
1194         autoextract=1 ; chownsrcdir=1 ; nocvsinsrcdir=1 ; cleanconfopt=1
1195         patchopt="-bfp1 -z .orig"
1196         createprefix=1 ; createdocs= ; rmemptydir=
1198         check_shared=1
1199         check_usrlocal=1
1200         check_badfiles=1
1202         badfiles= badfiles_nr=0
1203         declare -a badfiles_desc
1206 # this is a 2nd lightweight and modular "build this package" implementation
1207 # currently only used for the postlinux stuff - later maybe for more -ReneR
1209 build_package()
1211   logstamp=$PWD/log
1212   (
1213         set -e
1214         pushd $base
1216         super=$pkg
1217         pkg="$1" ; xpkg="$pkg"
1218         conffile="$2" ; [ "$conffile" ] || conffile="$pkg.conf"
1220         unset ${!hook*}
1221         declare -a hook_functions='()'
1222         hook_fcounter=0
1223         init_vars_and_hooks
1225         detect_confdir
1226         detect_patchfiles
1228         parse_desc $pkg
1230         # Erase positional parameters to prevent unintended parameter
1231         # passing. We do not want to pass the current positional parameters
1232         # to the loaded script.
1233         set --
1234         eval "$desc_O"
1236         echo_status "Building $xpkg ($ver) within $super (using $conffile)."
1238         for x in $( get_expanded $base/target/%/pkg_$pkg.conf $targetchain ) \
1239                 $confdir/$conffile; do
1240                 if [ -f $x ]; then
1241                         if [[ $x == */$conffile ]]; then
1242                                 echo "Reading package configuration ($conffile) from package directory."
1243                         else
1244                                 echo "Reading package configuration from target directory."
1245                         fi
1246                         . $x
1247                         break
1248                 fi
1249         done
1251         # short path - to not abort on missing downloads of postlinux.conf
1252         # packages that are not built anyway -ReneR
1253         if [ "$custmain" = "true" ] ; then
1254                 echo "Nothing is going to be done ayway - returning quickly."
1255                 return
1256         fi
1258         populate_archdir
1259         popd
1261         # dump for debugging
1262         hook_dump > $builddir/debug.hooks.$pkg
1263         dump_env > $builddir/debug.buildenv.$pkg
1265         echo "Running main build function '$mainfunction' ..."
1266         cd $builddir
1268         eval "$mainfunction"
1269         touch $logstamp
1270   )
1271   [ -f $logstamp ] || return 1
1272   rm $logstamp
1273   return 0