* fix hyprutils to find pixman includes
[t2sde.git] / scripts / functions.in
blob0f4a33068f6aa1fea9c49d0c4f4cd996f721dfc6
1 # --- T2-COPYRIGHT-BEGIN ---
2 # t2/scripts/functions.in
3 # Copyright (C) 2004 - 2025 The T2 SDE Project
4 # Copyright (C) 1998 - 2003 ROCK Linux Project
5 # SPDX-License-Identifier: GPL-2.0
6 # --- T2-COPYRIGHT-END ---
8 . scripts/core-functions.in
10 # This function returns a "uniqe id" as output
12 get_unique() {
13         date "+%y%m%d.%H%M%S.$$"
16 # this functions expands an string replacing % with all possible values
17 # listed after
18 case "$BASH_VERSION" in  # damn workaround for different syntax in both versions
19     2*)
20 get_expanded() {
21         local string="$1"; shift
22         while [ $# -gt 0 ]; do
23                 echo "${string//\\%/$1}"
24                 shift
25         done
29 get_expanded() {
30         local string="$1"; shift
31         while [ $# -gt 0 ]; do
32                 echo "${string//\%/$1}"
33                 shift
34         done
37 esac
39 # atstage <stagename> ...
40 # returns true if the build is on a stage related to the given name
42 atstage() {
43         local x=
44         for x; do
45                 case "$x" in
46                         toolchain)
47                                 [ $stagelevel -gt 0 ] || return 0       ;;
48                         cross*)
49                                 [ $stagelevel -lt 1 -o $stagelevel -gt 2 ] || return 0  ;;
50                         rebuild)
51                                 [ $stagelevel -ne 9 ] || return 0       ;;
52                         native)
53                                 [ $stagelevel -lt 3 ] || return 0       ;;
54                         *)
55                                 echo "atstage: '$x' stagename is not supported." >&2
56                                 break   ;;
57                 esac
58         done
59         return 1
62 # hasflag FLAG
64 hasflag() {
65         local desc_F=" $desc_F " # surounding spaces for match below
66         local arch2
67         [ "$arch_sizeof_char_p" = 4 ] && arch2=arch32 || arch2=arch64
68         [ "$desc_F" != "${desc_F/ $1 }" -o \
69           "$desc_F" != "${desc_F/ $1.$arch }" -o "$desc_F" != "${desc_F/ $1.$arch2 }" -o \
70           "$desc_F" != "${desc_F/ $1.$SDECFG_LIBC }" -o \
71           "$desc_F" != "${desc_F/ $1.$SDECFG_DEFAULT_CC }" ]
74 # Hook variables
76 unset hook_functions hook_fcounter
77 declare -a hook_functions='()'
78 hook_fcounter=0
80 # This function adds a code fragment to a named hook with the named priority
82 # hook_add hook_name priority code
84 hook_add() {
85         hook_functions[hook_fcounter]="$3" # declare -a hookidx_$1
86         eval "hookidx_$1[\${#hookidx_$1[@]}]=\"$2 $hook_fcounter\""
87         eval "((hookdirty_$1++))" || true; ((hook_fcounter++)) || true
90 # This function executes all code fragments from the named hook
92 # hook_eval hook_name
94 hook_eval() {
95         while read pri fnr; do
96                 [ "$pri" ] && eval "${hook_functions[fnr]}"
97         done < <(IFS=$'\n'; eval "echo \"\${hookidx_$1[*]}\"" | sort)
98         eval "unset hookdirty_$1"
101 # This function prints all hooks and their current contents
103 # hook_dump
105 hook_dump() {
106         for hook in ${!hookidx_*}; do
107                 hook=${hook#hookidx_}
108                 echo; echo "Contents of hook $hook:"
109                 
110                 while read pri fnr; do
111                         echo; echo "    $pri ($fnr)"
112                         echo "${hook_functions[fnr]}" | sed 's,^,       ,'
113                 done < <(IFS=$'\n'
114                           eval "echo \"\${hookidx_$hook[*]}\"" | sort)
115                 if eval "[ -n \"\$hookdirty_\$hook\" ]"; then
116                         echo; echo -n "    Hook is marked as dirty: "
117                         eval "echo \"\${hookdirty_$hook}\""
118                 fi
119         done
120         echo
123 # This function can be used to duplicate a shell-function. E.g. when
124 # overwriting a shell-function but the old one should stay available under
125 # a new name:
127 #       copy_function set_confopt set_confopt_foobar_old
129 #       set_confopt() {
130 #               ....
131 #               set_confopt_foobar_old "$@"
132 #               ....
133 #       }
135 copy_function() {
136         eval "$(declare -f $1 | sed "1 s,$1,$2,")"
139 # | column_clean |
141 # convert tabs to spaces, transform multiple consecutive spaces to one,
142 # remove leading and trailing spaces
143 column_clean() {
144         sed 's,\t, ,g; s,  *, ,g; s,^[ ]*,,; s,[ ]*$,,'
147 # This function sets the 'confopt' and some other variables.
148 # Re-run it in the package .conf file if you modify $prefix
150 set_confopt() {
151         local x= z=
152         prefix=${prefix#/}
154         if atstage toolchain; then
155                 z="$root"
156         fi
158         confopt="--prefix=$z/$prefix"
159         mesonopt="setup objs/ --prefix=$z/$prefix"
160         ninjaopt="-j$SDECFG_PARALLEL"
162         for x in bindir sbindir libdir libexecdir datadir includedir \
163             docdir infodir mandir sysconfdir localstatedir
164         do
165                 # bindir=/usr/bin
166                 eval "$x=`pkggetdir $x`"
167                 # --bindir=$root\$bindir
168                 if [ "$x" != libexecdir -a "$x" != docdir ]; then
169                         confopt="$confopt --$x=$z\$$x"
170                         mesonopt="$mesonopt --$x=$z\$$x"
171                 fi
172         done
174         export LIBSUFF=${libdir##*/lib}
176         if [ "$SDECFG_CONFIGURE_OPTS" ]; then
177                 var_append confopt " " "$SDECFG_CONFIGURE_OPTS"
178         fi
180         if [ "$SDECFG_DEBUG" = 0 ]; then
181                 var_append confopt " " "--disable-debug"
182         fi
184         if [ "$SDECFG_DISABLE_NLS" = 1 ]; then
185                 var_remove confopt ' ' '--enable-nls'
186                 var_append confopt ' ' '--disable-nls'
187         fi
189         confopt="$confopt \$extraconfopt"
191         atstage cross && var_append confopt ' ' '--with-sysroot=$root'
192         if atstage toolchain; then
193                 confopt="$confopt --target=\$arch_target --build=\$arch_build --host=\$arch_build"
194         else
195                 confopt="$confopt --build=\$arch_build --host=\$arch_target"
196         fi
200 # eval_config_command $(eval echo $confopt)
202 function eval_config_command() {
203         local config_command
205         for x in /usr/share/automake/*; do
206                 [ -x "$x" -a -f "$x" ] || continue
207                 x="$(basename "$x")"
208                 if [ -L $x -a ! -e $x ]; then
209                         echo "Fixing dead symlink $x."
210                         ln -sf /usr/share/automake/$x .
211                 fi
212         done
214         if atstage cross; then
215                 create_config_cache >> config.cache
216                 grep -q '.--cache-file=' $configscript &&
217                         set -- "$@" "--cache-file=./config.cache"
218                 export cache_file=config.cache
219         fi
221         config_command="$configprefix $configscript"
222         sub_scripts="$(find $(dirname $configscript) -name configure)"
224         if [ "$cleanconfopt" == "0" ]; then
225                 config_command="$config_command $@"
226         else
227             # remove unsupported config script options
228             for x; do
229                 if grep -q "[[ ]${x%%=*}[]= ):]" $configscript $sub_scripts; then
230                         config_command="$config_command $x"
231                 elif [[ $x = --*able-* ]] && egrep -q "\--(en|dis)able-\*" $configscript ||
232                      [[ $x = --with* ]] && egrep -q "\--with(|out)-\*" $configscript; then
233                         echo "Autodetection for option impossible: " \
234                              "$x passed thru."
235                         config_command="$config_command $x"
236                 else
237                         echo "Removing unsupported '$x' from configure option string."
238                 fi
239             done
240         fi
242         echo Running "$config_command"
243         eval "$config_command"
245         # the missing script is generally not very helpful, ...
246         if [ -f build/missing ]; then echo '#!/bin/true' > build/missing; fi
247         if [ -f missing ]; then echo '#!/bin/true' > missing; fi
250 # run 'make check' if Makefile supports it.
252 function run_check() {
253         if grep -q -e "^check:" Makefile; then
254                 echo "Running make check"
255                 $MAKE check
256         fi
257         if grep -q -e "^test:" Makefile; then
258                 echo "Running make test"
259                 $MAKE test
260         fi
263 # move the static libs from lib to usr/lib and correct the libdir used
264 # inside the .la file
266 postflist_static_lib() {
267         echo "Processing static lib corrections ..."
268         egrep '^(lib|lib64)/.*\.(a|la)$' $builddir/flist.txt |
269         while read fn; do
270                 [ -e $root/$fn -o -L $root/$fn ] || continue
271                 if [[ $fn = *.a ]]; then
272                         mv -fv $root/$fn $root/usr/$fn
273                 else
274                         sed "s,\([ =']\)/lib\(.*\),\1/usr/lib\2,g" \
275                                 $root/$fn > $root/usr/$fn
276                         so=${fn%.la}.so
277                         ln -svf ../../$so $root/usr/$so
278                         add_flist $root/usr/$so
279                         rm $root/$fn
280                 fi
281                 add_flist $root/usr/$fn
282         done
284         # this check might be removed in the future when we decide this is not
285         # an issue anymore ...
286         echo "Verifing the .la files ..."
287         defect_la="`egrep '(lib|lib64)/.*\.la$' $builddir/flist.txt |
288                     xargs egrep 'dependency_libs=.*-pthread.*' |
289                     cut -d : -f1 | sort -u | tr '\n' ' '`"
290         if [ "$defect_la" ]; then
291                 abort "-pthread in: $defect_la!"
292         fi
294         defect_la="`egrep '(lib|lib64)/.*\.la$' $builddir/flist.txt |
295                     xargs egrep "dependency_libs=.*(TOOLCHAIN|BACKUP|$SDECFG_ID).*" |
296                     cut -d : -f1 | sort -u | tr '\n' ' '`"
297         if [ "$defect_la" ]; then
298                 local la
299                 echo_warning "Detected problems in following libtool files:"
300                 for la in $defect_la; do
301                         echo_warning "  $la"
302                 done
303                 echo_warning "In absence of a proper fix (or replacement) for libtool and friends,"
304                 echo_warning "for now the .la files are automatically corrected."
306                 # Cleanup dependency_libs, remove build system path
307                 local dependency_libs
308                 local dlibsnew=""
309                 local dlibtmp deplib
310                 local libsub=${libdir##*/}
311                 for la in $defect_la; do
312                         eval `grep ^dependency_libs= $root/$la`
314                         for deplib in $dependency_libs; do
315                                 if [ $libsub != lib ]; then
316                                         case "$deplib" in
317                                         */lib|*/lib/*)
318                                                 deplib="`echo $deplib | sed "s,/lib$,/$libsub,g; s,/lib/,/$libsub/,g"`"
319                                                 ;;
320                                         esac
321                                 fi
323                                 case "$deplib" in
324                                 *TOOLCHAIN*|*BACKUP*|*$SDECFG_ID*) ;;
325                                 *)
326                                         dlibtmp=$dlibsnew; var_remove dlibtmp ' ' "$deplib"
327                                         [ "$dlibtmp" = "$dlibsnew" ] && var_append dlibsnew ' ' "$deplib"
328                                         ;;
329                                 
330                                 esac
331                         done
333                         sed -i "s,^dependency_libs=.*,dependency_libs='$dlibsnew'," $root/$la
334                         dlibsnew=
335                 done
336         fi
339 postflist_fix_cross_scripts() {
340         grep 'bin/' $builddir/flist.txt |
341         while read f; do
342             if [ -f "$root/$f" ] && grep -qa '#!.*TOOLCHAIN/cross.*bin/' $root/$f; then
343                 echo_warning "Sed'ing TOOLCHAIN.*bin in $f"
344                 sed -i '1s,^#!.*TOOLCHAIN/cross.*bin/,#!/usr/bin/env -S ,' "$root/$f"
345             fi
346         done
349 # Parse the *.desc file. Use the description from PKG-DESC-FORMAT and
350 # save the tag data in $desc_*.
352 parse_desc() {
353     unset ${!desc_*}
355     tags="`sed -n '/^\[/ { s/][^]]*$//; s/. ./|/g; s/^\[//; p }' \
356           $base/misc/share/PKG-DESC-FORMAT`"
358     descs=$base/package/*/$1/$1.desc
359     [ -e $base/architecture/$arch/package/$1/$1.desc ] &&
360          var_append descs ' ' $base/architecture/$arch/package/$1/$1.desc
361     [ -e $base/target/$target/package/$pkg/$pkg.desc ] &&
362          var_append descs ' ' $base/target/$target/package/$1/$1.desc
364     for desc in $descs; do
365         #echo_status "Reading $desc ..."
366         for tag in $tags; do
367                 tagdata="`egrep -a "^\[($tag)\]" $desc |
368                           cut -f2- -d']' | sed 's,^ ,,'`"
369                 tag="`echo $tag | cut -f1 -d'|' | tr - _`"
370                 # only overwrite defined tags
371                 [ "$tagdata" ] && eval "desc_$tag=\"\$tagdata\""
372         done
373     done
375     ver="`echo "$desc_V" | tail -n 1 | cut -f1 -d' '`"
376     extraver="`echo "$desc_V" | tail -n 1 | cut -s -f2- -d' '`"
377     [ -z "$extraver" ] && extraver="${sdever//DEV-*/DEV}"
380 # This function is used for forcing a file to be in the flist
382 add_flist() {
383         for addfile; do
384                 echo "$addfile" | fl_wrparse -D -r "$xroot/" \
385                         >> $builddir/flist.txt
386         done
389 # This function is used for forcing a package to be in the dependency list
391 add_dependency() {
392         for addpackage; do
393                 echo "$addpackage: add_dependency()" \
394                         >> $builddir/dependencies.debug
395         done
398 # This function is used to subsitute some important variables
399 # using a D_ prefix thru m4 ...
400 sde_substitute() {
401         sed -e s,D_prefix,$prefix,g   -e s,D_sysconfdir,$sysconfdir,g \
402             -e s,D_docdir,$docdir,g   -e s,D_localstatedir,$localstatedir,g \
403             -e s,D_datadir,$datadir,g -e s,D_infodir,$infodir,g \
404             -e s,D_bindir,$bindir,g   -e s,D_sbindir,$sbindir,g \
405             -e s,D_libdir,$libdir,g   -e s,D_libexecdir,$libexecdir,g \
406             -e s,D_mandir,$mandir,g   -e s,D_includedir,$includedir,g \
407             -e s,D_ver,$ver,g $1
410 # This outputs a predefined config.cache file as it needed by some
411 # packages to cross-build correctly in stages 0 and 1.
413 create_config_cache() {
414         cat $base/scripts/config.cache
416         if [ $createarchcache -eq 1 ]; then
417                 cat <<-EOT
418                 # Architecture specific stuff\n"
419                 arch_sizeof_char=1
420                 ac_cv_sizeof_char=1
421                 ac_cv_sizeof_short=$arch_sizeof_short
422                 ac_cv_sizeof_int=$arch_sizeof_int
423                 ac_cv_sizeof_long=$arch_sizeof_long
424                 ac_cv_sizeof_long_long=$arch_sizeof_long_long
425                 ac_cv_sizeof_char_p=$arch_sizeof_char_p
426                 ac_cv_sizeof_void_p=$arch_sizeof_char_p
427                 ac_cv_c_bigendian=$arch_bigendian
429         fi
432 create_meson_cross() {
433         cat <<-EOT
434 [binaries]
435 c = '$CC'
436 cpp = '$CXX'
437 ar = '$AR'
438 strip = '$STRIP'
439 pkgconfig = 'pkg-config'
440 llvm-config = 'llvm-config'
441 cmake = 'cmake'
442 rust = [ 'rustc', '--target', '$rust_target' ]
444 [properties]
445 sizeof_int = $arch_sizeof_int
446 sizeof_wchar_t = $arch_sizeof_int
447 sizeof_void* = $arch_sizeof_char_p
448 alignment_char = 1
449 alignment_void* = $arch_sizeof_int
450 alignment_double = 4
451 has_function_printf = true
452 needs_exe_wrapper = true
454 [host_machine]
455 system = '$SDECFG_KERNEL'
456 cpu_family = '$(uname -m)'
457 cpu = '$arch' # or uname -m?
459 [ $arch_bigendian == "yes" ] && echo "endian = 'big'" || echo "endian = 'little'"
462 # Generate a CMake toolchain file for cross builds
464 create_cmake_toolchain_file() {
465         cat <<-EOT
466         SET(CMAKE_SYSTEM_NAME Linux)
467         SET(CMAKE_SYSTEM_VERSION 1)
468         SET(CMAKE_C_COMPILER $CC)
469         SET(CMAKE_CXX_COMPILER $CXX)
470         SET(CMAKE_FIND_ROOT_PATH $root)
471         SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
472         SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
473         SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
474         SET(PACKAGE_VENDOR "T2 SDE")
478 # Abort build before actual build starts
479 # (is overwritten in Build-Pkg)
481 abort() {
482         echo -e "The package build aborted with the following config" \
483              "error:\n$*" > $root/var/adm/logs/$stagelevel-$xpkg.err
484         echo_errorquote "$(< $root/var/adm/logs/$stagelevel-$xpkg.err)"
485         echo_pkg_abort $stagelevel $repository $xpkg
486         exit 1
489 # Dump Environment
491 dump_env() {
493         # Dump $base - only set if there is not already an older value.
494         #
495         echo "base=\"\${base:-$base}\""
497         # Dump all variables including their flags, but skip read-only
498         # variables and $base.
499         #
500         # Substitute base directory with ${base}.
501         #
502         for name in ${!a*} ${!b*} ${!c*} ${!d*} ${!e*} ${!f*} ${!g*} ${!h*} \
503                     ${!i*} ${!j*} ${!k*} ${!l*} ${!m*} ${!n*} ${!o*} ${!p*} \
504                     ${!q*} ${!r*} ${!s*} ${!t*} ${!u*} ${!v*} ${!w*} ${!x*} \
505                     ${!y*} ${!z*}                                           \
506                     ${!A*} ${!B*} ${!C*} ${!D*} ${!E*} ${!F*} ${!G*} ${!H*} \
507                     ${!I*} ${!J*} ${!K*} ${!L*} ${!M*} ${!N*} ${!O*} ${!P*} \
508                     ${!Q*} ${!R*} ${!S*} ${!T*} ${!U*} ${!V*} ${!W*} ${!X*} \
509                     ${!Y*} ${!Z*} ${!_*}
510         do
511                 [ $name = base -o $name = PWD ] && continue
512                 if declare -p $name | head -n 1 | grep -qv '^declare -[a-z]*r'
513                 then
514                         declare -p $name | sed "s,\\(^\\|[\"=:]\\)$base\\([\"=:/]\\|\$\\),\\1\${base}\\2,g"
515                 fi
516         done
518         # Dump functions
519         #
520         declare -f | sed 's/^declare -f //; s/<<(/< <(/;'
522         # Dump aliases
523         #
524         alias
527 # Estimate package build time based on binutils reference time and cached build time.
529 pkgbuildtime() {
530         local pkg="$1" buildtime
532         [ -e $base/build/$SDECFG_ID/TOOLCHAIN/reftime ] &&
533                 local reftime=$(< $base/build/$SDECFG_ID/TOOLCHAIN/reftime)
534         
535         [ -e $base/package/*/$pkg/$pkg.cache ] &&
536                 buildtime=$(sed -n "s/\[BUILDTIME\] \([^ ]*\).*/\1/p" $base/package/*/$pkg//$pkg.cache)
537         [ "$buildtime" = 0 ] && buildtime=1 # old quantizised to 0, or just fast: at least something
539         [ "$reftime" -a "$buildtime" ] &&
540                 gawk "BEGIN { parallel=.95; buildtime=$reftime * $buildtime / 100 / 100; \
541                         time = int(buildtime * (1-parallel) + buildtime * parallel / ${SDECFG_PARALLEL:-1}); \
542                         printf(\"%d\n\", time > 0 ? time : 1); }"
545 # Check if a package is already installed
547 # It does check the build-list if not in the rebuild stage - and
548 # the really installed package data for rebuilds (and so manual builds).
550 pkginstalled() {
551         # add optional dep, if not supressed with "-n"
552         [ "$1" == "-n" ] && shift || var_append desc_E $'\n' "opt $1"
554         if ! atstage rebuild; then
555                 local pattern="${1//+/\\+}"
556                 egrep -q "^X.* ($pattern) " $base/config/$config/packages && return
557         else
558                 [ -f $root/var/adm/packages/$1 ] && return
559         fi
561         [ -e $base/package/*/$1 ] ||
562                 echo_warning "Installed package checked: $1 does not exist"
563         
564         false
567 # pkgprefix [-t] [ <type> ] <package>
568 # Returns the prefix or the location of a 'type' of an already built package,
569 # or aborts the build if not yet installed.
570 # When run in the test mode [-t] it returns an error code accordingly.
572 pkgprefix() {
573         local type= pkg=
574         local dotest= abortmsg=
575         local prefix= value=
577         # -t : only see if it's possible to get the values
578         if [ "$1" = "-t" ]; then
579                 dotest=1; shift
580         fi
581         
582         if [ $# -eq 2 ]; then
583                 type="$1"; shift
584         fi
585         pkg="$1"
587         # test usual error causes
588         if [ -z "$pkg" ]; then
589                 abort "pkgprefix: you must specify a package"
590         elif [ ! -f "$root/var/adm/packages/$pkg" ]; then
591                 abortmsg="package $pkg is not present"
592         elif grep -q "^Prefix:" "$root/var/adm/packages/$pkg"; then
593                 prefix=$(grep "^Prefix: " "$root/var/adm/packages/$pkg" | cut -d' ' -f2-)
594         else
595                 abort "pkgprefix: $pkg record is to old (no Prefix: entry), please rebuild it."
596         fi
598         if [ "$dotest" ]; then
599                 # test mode: abort or continue
600                 if [ "$abortmsg" ]; then
601                         echo "pkgprefix: $abortmsg" 1>&2
602                         return 1
603                 else
604                         return 0
605                 fi
606         elif [ "$abortmsg" ]; then
607                 echo "pkgprefix: $abortmsg" 1>&2
608         elif [ -z "$type" -o "$type" = "prefix" ]; then
609                 echo "$prefix"
610                 return 0
611         elif [ "$type" = "ver" ]; then
612                 value=$(grep "^Package Name and Version:" "$root/var/adm/packages/$pkg" | cut -d' ' -f6)
613         else
614                 value=$(grep "^Location $type: " "$root/var/adm/packages/$pkg" | cut -d' ' -f3-)
615                 if [ -z "$value" ]; then
616                         # try default location for that $prefix
617                         value=$(xpkg="$pkg"; pkggetdir "$type")
618                 fi
619         fi
620         echo "${value:-PKGPREFIX_ERROR}"
623 # pkggetdir <type>     (needs $prefix and $xpkg)
624 # returns the location for the file of a 'type' considering it's prefix
626 pkggetdir() {
627         local xprefix=${prefix:+/$prefix}
628         case "$1" in
629                 bindir)  echo "$xprefix/bin"    ;;
630                 sbindir) echo "$xprefix/sbin"   ;;
631                 libdir)
632                   if atstage toolchain; then
633                         echo "$xprefix/lib"
634                   elif [ "$SDECFG_MULTILIB" = 1 ]; then
635                     case $arch_machine in
636                         powerpc64*|sparc64|loongarch64|mips64|riscv*|x86_64)
637                                 if [ "$SDECFG_X8664_X32" = 1 ]; then
638                                         echo "$xprefix/libx32"
639                                 elif [ "$SDECFG_MIPS64_N32" = 1 ]; then
640                                         echo "$xprefix/lib32"
641                                 else
642                                         echo "$xprefix/lib64"
643                                 fi
644                                 ;;
645                         *)
646                                 echo "$xprefix/lib"
647                                 ;;
648                     esac
649                   else
650                         echo "$xprefix/lib"
651                   fi
652                   ;;
653                 libexecdir) echo "${xprefix:-/usr}/libexec"     ;;
654                 datadir) echo "${xprefix:-/usr}/share"  ;;
655                 infodir) echo "${xprefix:-/usr}/info"   ;;
656                 mandir) echo "${xprefix:-/usr}/man"     ;;
657                 docdir) echo "${xprefix:-/usr}/doc/$xpkg"       ;;
658                 includedir) echo "${xprefix:-/usr}/include"     ;;
659                 sysconfdir) echo "/etc${xprefix##/usr*}"        ;;
660                 localstatedir) echo "/var${xprefix##/usr*}"     ;;
661         esac
665 # This function generates the T2 package checksum of $confdir.
666 # The checksum includes the filenames and content (except of the .cache),
667 # including subdirs but without whitespaces and comments and some tag lines
668 # that are not vital for rebuilds during update checks.
670 # pkgchksum package-name | full-patch
672 pkgchksum() {
673   (
674         local md5sum="md5sum"
675         if ! type -p $md5sum > /dev/null; then
676            md5sum="md5 -r"
677         fi
678         # expand to full path if only a package name was specified
679         [[ $1 == */* ]] || set $base/package/*/$1/
680         cd $1 || return 1
681         # find all files (without hidden (e.g. .svn) files)
682         find . ! -path '*/.*' ! -name '*.cache' -print -exec cat \{\} \; \
683         2>/dev/null |
684         # strip some unimportant stuff (e.g. comments, whitespaces, ...)
685         sed \
686         -e '/^[ ]*#.*/d' \
687         -e '/^\[COPY\]/d' \
688         -e '/^\[CV-*\]/d' \
689         -e '/^\[[T,I,U,A,M,L,S,C]\]/d' \
690         -e 's/[\t ]*//g' \
691         -e '/^ *$/d' |
692         $md5sum | cut -d ' ' -f 1
693   )
696 # Create Package Database for gasgui install tool
698 create_package_db() {
699         rm -f $3.tmp
700         for file in $(echo $1/descs/*); do
701                 [ -f "$file" ] || continue
702                 pkg="${file##*/}"
703                 # only include the package if a binary file is available
705                 if [ "$SDECFG_PKGFILE_VER" = 1 ]; then
706                         v=-$(grep '^Package Name and Version' \
707                                 $1/packages/$pkg | cut -f6 -d' ')
708                 else
709                         v=""
710                 fi
711                 bfile=${pkg}${v}.$SDECFG_PKGFILE_TYPE
713                 if [ -e $2/$bfile ]; then
714                         [ "$pkg" = TRANS.TBL ] && continue
715                         (
716                           echo -e "$pkg"
717                           echo -e "\027"
719                           cat $1/descs/$pkg | grep -v '\[COPY\]'
720                           echo -e "\027"
722                           cat $1/dependencies/$pkg
723                           echo -e "\027"
725                           cat $1/md5sums/$pkg
726                           echo -e "\027"
728                           echo -e "\004"
729                         ) >> $3.tmp
730                 else
731                         echo_error "Binary file for $bfile not present." \
732                                    "Skipped in package database."
733                 fi
734         done
735         gzip -c $3.tmp > $3; rm -f $3.tmp
738 # Add files to the 'badfiles' list
740 register_badfiles() {
741         local x desc="$1"
742         shift
744         for x in "$@"; do
745                 var_append badfiles $'\n' " $x\$"
746                 badfiles_desc[$badfiles_nr]=" $x\$"$'\n'"$desc"
747                 ((badfiles_nr++))
748         done
751 # Detect the available patchfiles
753 detect_patchfiles() {
754         local x= y=
755         patchfiles="`ls $confdir/*.patch{,.$arch,.$SDECFG_KERNEL} \
756                         $confdir/*.patch_$xpkg{.$arch,.$SDECFG_KERNEL} \
757                         2> /dev/null | tr '\n' ' '`"
759         atstage toolchain &&
760         var_append patchfiles ' ' "`ls $confdir/*.patch.cross0{,.$arch,.$SDECFG_KERNEL} \
761                                     2>/dev/null | tr '\n' ' '`"
762         atstage cross &&
763         var_append patchfiles ' ' "`ls $confdir/*.patch.cross{,.$arch,.$SDECFG_KERNEL} \
764                                     2>/dev/null | tr '\n' ' '`"
766         for x in $(get_reverted $targetchain); do
767                 for y in pkg_$pkg.patch{,.$arch,.$SDECFG_KERNEL} xpkg_$xpkg.patch{,.$arch,.$SDECFG_KERNEL}; do
768                         if [ -f $base/target/$x/$y ]; then
769                                 patchfiles="$patchfiles $base/target/$x/$y"
770                         fi
771                 done
772         done
774         # get additional patches from $targetdir/package/$pkg and architecture/package/$pkg -
775         # if it's not the confdir ie. contains the .desc file which overrides the default
776         for x in $targetdir/package/$pkg $base/architecture/$arch/package/$pkg; do
777                 if [ $confdir != $x ]; then
778                         var_append patchfiles ' ' "`ls $x/*.patch{,.$arch} 2> /dev/null | tr '\n' ' '`"
779                 fi
780         done
783 get_compressor() {
784         local x
785         case "$1" in
786         *.bz2|*.tbz2) x="bzip2 -d" ;;
787         *.gz|*.tgz) x="gzip -d" ;;
788         *.lz) x="lzip -d" ;;
789         *.lzma) x="lzma -d" ;;
790         *.xz|*.txz) x="xz -d" ;;
791         *.Z) x="compress -d" ;;
792         *.zst) x="zstd -d" ;;
793         *.br) x="brotli -d" ;;
794         esac
795         [ "$x" ] && echo "$x"
798 # Apply the given $patchfiles
799 # [ hook called for each patch ] [ filter script ]
801 apply_patchfiles() {
802         local hook="$1"
803         local filter="$2"
804         [ "$filter" ] || filter=cat
805         for x in $patchfiles; do
806                 # correct the absolute path, e.g. for patchfiles supplied in
807                 # the .desc file, we assume relative path patches are mirrorable
808                 if [ ! -e "$x" -a -n "${x##*/*}" ]; then
809                         x="$base/download/mirror/${x:0:1}/$x"
810                 fi
812                 echo "Applying $x"
813                 local compressor="$(get_compressor "$x")"
814                 if [ "$compressor" ]; then
815                         patch_file=`mktemp`
816                         $compressor < $x > $patch_file
817                 else
818                         patch_file=$x
819                 fi
821                 $filter $patch_file | patch $patchopt
823                 [ "$compressor" ] && rm $patch_file
824                 eval "$hook"
825         done
828 # -------------------------------------------------------------------
829 # The automatic extraction of archive (prior to building) supports
830 # multiple archive types. For every archive type we have a separate
831 # func that knows how to extract the archive. However, every func
832 # should deliver two file: untar.txt and xsrcdir.txt.
834 # untar.txt needs to contain all extracted files.
835 # xsrcdir.txt need to contain the top level extraction directories.
836 # -------------------------------------------------------------------
838 autoextract_tar() {
839         echo "Extracting $xsrctar ($taropt) ... "
840         tar -v $taropt $1 > untar.txt
843 autoextract_zip() {
844         echo "Extracting $xsrctar ($zipopt) ... "
845         unzip $zipopt $1 | sed -n '/: [a-z]/{s,.*: ,,p}' > untar.txt
848 autoextract_7z() {
849         echo "Extracting $xsrctar ($sevenzipopt) ... "
850         7z $sevenzipopt $1 | sed 's,/,,' | cut -f3 -d" " | grep -v "^$" > untar.txt
853 # Main program for building a package
855 build_this_package() {
856         if [ ".$desc_SRC" == "." ]; then
857                 # Autodetect source tar and extract it
858                 #
859                 if [ "$srctar" = auto ]; then
860                         xsourceballs=$(echo "$desc_D" | head -n 1 | sed 's, ,\t,g; s,\t\t*,\t,g' |
861                                 cut -f2)
862                         if [ -z "$xsourceballs" ]; then
863                                 echo "Can't auto-detect srctar for package '$xpkg'!"
864                                 false
865                         fi
866                 else
867                         xsourceballs="$srctar"
868                 fi
869         elif [ "$srctar" = auto ]; then
870                 sourceballs=$(echo "$desc_D" | sed 's, ,\t,g; s,\t\t*,\t,g' |
871                         cut -f2)
872                 xsrcpattern=$(echo "$desc_SRC" | sed 's, ,\t,g; s,\t\t*,\n,g')
873                 xsourceballs=$(echo "$sourceballs" | grep -F "$xsrcpattern")
874         else
875                 xsourceballs="$srctar"
876         fi
877         for xsrctar in $xsourceballs; do
878                 saved_patchfiles="$patchfiles"
879                 var_append patchfiles " " \
880                            "`ls $confdir/*.patch.${xsrctar/-[v0-9]*/} 2> /dev/null`"
881                 if [ "$xsrctar" != none -a "$autoextract" = 1 ]; then
882                         cd $builddir
883                         if [ -z "$custextract" ]; then
884                                 # No custom extraction, so determine what
885                                 # autoextraction to use.
886                                 case "$xsrctar" in
887                                 *.zip) custextract="autoextract_zip" ;;
888                                 *.7z) custextract="autoextract_7z" ;;
889                                 *) custextract="autoextract_tar" ;; # *.tar.bz2|*.tbz2|*.tbz
890                                 esac
891                         fi
892                         if [ -n "$custextract" ]; then
893                                 # Do the actual extraction of the archive.
894                                 eval "$custextract $archdir/$xsrctar"
895                                 sed 's,^\./,,; /^$/d' untar.txt | cut -f1 -d/ | sort -u > xsrcdir.txt
896                         fi
897                         #
898                         if [ "$srcdir" = auto ]; then
899                                 xsrcdir=${xsrctar%.tar.*}
900                                 xsrcdir=${xsrcdir%.t?z*}
901                                 if [ ! -d $xsrcdir ]; then
902                                         for x in $pkg-$ver ${pkg}_$ver $pkg \
903                                                  $xpkg-$ver ${xpkg}_$ver $xpkg \
904                                                  "$(cat xsrcdir.txt)"
905                                         do
906                                                 [ -d "$x" ] && xsrcdir="$x"
907                                         done
908                                 fi
909                         else
910                                 xsrcdir="$srcdir"
911                         fi
912                         #
913                         if [ "$chownsrcdir" = 1 ]; then
914                                 echo "Fixing ownership and permissions ..."
915                                 chown -R 0:0 $builddir/$xsrcdir
916                         fi
917                         #
918                         if [ "$nocvsinsrcdir" = 1 ]; then
919                                 echo "Removing CVS, .svn, {arch} and .arch-ids directories ..."
920                                 egrep '(^|/)(CVS|\.svn|\{arch\}|\.arch-ids)(/|$)' untar.txt |
921                                 while read x; do
922                                         echo "Removing $x ..."
923                                         rm -rf "$x"
924                                 done
925                         fi
926                         #
927                         echo "Changing into $builddir/$xsrcdir ..."
928                         cd $builddir/$xsrcdir
930                         # Apply patches
931                         #
932                         hook_eval prepatch
933                         [ $autopatch = 1 ] && apply_patchfiles
934                         hook_eval postpatch
936                 else
937                         cd $builddir
938                 fi
940                 if [ "$createprefix" = 1 ]; then
941                         echo "Creating $root/$prefix/<..> if required ..."
942                         for x in $foodirlist; do
943                                 eval "x=\"$root\$$x\""
944                                 if [ ! -e $x ]; then
945                                         mkdir -p $x
946                                         rmemptydir="$rmemptydir $x"
947                                 fi
948                         done
949                 fi
950                 
951                 if [ ".$custmain" = "." ]
952                 then
953                         hook_eval preconf
955                         # Maybe generate a configure first
956                         #
957                         if [ "$autogen" = 1 -o \
958                              \( -f configure.in -a ! -f configure -a "$autogen" != 0 \) ]; then
959                                 if [ -f autogen.sh ]; then
960                                         echo "Running package autogen script"
961                                         sed -i 's,.*/configure ,: # &,' autogen.sh
962                                         sh autogen.sh $(eval echo $confopt)
963                                 else
964                                         echo "Running builtin autogen script"
965                                         libtoolize --force --automake
966                                         aclocal $ACLOCAL_FLAGS
967                                         if grep AM_INIT_AUTOMAKE \
968                                            configure.[ia][nc]
969                                         then automake --add-missing; fi
970                                         autoconf
971                                 fi
972                         fi
973                         # Run configure scripts etc.
974                         #
975                         if [ "$runconf" = 1 ]; then
976                           if [ -n "$(type -p $configscript)" -o "$autogen" = 1 ]; then
977                                 eval_config_command $(eval echo $confopt)
978                           fi
979                         fi
981                         # CMake style
982                         #
983                         if [ "$runcmake" = 1 -a ! -f Makefile ] &&
984                            [ -e $cmakelists -o -e ../$cmakelists ]; then
985                                 if atstage cross; then
986                                         create_cmake_toolchain_file >> t2.cmake
987                                         var_insert cmakeopt " " "-DCMAKE_TOOLCHAIN_FILE=t2.cmake"
988                                 fi
990                                 # top-level CMakeLists?
991                                 [ ! -e $cmakelists ] && cmakelists="../$cmakelists"
993                                 # already ending with a directory?
994                                 [[ "$cmakeopt" = *. ]] || var_append cmakeopt ' ' "${cmakelists%%/*}"
996                                 eval echo "Running cmake $cmakeopt"
997                                 cmake $(eval echo $cmakeopt)
998                         fi
1000                         # Automated package build
1002                         # Styles without make run first:
1003                         if [ -f pyproject.toml -a "$rungpepinstall" = 1 ]; then
1004                                 hook_eval premake
1005                                 hook_eval inmake
1006                                 echo "Running gpep517 build-wheel --wheel-dir .dist --output-fd 3 3>&1 >&2"
1007                                 gpep517 build-wheel --wheel-dir .dist --output-fd 3 3>&1 >&2
1008                                 hook_eval postmake
1009                                 echo "Running python -m installer .dist/*.whl"
1010                                 python -m installer .dist/*.whl
1011                         elif [ -f setup.py -a "$runpysetup" = 1 ]; then
1012                                 pyconfopt="${pyconfopt:=--prefix $root/$prefix}"
1013                                 hook_eval premake
1014                                 eval echo "Running ${pyscript:-python} setup.py build install $pyconfopt"
1015                                 eval ${pyscript:-python} setup.py build install $pyconfopt
1016                                 hook_eval postmake
1017                         # for backwards compatibility, but users should REALLY use rungpepinstall instead
1018                         elif [ -f pyproject.toml -a "$runpipinstall" = 1 ]; then
1019                                 hook_eval premake
1020                                 eval echo "Running ${pyscript:-python} -m pip install ."
1021                                 eval ${pyscript:-python} -m pip install --break-system-packages .
1022                                 hook_eval postmake
1023                         elif [ -f meson.build -a "$runmeson" = 1 ]; then
1024                                 if atstage cross; then
1025                                         create_meson_cross >> cross.ini
1026                                         CC=cc CXX=c++ # make meson happy :-/
1027                                         var_append mesonopt " " "--cross-file cross.ini"
1028                                 fi
1029                                 hook_eval premake
1030                                 eval echo "Running meson $mesonopt"
1031                                 eval "meson $mesonopt"
1032                                 hook_eval inmake
1033                                 eval echo "Running ninja -C objs/ $ninjaopt install"
1034                                 atstage cross && export DESTDIR=$root
1035                                 ninja -C objs/ $ninjaopt install
1036                                 hook_eval postmake
1037                         elif [ -f build.ninja -a "$runninja" = 1 ]; then
1038                                 hook_eval premake
1039                                 eval echo "Running ninja $ninjaopt"
1040                                 ninja $ninjaopt
1041                                 hook_eval inmake
1042                                 eval echo "Running ninja $ninjaopt install"
1043                                 atstage cross && export DESTDIR=$root
1044                                 ninja $ninjaopt install
1045                                 hook_eval postmake
1046                         elif [ -f justfile -a "$runjust" = 1 ]; then
1047                                 hook_eval premake
1048                                 if [ "$justopt" ]; then
1049                                         eval echo "Running just $justopt"
1050                                         eval "just $justopt"
1051                                 fi
1052                                 hook_eval inmake
1053                                 if [ "$justinstopt" ]; then
1054                                         eval echo "Running just $justinstopt"
1055                                         eval "just $justinstopt"
1056                                 fi
1057                                 hook_eval postmake
1058                         elif [ -f Cargo.toml -a "$runcargo" = 1 ]; then
1059                                 hook_eval premake
1060                                 if [ "$cargoopt" -a ! "$cargoinstopt" ]; then
1061                                         eval echo "Running cargo $cargoopt"
1062                                         eval "cargo $cargoopt -j$SDECFG_PARALLEL"
1063                                 fi
1064                                 hook_eval inmake
1065                                 if [ "$cargoinstopt" ]; then
1066                                         eval echo "Running cargo $cargoinstopt"
1067                                         eval "cargo $cargoinstopt -j$SDECFG_PARALLEL"
1068                                 fi
1069                                 hook_eval postmake
1070                         elif [ -f SConstruct -a "$runscons" = 1 ]; then
1071                                 hook_eval premake
1072                                 if [ "$sconsopt" ]; then
1073                                         eval echo "Running scons $sconsopt"
1074                                         eval "scons $sconsopt"
1075                                 fi
1076                                 hook_eval inmake
1077                                 if [ "$sconsinstopt" ]; then
1078                                         eval echo "Running scons $sconsinstopt"
1079                                         eval "scons $sconsinstopt"
1080                                 fi
1081                                 hook_eval postmake
1082                         elif [ -f build.zig -a "$runzig" = 1 ]; then # some projects still use makefile
1083                                 hook_eval premake
1084                                 eval echo "Running zig build $zigconfopt"
1085                                 eval "zig build $zigconfopt"
1086                                 hook_eval inmake
1087                                 eval echo "Running zig build install $zigconfopt"
1088                                 eval "zig build install $zigconfopt"
1089                                 hook_eval postmake
1090                         elif [ -f go.mod -a "$rungo" = 1 ]; then # some projects still use makefile
1091                                 hook_eval premake
1092                                 eval echo "Running go build $goconfopt"
1093                                 eval "go build $goconfopt"
1094                                 hook_eval inmake
1095                                 #eval "go install" # No universal way to install?
1096                                 hook_eval postmake
1097                         elif [ -f META6.json -a "$runzef" = 1 ]; then
1098                                 hook_eval premake
1099                                 var_append zefopt " " "--force-install --/depends --/test-depends --/build-depends"
1100                                 var_append zefopt " " "--install-to=inst#$root/$prefix/share/perl6/site"
1101                                 hook_eval inmake
1102                                 eval echo "Running zef install . $zefopt"
1103                                 eval "zef install . $zefopt"
1104                         elif [ -f pom.xml -a "$runmaven" = 1 ]; then
1105                                 hook_eval premake
1106                                 eval echo "Running mvn build $mavenopt"
1107                                 eval "mvn build $mavenopt"
1108                                 hook_eval inmake
1109                                 eval echo "Running mvn install $maveninstopt"
1110                                 eval "mvn install $maveninstopt"
1111                                 hook_eval postmake
1112                                 hook_eval postmake
1113                         else # styles that include a make run
1114                                 if [ ! -f Makefile -a ! -f makefile -a \
1115                                      -f Makefile.PL -a "$runmkpl" = 1 ]; then
1116                                         echo "Running perl Makefile.PL ${plconfopt:-INSTALLDIRS=perl}"
1117                                         perl Makefile.PL ${plconfopt:-INSTALLDIRS=perl}
1118                                         if atstage cross; then
1119                                                 sed -i "s,/TOOLCHAIN/cross/usr/lib,$libdir,g" Makefile
1120                                                 sed -i "s,/TOOLCHAIN/cross,,g" Makefile
1121                                                 var_append makeopt ' ' 'PERL=perl FULLPERL=perl'
1122                                                 var_append makeinstopt ' ' 'PERL=perl FULLPERL=perl DESTDIR='
1123                                         fi
1124                                 fi
1125                                 #
1126                                 if [ ! -f Makefile -a ! -f makefile -a \
1127                                      -f Imakefile -a "$runxmkmf" = 1 ]; then
1128                                         echo "Running xmkmf -a"
1129                                         xmkmf -a
1130                                 fi
1131                                 #
1132                                 # Build it
1133                                 #
1134                                 hook_eval premake
1135                                 if [ "$runmake" = 1 -a "$makeopt" ]; then
1136                                         eval echo "Running $MAKE $makeopt"
1137                                         eval "$MAKE $makeopt"
1138                                 fi
1139                                 hook_eval inmake
1140                                 if [ "$runmake" = 1 -a "$makeinstopt" ]; then
1141                                         eval echo "Running $MAKE $makeinstopt"
1142                                         eval "$MAKE $makeinstopt"
1143                                 fi
1144                                 hook_eval postmake
1145                         fi
1146                 else
1147                         echo_warning "The use of custmain is deprecated, please use hooks instead."
1148                         eval "$custmain"
1149                         for x in preconf premake inmake postmake; do
1150                                 if eval "[ -n \"\$hookdirty_$x\" ]"; then
1151                                         echo "Hook $x is still marked as dirty running it, now ..."
1152                                         hook_eval $x
1153                                 fi
1154                         done
1155                 fi
1157                 if [ "$createdocs" != 0 ]; then
1158                         if [ ! -e $root$docdir ]; then
1159                                 mkdir -p $docdir
1160                                 rmemptydir="$rmemptydir $root$docdir"
1161                         fi
1162                         [ -z "$createdocs" ] && createdocs="$SDECFG_CREATE_DOCS"
1163                 fi
1165                 if [ "$createdocs" = 1 ]; then
1166                         echo "Trying to copy the default documentation ..."
1167                         for x in [A-Z][A-Z]* *.lsm ChangeLog*; do
1168                                 [ "${x#*.[cho0-9]}" ] || continue
1169                                 [ "${x#*.info*}"    ] || continue
1170                                 [ "${x#*.TAR*}"     ] || continue
1171                                 [ "${x#*akefile*}"  ] || continue
1172                                 [ -f $x ] && cp -v $x $root$docdir/$x
1173                         done
1175                         echo "Trying to copy even more documentation ..."
1176                         [ -d $builddir/$xsrcdir ] && cd $builddir/$xsrcdir
1177                         for x in `find -type d \( -name 'doc' -o -name 'docs' \
1178                                        -o -name '[Dd]ocumentation' \) ! -empty`
1179                         do
1180                                 if [ -d "$x" -a "`echo $x/*`" != "$x/*" ]
1181                                 then cp -rLv $x/* $root$docdir || true; fi
1182                         done
1183                         for x in $confdir/*.doc; do
1184                                 if [ -f $x ]
1185                                 then cp -v $x $root$docdir/${x%.doc}; fi
1186                         done
1187                         find $root$docdir/ -name '*.[0-9]' -o -name '*.info*' \
1188                                 -o -name '[Mm]akefile*' |
1189                                 xargs -r rm -f 2> /dev/null || true
1190                         find $root$docdir/* -type d -empty 2> /dev/null |
1191                                 xargs -r rmdir 2> /dev/null || true
1192                 fi
1194                 hook_eval postdoc
1195                 if atstage native && [ -f /sbin/ldconfig ]; then
1196                         echo "Running ldconfig"
1197                         ldconfig
1198                 fi
1199                 patchfiles="$saved_patchfiles"
1200         done
1201   
1202         if [ "$rmemptydir" ]; then
1203                 rmdir $rmemptydir 2> /dev/null || true
1204         fi
1206         return 0
1209 # source_file cksum file url
1211 # Create the file path from 'file' and 'url'.
1212 # cksum and url are ignored
1213 # ([D] tag compatible format)
1215 source_file() {
1216         local pre="" file="$2" url="$3" mirror="mirror"
1218         # '-' as $url prefix means, nomirrorable
1219         [ "${url:0:1}" == "-" ] && mirror="local"
1220         
1221         # inside Build-Pkg $archdir is set
1222         if [ -n "$archdir" ]; then
1223                 pre=$base/
1224         fi
1225     
1226         echo ${pre}download/${mirror}/${file:0:1}/$file
1229 # match_source_file [-p] pattern [[package] ...]
1231 # Returns path and name of a downloaded file from a list of packages, matching
1232 # a grep pattern. Without -p it only returns it's name, not the path.
1234 match_source_file() {
1235         local pattern= package= showpath=0
1236         local x= file= url= mirror=
1237         local found=1
1239         while [ "$1" ]; do
1240           case "$1" in
1241                 -p) showpath=1; shift ;;
1242                 *) break ;; # no abort as the pattern might start with a '-'
1243           esac
1244         done
1245         pattern="$1"; shift
1247         for package in ${*:-$pkg}; do
1248                 while read x x file url x; do
1249                         found=0
1251                         if [ $showpath -eq 0 ]; then
1252                                 echo $file
1253                         else
1254                                 [ "${url:0:1}" == "-" ] && mirror="local" || mirror="mirror"
1255                                 echo $base/download/${mirror}/${file:0:1}/$file
1256                         fi
1257                 done < <(for f in $base/target/$target/package/$package/$package.desc \
1258                                    $base/architecture/$arch/package/$package/$package.desc \
1259                                    $base/package/*/$package/$package.desc; do
1260                                 grep -a -e "^\[D\] [^ ]* .*$pattern" $f 2> /dev/null
1261                                 grep -q -a -e "^\[D\]" $f 2> /dev/null && break
1262                           done)
1263         done
1264         return $found
1267 # create the virtual $archdir symlinks
1269 populate_archdir() {
1270         local x= missing=0
1271         for x in `match_source_file -p .`; do
1272                 if [ ! -f $x ]; then
1273                         echo_warning "File not found: ${x#$base/}"
1274                         missing=1
1275                 elif [ ! -e "$builddir/archdir/${x##*/}" ]; then
1276                         ln -vs $x $builddir/archdir/
1277                 fi
1278         done
1279         if [ $missing -eq 1 ]; then
1280                 echo_warning "Did you run scripts/Download for this package?"
1281                 false
1282         fi
1285 # search for the package confdir
1287 detect_confdir() {
1288         confdir=
1289         for x in package/*/$pkg/$pkg.desc; do
1290                 [ -f "$x" ] || continue
1291                 if [ "$confdir" ]; then
1292                         echo_pkg_deny $stagelevel $pkg "in multiple trees"
1293                         echo "Package $pkg in multiple trees!" \
1294                           > $root/var/adm/logs/$stagelevel-$xpkg.err
1295                         exit 1
1296                 fi
1297                 x=${x#package/} x=${x%%/*}
1298                 confdir="$base/package/$x/$pkg"
1299                 repository=$x
1300         done
1302         if [ -e architecture/$arch/package/$pkg/$pkg.desc ]
1303         then confdir="$base/architecture/$arch/package/$pkg"; fi
1305         if [ -e $base/target/$target/package/$pkg/$pkg.desc ]
1306         then confdir="$base/target/$target/package/$pkg"; fi
1309 # initialize standard vars and hooks
1311 init_vars_and_hooks() {
1312         makeopt='CC="$CC" CPP="$CPP" CXX="$CXX"'
1313         sconsopt='CC=$CC PREFIX=/$prefix LIBDIR=$libdir'
1314         cargoopt='build'
1315         cargoinstopt='install --path . --root $root/$prefix --no-track --force' # -Z no-index-update
1316         goconfopt='-buildmode=pie -trimpath -mod=readonly'
1317         zigconfopt='--prefix $root/$prefix'
1318         justopt='prefix=/$prefix'
1320         # support both lowercase GNU and uppercase BSD conventions
1321         if atstage toolchain; then
1322                 makeopt="$makeopt"' prefix="$root/$prefix" PREFIX="$root/$prefix" docdir="$root$docdir"'
1323                 cmakeopt='-DCMAKE_INSTALL_PREFIX="$root/$prefix" -DCMAKE_INSTALL_LIBDIR="$root$libdir" -DCMAKE_LIBRARY_PATH="$root$libdir"'
1324         else
1325                 makeopt="$makeopt"' prefix="/$prefix" PREFIX="/$prefix" docdir="$docdir"'
1326                 cmakeopt='-DCMAKE_INSTALL_PREFIX="/$prefix" -DCMAKE_INSTALL_LIBDIR="$libdir" -DCMAKE_LIBRARY_PATH="$libdir"'
1327         fi
1329         if [ "$SDECFG_DEBUG" = 1 ]; then
1330                 var_append cargoinstopt ' ' '--debug'
1331                 var_append cmakeopt ' ' '-DCMAKE_BUILD_TYPE=Debug'
1332         else
1333                 var_append cargoopt ' ' '--release'
1334                 var_append cmakeopt ' ' '-DCMAKE_BUILD_TYPE=Release'
1335         fi
1337         if ! atstage native; then
1338                 makeopt="$makeopt"' CC_FOR_BUILD="$BUILDCC"'
1339                 makeopt="$makeopt"' BUILDCC="$BUILDCC" BUILD_CC="$BUILD_CC"'
1340                 makeopt="$makeopt"' HOSTCC="$HOSTCC"   HOST_CC="$HOST_CC"'
1341                 makeopt="$makeopt"' STRIP="$STRIP" AR="$AR" LD="$LD" AS="$AS"'
1342                 makeopt="$makeopt"' RANLIB="$RANLIB" NM="$NM"'
1343         fi
1345         if atstage native; then
1346                 flistdel="$flistdel|`echo $base | sed s,^/,,`/.*"
1347         fi
1349         if atstage cross; then
1350                 cmakeopt="$cmakeopt -DCMAKE_SYSTEM_PROCESSOR=$(echo $arch | arch2uname)"
1352                 # everyting non-DESTDIR is passed in the specific packages
1353                 makeinstopt="$makeopt"' DESTDIR="$root" install'
1354                 sconsinstopt='PREFIX=$root/$prefix LIBDIR=$root$libdir install'
1356                 cargoopt="$cargoopt"' --target ${arch_target}' # /-t2-/-unknown-}
1357                 cargoinstopt="$cargoinstopt"' --target ${arch_target}' # /-t2-/-unknown-}
1359                 justopt="$justopt"' root="$root"'
1360                 justinstopt="$justopt"' root="$root" install'
1361         else
1362                 makeinstopt="$makeopt"' install'
1363                 sconsinstopt="$sconsopt"' install'
1364                 justinstopt="$justopt"' install'
1365         fi
1367         atstage cross && hook_add postflist 2 'postflist_fix_cross_scripts'
1368         [ "$SDECFG_DO_CHECK" = 1 ] && hook_add inmake 6 'run_check'
1369         [ "$SDECFG_STATIC_IN_USR" = 1 ] && hook_add postflist 3 'postflist_static_lib'
1371         createarchcache=0
1373         custmain=""
1374         configprefix="" autogen=
1375         configscript="./configure" extraconfopt=""
1376         cmakelists="CMakeLists.txt"
1378         srcdir=auto srctar=auto
1379         taropt="-xf" # --use-compress-program=zstd
1380         sevenzipopt="x"
1382         mainfunction="build_this_package"
1383         runconf=1 runmake=1 runxmkmf=1 runmkpl=1 runpysetup=1 runpipinstall=0 rungpepinstall=1
1384         runcmake=1 runmaven=1 runmeson=1 runninja=1 runcargo=1 runjust=1 rungo=1 runscons=1 runzig=1
1385         runzef=1 autopatch=1 autoextract=1 chownsrcdir=1 nocvsinsrcdir=1 cleanconfopt=1
1386         patchopt="-bfp1 -z .orig"
1387         createprefix=1 createdocs="" rmemptydir=""
1389         check_shared=1
1390         check_usrlocal=1
1391         check_badfiles=1
1393         badfiles="" badfiles_nr=0
1394         declare -a badfiles_desc
1397 # this is a 2nd lightweight and modular "build this package" implementation
1398 # currently only used for the postlinux stuff - later maybe for more -ReneR
1400 build_package() {
1401   logstamp=$PWD/log
1402   (
1403         set -e
1404         pushd $base
1406         super=$pkg
1407         pkg="$1" xpkg="$pkg"
1408         [ "$2" ] && conffile="$2" || conffile="$pkg.conf"
1410         unset ${!hook*}
1411         declare -a hook_functions='()'
1412         hook_fcounter=0
1413         init_vars_and_hooks
1415         detect_confdir
1416         detect_patchfiles
1417         parse_desc $pkg
1419         # Erase positional parameters to prevent unintended current
1420         # arguments pssing to the loaded script.
1421         set --
1422         eval "$desc_O"
1424         echo_status "Building $xpkg within $super (using $conffile)"
1426         for x in $(get_expanded $base/target/%/pkg_$pkg.conf $targetchain) \
1427                 $targetdir/package/$pkg/$pkg.conf \
1428                 architecture/$arch/package/$pkg/$pkg.conf \
1429                 $confdir/$conffile; do
1430                 if [ -f $x ]; then
1431                         if [[ $x == */$conffile ]]; then
1432                                 echo "Reading package configuration ($conffile) from package directory."
1433                         else
1434                                 echo "Reading package configuration from $x."
1435                         fi
1436                         . $x
1437                         break
1438                 fi
1439         done
1441         # short path - to not abort on missing downloads of postlinux.conf
1442         # packages that are not built anyway -ReneR
1443         if [ "$custmain" = "true" ]; then
1444                 echo "Nothing is going to be done ayway - returning quickly."
1445                 return
1446         fi
1448         populate_archdir
1449         popd
1451         # dump for debugging
1452         hook_dump > $builddir/debug.hooks.$pkg
1453         dump_env > $builddir/debug.buildenv.$pkg
1455         echo "Running main build function '$mainfunction'"
1456         cd $builddir
1458         eval "$mainfunction"
1459         touch $logstamp
1460   )
1461   [ -f $logstamp ] || return 1
1462   rm $logstamp
1463   return 0