1 # --- T2-COPYRIGHT-NOTE-BEGIN ---
2 # T2 SDE: scripts/functions.in
3 # Copyright (C) 2004 - 2024 The T2 SDE Project
4 # Copyright (C) 1998 - 2003 ROCK Linux Project
6 # This Copyright note is generated by scripts/Create-CopyPatch,
7 # more information can be found in the files COPYING and README.
9 # This program is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License version 2.
11 # --- T2-COPYRIGHT-NOTE-END ---
13 . scripts/core-functions.in
15 # This function returns a "uniqe id" as output
18 date "+%y%m%d.%H%M%S.$$"
21 # this functions expands an string replacing % with all possible values
23 case "$BASH_VERSION" in # damn workaround for different syntax in both versions
26 local string="$1"; shift
27 while [ $# -gt 0 ]; do
28 echo "${string//\\%/$1}"
35 local string="$1"; shift
36 while [ $# -gt 0 ]; do
37 echo "${string//\%/$1}"
44 # atstage <stagename> ...
45 # returns true if the build is on a stage related to the given name
52 [ $stagelevel -gt 0 ] || return 0 ;;
54 [ $stagelevel -lt 1 -o $stagelevel -gt 2 ] || return 0 ;;
56 [ $stagelevel -ne 9 ] || return 0 ;;
58 [ $stagelevel -lt 3 ] || return 0 ;;
60 echo "atstage: '$x' stagename is not supported." >&2
70 local desc_F=" $desc_F " # surounding spaces for match below
72 [ "$arch_sizeof_char_p" = 4 ] && arch2=arch32 || arch2=arch64
73 [ "$desc_F" != "${desc_F/ $1 }" -o \
74 "$desc_F" != "${desc_F/ $1.$arch }" -o "$desc_F" != "${desc_F/ $1.$arch2 }" -o \
75 "$desc_F" != "${desc_F/ $1.$SDECFG_LIBC }" -o \
76 "$desc_F" != "${desc_F/ $1.$SDECFG_DEFAULT_CC }" ]
81 unset hook_functions hook_fcounter
82 declare -a hook_functions='()'
85 # This function adds a code fragment to a named hook with the named priority
87 # hook_add hook_name priority code
90 hook_functions[hook_fcounter]="$3" # declare -a hookidx_$1
91 eval "hookidx_$1[\${#hookidx_$1[@]}]=\"$2 $hook_fcounter\""
92 eval "((hookdirty_$1++))" || true; ((hook_fcounter++)) || true
95 # This function executes all code fragments from the named hook
100 while read pri fnr; do
101 [ "$pri" ] && eval "${hook_functions[fnr]}"
102 done < <(IFS=$'\n'; eval "echo \"\${hookidx_$1[*]}\"" | sort)
103 eval "unset hookdirty_$1"
106 # This function prints all hooks and their current contents
111 for hook in ${!hookidx_*}; do
112 hook=${hook#hookidx_}
113 echo; echo "Contents of hook $hook:"
115 while read pri fnr; do
116 echo; echo " $pri ($fnr)"
117 echo "${hook_functions[fnr]}" | sed 's,^, ,'
119 eval "echo \"\${hookidx_$hook[*]}\"" | sort)
120 if eval "[ -n \"\$hookdirty_\$hook\" ]"; then
121 echo; echo -n " Hook is marked as dirty: "
122 eval "echo \"\${hookdirty_$hook}\""
128 # This function can be used to duplicate a shell-function. E.g. when
129 # overwriting a shell-function but the old one should stay available under
132 # copy_function set_confopt set_confopt_foobar_old
136 # set_confopt_foobar_old "$@"
141 eval "$(declare -f $1 | sed "1 s,$1,$2,")"
146 # convert tabs to spaces, transform multiple consecutive spaces to one,
147 # remove leading and trailing spaces
149 sed 's,\t, ,g; s, *, ,g; s,^[ ]*,,; s,[ ]*$,,'
152 # This function sets the 'confopt' and some other variables.
153 # Re-run it in the package .conf file if you modify $prefix
159 if atstage toolchain; then
163 confopt="--prefix=$z/$prefix"
164 mesonopt="setup objs/ --prefix=$z/$prefix"
165 ninjaopt="-j$SDECFG_PARALLEL_MAX"
167 for x in bindir sbindir libdir libexecdir datadir includedir \
168 docdir infodir mandir sysconfdir localstatedir
171 eval "$x=`pkggetdir $x`"
172 # --bindir=$root\$bindir
173 if [ "$x" != libexecdir -a "$x" != docdir ]; then
174 confopt="$confopt --$x=$z\$$x"
175 mesonopt="$mesonopt --$x=$z\$$x"
179 export LIBSUFF=${libdir##*/lib}
181 if [ "$SDECFG_CONFIGURE_OPTS" ]; then
182 var_append confopt " " "$SDECFG_CONFIGURE_OPTS"
185 if [ "$SDECFG_DEBUG" = 0 ]; then
186 var_append confopt " " "--disable-debug"
189 if [ "$SDECFG_DISABLE_NLS" = 1 ]; then
190 var_remove confopt ' ' '--enable-nls'
191 var_append confopt ' ' '--disable-nls'
194 confopt="$confopt \$extraconfopt"
196 atstage cross && var_append confopt ' ' '--with-sysroot=$root'
197 if atstage toolchain; then
198 confopt="$confopt --target=\$arch_target --build=\$arch_build --host=\$arch_build"
200 confopt="$confopt --build=\$arch_build --host=\$arch_target"
205 # eval_config_command $(eval echo $confopt)
207 function eval_config_command() {
210 for x in /usr/share/automake/*; do
211 [ -x "$x" -a -f "$x" ] || continue
213 if [ -L $x -a ! -e $x ]; then
214 echo "Fixing dead symlink $x."
215 ln -sf /usr/share/automake/$x .
219 if atstage cross; then
220 create_config_cache >> config.cache
221 grep -q '.--cache-file=' $configscript &&
222 set -- "$@" "--cache-file=./config.cache"
223 export cache_file=config.cache
226 config_command="$configprefix $configscript"
227 sub_scripts="$(find $(dirname $configscript) -name configure)"
229 if [ "$cleanconfopt" == "0" ]; then
230 config_command="$config_command $@"
232 # remove unsupported config script options
234 if grep -q "[[ ]${x%%=*}[]= ):]" $configscript $sub_scripts; then
235 config_command="$config_command $x"
236 elif [[ $x = --*able-* ]] && egrep -q "\--(en|dis)able-\*" $configscript ||
237 [[ $x = --with* ]] && egrep -q "\--with(|out)-\*" $configscript; then
238 echo "Autodetection for option impossible: " \
240 config_command="$config_command $x"
242 echo "Removing unsupported '$x' from configure option string."
247 echo Running "$config_command"
248 eval "$config_command"
250 # the missing script is generally not very helpful, ...
251 if [ -f build/missing ]; then echo '#!/bin/true' > build/missing; fi
252 if [ -f missing ]; then echo '#!/bin/true' > missing; fi
255 # run 'make check' if Makefile supports it.
257 function run_check() {
258 if grep -q -e "^check:" Makefile; then
259 echo "Running make check"
262 if grep -q -e "^test:" Makefile; then
263 echo "Running make test"
268 # move the static libs from lib to usr/lib and correct the libdir used
269 # inside the .la file
271 postflist_static_lib() {
272 echo "Processing static lib corrections ..."
273 egrep '^(lib|lib64)/.*\.(a|la)$' $builddir/flist.txt |
275 [ -e $root/$fn -o -L $root/$fn ] || continue
276 if [[ $fn = *.a ]]; then
277 mv -fv $root/$fn $root/usr/$fn
279 sed "s,\([ =']\)/lib\(.*\),\1/usr/lib\2,g" \
280 $root/$fn > $root/usr/$fn
282 ln -svf ../../$so $root/usr/$so
283 add_flist $root/usr/$so
286 add_flist $root/usr/$fn
289 # this check might be removed in the future when we decide this is not
290 # an issue anymore ...
291 echo "Verifing the .la files ..."
292 defect_la="`egrep '(lib|lib64)/.*\.la$' $builddir/flist.txt |
293 xargs egrep 'dependency_libs=.*-pthread.*' |
294 cut -d : -f1 | sort -u | tr '\n' ' '`"
295 if [ "$defect_la" ]; then
296 abort "-pthread in: $defect_la!"
299 defect_la="`egrep '(lib|lib64)/.*\.la$' $builddir/flist.txt |
300 xargs egrep "dependency_libs=.*(TOOLCHAIN|BACKUP|$SDECFG_ID).*" |
301 cut -d : -f1 | sort -u | tr '\n' ' '`"
302 if [ "$defect_la" ]; then
304 echo_warning "Detected problems in following libtool files:"
305 for la in $defect_la; do
308 echo_warning "In absence of a proper fix (or replacement) for libtool and friends,"
309 echo_warning "for now the .la files are automatically corrected."
311 # Cleanup dependency_libs, remove build system path
312 local dependency_libs
315 local libsub=${libdir##*/}
316 for la in $defect_la; do
317 eval `grep ^dependency_libs= $root/$la`
319 for deplib in $dependency_libs; do
320 if [ $libsub != lib ]; then
323 deplib="`echo $deplib | sed "s,/lib$,/$libsub,g; s,/lib/,/$libsub/,g"`"
329 *TOOLCHAIN*|*BACKUP*|*$SDECFG_ID*) ;;
331 dlibtmp=$dlibsnew; var_remove dlibtmp ' ' "$deplib"
332 [ "$dlibtmp" = "$dlibsnew" ] && var_append dlibsnew ' ' "$deplib"
338 sed -i "s,^dependency_libs=.*,dependency_libs='$dlibsnew'," $root/$la
344 postflist_fix_cross_scripts() {
345 grep 'bin/' $builddir/flist.txt |
347 if [ -f "$root/$f" ] && grep -qa '#!.*TOOLCHAIN/cross.*bin/' $root/$f; then
348 echo_warning "Sed'ing TOOLCHAIN.*bin in $f"
349 sed -i '1s,^#!.*TOOLCHAIN/cross.*bin/,#!/usr/bin/env -S ,' "$root/$f"
354 # Parse the *.desc file. Use the description from PKG-DESC-FORMAT and
355 # save the tag data in $desc_*.
360 tags="`sed -n '/^\[/ { s/][^]]*$//; s/. ./|/g; s/^\[//; p }' \
361 $base/misc/share/PKG-DESC-FORMAT`"
363 descs=$base/package/*/$1/$1.desc
364 [ -e $base/architecture/$arch/package/$1/$1.desc ] &&
365 var_append descs ' ' $base/architecture/$arch/package/$1/$1.desc
366 [ -e $base/target/$target/package/$pkg/$pkg.desc ] &&
367 var_append descs ' ' $base/target/$target/package/$1/$1.desc
369 for desc in $descs; do
370 #echo_status "Reading $desc ..."
372 tagdata="`egrep -a "^\[($tag)\]" $desc |
373 cut -f2- -d']' | sed 's,^ ,,'`"
374 tag="`echo $tag | cut -f1 -d'|' | tr - _`"
375 # only overwrite defined tags
376 [ "$tagdata" ] && eval "desc_$tag=\"\$tagdata\""
380 ver="`echo "$desc_V" | tail -n 1 | cut -f1 -d' '`"
381 extraver="`echo "$desc_V" | tail -n 1 | cut -s -f2- -d' '`"
382 [ -z "$extraver" ] && extraver="${sdever//DEV-*/DEV}"
385 # This function is used for forcing a file to be in the flist
389 echo "$addfile" | fl_wrparse -D -r "$xroot/" \
390 >> $builddir/flist.txt
394 # This function is used for forcing a package to be in the dependency list
398 echo "$addpackage: add_dependency()" \
399 >> $builddir/dependencies.debug
403 # This function is used to subsitute some important variables
404 # using a D_ prefix thru m4 ...
406 sed -e s,D_prefix,$prefix,g -e s,D_sysconfdir,$sysconfdir,g \
407 -e s,D_docdir,$docdir,g -e s,D_localstatedir,$localstatedir,g \
408 -e s,D_datadir,$datadir,g -e s,D_infodir,$infodir,g \
409 -e s,D_bindir,$bindir,g -e s,D_sbindir,$sbindir,g \
410 -e s,D_libdir,$libdir,g -e s,D_libexecdir,$libexecdir,g \
411 -e s,D_mandir,$mandir,g -e s,D_includedir,$includedir,g \
415 # This outputs a predefined config.cache file as it needed by some
416 # packages to cross-build correctly in stages 0 and 1.
418 create_config_cache() {
419 cat $base/scripts/config.cache
421 if [ $createarchcache -eq 1 ]; then
423 # Architecture specific stuff\n"
426 ac_cv_sizeof_short=$arch_sizeof_short
427 ac_cv_sizeof_int=$arch_sizeof_int
428 ac_cv_sizeof_long=$arch_sizeof_long
429 ac_cv_sizeof_long_long=$arch_sizeof_long_long
430 ac_cv_sizeof_char_p=$arch_sizeof_char_p
431 ac_cv_sizeof_void_p=$arch_sizeof_char_p
432 ac_cv_c_bigendian=$arch_bigendian
437 create_meson_cross() {
444 pkgconfig = 'pkg-config'
445 llvm-config = 'llvm-config'
450 sizeof_int = $arch_sizeof_int
451 sizeof_wchar_t = $arch_sizeof_int
452 sizeof_void* = $arch_sizeof_char_p
454 alignment_void* = $arch_sizeof_int
456 has_function_printf = true
457 needs_exe_wrapper = true
460 system = '$SDECFG_KERNEL'
461 cpu_family = '$(uname -m)'
462 cpu = '$arch' # or uname -m?
464 [ $arch_bigendian == "yes" ] && echo "endian = 'big'" || echo "endian = 'little'"
467 # Generate a CMake toolchain file for cross builds
469 create_cmake_toolchain_file() {
471 SET(CMAKE_SYSTEM_NAME Linux)
472 SET(CMAKE_SYSTEM_VERSION 1)
473 SET(CMAKE_C_COMPILER $CC)
474 SET(CMAKE_CXX_COMPILER $CXX)
475 SET(CMAKE_FIND_ROOT_PATH $root)
476 SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
477 SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
478 SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
479 SET(PACKAGE_VENDOR "T2 SDE")
483 # Abort build before actual build starts
484 # (is overwritten in Build-Pkg)
487 echo -e "The package build aborted with the following config" \
488 "error:\n$*" > $root/var/adm/logs/$stagelevel-$xpkg.err
489 echo_errorquote "$(< $root/var/adm/logs/$stagelevel-$xpkg.err)"
490 echo_pkg_abort $stagelevel $repository $xpkg
498 # Dump $base - only set if there is not already an older value.
500 echo "base=\"\${base:-$base}\""
502 # Dump all variables including their flags, but skip read-only
503 # variables and $base.
505 # Substitute base directory with ${base}.
507 for name in ${!a*} ${!b*} ${!c*} ${!d*} ${!e*} ${!f*} ${!g*} ${!h*} \
508 ${!i*} ${!j*} ${!k*} ${!l*} ${!m*} ${!n*} ${!o*} ${!p*} \
509 ${!q*} ${!r*} ${!s*} ${!t*} ${!u*} ${!v*} ${!w*} ${!x*} \
511 ${!A*} ${!B*} ${!C*} ${!D*} ${!E*} ${!F*} ${!G*} ${!H*} \
512 ${!I*} ${!J*} ${!K*} ${!L*} ${!M*} ${!N*} ${!O*} ${!P*} \
513 ${!Q*} ${!R*} ${!S*} ${!T*} ${!U*} ${!V*} ${!W*} ${!X*} \
516 [ $name = base -o $name = PWD ] && continue
517 if declare -p $name | head -n 1 | grep -qv '^declare -[a-z]*r'
519 declare -p $name | sed "s,\\(^\\|[\"=:]\\)$base\\([\"=:/]\\|\$\\),\\1\${base}\\2,g"
525 declare -f | sed 's/^declare -f //; s/<<(/< <(/;'
532 # Estimate package build time based on binutils reference time and cached build time.
535 local pkg="$1" buildtime
537 [ -e $base/build/$SDECFG_ID/TOOLCHAIN/reftime ] &&
538 local reftime=$(< $base/build/$SDECFG_ID/TOOLCHAIN/reftime)
540 [ -e $base/package/*/$pkg/$pkg.cache ] &&
541 buildtime=$(sed -n "s/\[BUILDTIME\] \([^ ]*\).*/\1/p" $base/package/*/$pkg//$pkg.cache)
542 [ "$buildtime" = 0 ] && buildtime=1 # old quantizised to 0, or just fast: at least something
544 [ "$reftime" -a "$buildtime" ] &&
545 gawk "BEGIN { parallel=.95; buildtime=$reftime * $buildtime / 100 / 100; \
546 time = int(buildtime * (1-parallel) + buildtime * parallel / $SDECFG_PARALLEL_MAX); \
547 printf(\"%d\n\", time > 0 ? time : 1); }"
550 # Check if a package is already installed
552 # It does check the build-list if not in the rebuild stage - and
553 # the really installed package data for rebuilds (and so manual builds).
556 # add optional dep, if not supressed with "-n"
557 [ "$1" == "-n" ] && shift || var_append desc_E $'\n' "opt $1"
559 if ! atstage rebuild; then
560 local pattern="${1//+/\\+}"
561 egrep -q "^X.* ($pattern) " $base/config/$config/packages && return
563 [ -f $root/var/adm/packages/$1 ] && return
566 [ -e $base/package/*/$1 ] ||
567 echo_warning "Installed package checked: $1 does not exist"
572 # pkgprefix [-t] [ <type> ] <package>
573 # Returns the prefix or the location of a 'type' of an already built package,
574 # or aborts the build if not yet installed.
575 # When run in the test mode [-t] it returns an error code accordingly.
579 local dotest= abortmsg=
582 # -t : only see if it's possible to get the values
583 if [ "$1" = "-t" ]; then
587 if [ $# -eq 2 ]; then
592 # test usual error causes
593 if [ -z "$pkg" ]; then
594 abort "pkgprefix: you must specify a package"
595 elif [ ! -f "$root/var/adm/packages/$pkg" ]; then
596 abortmsg="package $pkg is not present"
597 elif grep -q "^Prefix:" "$root/var/adm/packages/$pkg"; then
598 prefix=$(grep "^Prefix: " "$root/var/adm/packages/$pkg" | cut -d' ' -f2-)
600 abort "pkgprefix: $pkg record is to old (no Prefix: entry), please rebuild it."
603 if [ "$dotest" ]; then
604 # test mode: abort or continue
605 if [ "$abortmsg" ]; then
606 echo "pkgprefix: $abortmsg" 1>&2
611 elif [ "$abortmsg" ]; then
612 echo "pkgprefix: $abortmsg" 1>&2
613 elif [ -z "$type" -o "$type" = "prefix" ]; then
616 elif [ "$type" = "ver" ]; then
617 value=$(grep "^Package Name and Version:" "$root/var/adm/packages/$pkg" | cut -d' ' -f6)
619 value=$(grep "^Location $type: " "$root/var/adm/packages/$pkg" | cut -d' ' -f3-)
620 if [ -z "$value" ]; then
621 # try default location for that $prefix
622 value=$(xpkg="$pkg"; pkggetdir "$type")
625 echo "${value:-PKGPREFIX_ERROR}"
628 # pkggetdir <type> (needs $prefix and $xpkg)
629 # returns the location for the file of a 'type' considering it's prefix
632 local xprefix=${prefix:+/$prefix}
634 bindir) echo "$xprefix/bin" ;;
635 sbindir) echo "$xprefix/sbin" ;;
637 if atstage toolchain; then
639 elif [ "$SDECFG_MULTILIB" = 1 ]; then
640 case $arch_machine in
641 powerpc64*|sparc64|loongarch64|mips64|riscv*|x86_64)
642 if [ "$SDECFG_X8664_X32" = 1 ]; then
643 echo "$xprefix/libx32"
644 elif [ "$SDECFG_MIPS64_N32" = 1 ]; then
645 echo "$xprefix/lib32"
647 echo "$xprefix/lib64"
658 libexecdir) echo "${xprefix:-/usr}/libexec" ;;
659 datadir) echo "${xprefix:-/usr}/share" ;;
660 infodir) echo "${xprefix:-/usr}/info" ;;
661 mandir) echo "${xprefix:-/usr}/man" ;;
662 docdir) echo "${xprefix:-/usr}/doc/$xpkg" ;;
663 includedir) echo "${xprefix:-/usr}/include" ;;
664 sysconfdir) echo "/etc${xprefix##/usr*}" ;;
665 localstatedir) echo "/var${xprefix##/usr*}" ;;
670 # This function generates the T2 package checksum of $confdir.
671 # The checksum includes the filenames and content (except of the .cache),
672 # including subdirs but without whitespaces and comments and some tag lines
673 # that are not vital for rebuilds during update checks.
675 # pkgchksum package-name | full-patch
679 local md5sum="md5sum"
680 if ! type -p $md5sum > /dev/null; then
683 # expand to full path if only a package name was specified
684 [[ $1 == */* ]] || set $base/package/*/$1/
686 # find all files (without hidden (e.g. .svn) files)
687 find . ! -path '*/.*' ! -name '*.cache' -print -exec cat \{\} \; \
689 # strip some unimportant stuff (e.g. comments, whitespaces, ...)
694 -e '/^\[[T,I,U,A,M,L,S,C]\]/d' \
697 $md5sum | cut -d ' ' -f 1
701 # Create Package Database for gasgui install tool
703 create_package_db() {
705 for file in $(echo $1/descs/*); do
706 [ -f "$file" ] || continue
708 # only include the package if a binary file is available
710 if [ "$SDECFG_PKGFILE_VER" = 1 ]; then
711 v=-$(grep '^Package Name and Version' \
712 $1/packages/$pkg | cut -f6 -d' ')
716 bfile=${pkg}${v}.$SDECFG_PKGFILE_TYPE
718 if [ -e $2/$bfile ]; then
719 [ "$pkg" = TRANS.TBL ] && continue
724 cat $1/descs/$pkg | grep -v '\[COPY\]'
727 cat $1/dependencies/$pkg
736 echo_error "Binary file for $bfile not present." \
737 "Skipped in package database."
740 gzip -c $3.tmp > $3; rm -f $3.tmp
743 # Add files to the 'badfiles' list
745 register_badfiles() {
750 var_append badfiles $'\n' " $x\$"
751 badfiles_desc[$badfiles_nr]=" $x\$"$'\n'"$desc"
756 # Detect the available patchfiles
758 detect_patchfiles() {
760 patchfiles="`ls $confdir/*.patch{,.$arch,.$SDECFG_KERNEL} \
761 $confdir/*.patch_$xpkg{.$arch,.$SDECFG_KERNEL} \
762 2> /dev/null | tr '\n' ' '`"
765 var_append patchfiles ' ' "`ls $confdir/*.patch.cross0{,.$arch,.$SDECFG_KERNEL} \
766 2>/dev/null | tr '\n' ' '`"
768 var_append patchfiles ' ' "`ls $confdir/*.patch.cross{,.$arch,.$SDECFG_KERNEL} \
769 2>/dev/null | tr '\n' ' '`"
771 for x in $(get_reverted $targetchain); do
772 for y in pkg_$pkg.patch{,.$arch,.$SDECFG_KERNEL} xpkg_$xpkg.patch{,.$arch,.$SDECFG_KERNEL}; do
773 if [ -f $base/target/$x/$y ]; then
774 patchfiles="$patchfiles $base/target/$x/$y"
779 # get additional patches from $targetdir/package/$pkg and architecture/package/$pkg -
780 # if it's not the confdir ie. contains the .desc file which overrides the default
781 for x in $targetdir/package/$pkg $base/architecture/$arch/package/$pkg; do
782 if [ $confdir != $x ]; then
783 var_append patchfiles ' ' "`ls $x/*.patch{,.$arch} 2> /dev/null | tr '\n' ' '`"
791 *.bz2|*.tbz2) x="bzip2 -d" ;;
792 *.gz|*.tgz) x="gzip -d" ;;
794 *.lzma) x="lzma -d" ;;
795 *.xz|*.txz) x="xz -d" ;;
796 *.Z) x="compress -d" ;;
797 *.zst) x="zstd -d" ;;
798 *.br) x="brotli -d" ;;
800 [ "$x" ] && echo "$x"
803 # Apply the given $patchfiles
804 # [ hook called for each patch ] [ filter script ]
809 [ "$filter" ] || filter=cat
810 for x in $patchfiles; do
811 # correct the absolute path, e.g. for patchfiles supplied in
812 # the .desc file, we assume relative path patches are mirrorable
813 if [ ! -e "$x" -a -n "${x##*/*}" ]; then
814 x="$base/download/mirror/${x:0:1}/$x"
818 local compressor="$(get_compressor "$x")"
819 if [ "$compressor" ]; then
821 $compressor < $x > $patch_file
826 $filter $patch_file | patch $patchopt
828 [ "$compressor" ] && rm $patch_file
833 # -------------------------------------------------------------------
834 # The automatic extraction of archive (prior to building) supports
835 # multiple archive types. For every archive type we have a separate
836 # func that knows how to extract the archive. However, every func
837 # should deliver two file: untar.txt and xsrcdir.txt.
839 # untar.txt needs to contain all extracted files.
840 # xsrcdir.txt need to contain the top level extraction directories.
841 # -------------------------------------------------------------------
844 echo "Extracting $xsrctar ($taropt) ... "
845 tar -v $taropt $1 > untar.txt
849 echo "Extracting $xsrctar ($zipopt) ... "
850 unzip $zipopt $1 | sed 's,^.*/$,,' |
851 cut -f4 -d" " | grep -v "^$" > untar.txt
855 echo "Extracting $xsrctar ($sevenzipopt) ... "
856 7za $sevenzipopt $1 | sed 's,/,,' |
857 cut -f3 -d" " | grep -v "^$" > untar.txt
860 # Main program for building a package
862 build_this_package() {
863 if [ ".$desc_SRC" == "." ]; then
864 # Autodetect source tar and extract it
866 if [ "$srctar" = auto ]; then
867 xsourceballs=$(echo "$desc_D" | head -n 1 | sed 's, ,\t,g; s,\t\t*,\t,g' |
869 if [ -z "$xsourceballs" ]; then
870 echo "Can't auto-detect srctar for package '$xpkg'!"
874 xsourceballs="$srctar"
876 elif [ "$srctar" = auto ]; then
877 sourceballs=$(echo "$desc_D" | sed 's, ,\t,g; s,\t\t*,\t,g' |
879 xsrcpattern=$(echo "$desc_SRC" | sed 's, ,\t,g; s,\t\t*,\n,g')
880 xsourceballs=$(echo "$sourceballs" | grep -F "$xsrcpattern")
882 xsourceballs="$srctar"
884 for xsrctar in $xsourceballs; do
885 saved_patchfiles="$patchfiles"
886 var_append patchfiles " " \
887 "`ls $confdir/*.patch.${xsrctar/-[v0-9]*/} 2> /dev/null`"
888 if [ "$xsrctar" != none -a "$autoextract" = 1 ]; then
890 if [ -z "$custextract" ]; then
891 # No custom extraction, so determine what
892 # autoextraction to use.
894 *.zip) custextract="autoextract_zip" ;;
895 *.7z) custextract="autoextract_7z" ;;
896 *) custextract="autoextract_tar" ;; # *.tar.bz2|*.tbz2|*.tbz
899 if [ -n "$custextract" ]; then
900 # Do the actual extraction of the archive.
901 eval "$custextract $archdir/$xsrctar"
902 sed 's,^\./,,; /^$/d' untar.txt | cut -f1 -d/ | sort -u > xsrcdir.txt
905 if [ "$srcdir" = auto ]; then
906 xsrcdir=${xsrctar%.tar.*}
907 xsrcdir=${xsrcdir%.t?z*}
908 if [ ! -d $xsrcdir ]; then
909 for x in $pkg-$ver ${pkg}_$ver $pkg \
910 $xpkg-$ver ${xpkg}_$ver $xpkg \
913 [ -d "$x" ] && xsrcdir="$x"
920 if [ "$chownsrcdir" = 1 ]; then
921 echo "Fixing ownership and permissions ..."
922 chown -R 0:0 $builddir/$xsrcdir
925 if [ "$nocvsinsrcdir" = 1 ]; then
926 echo "Removing CVS, .svn, {arch} and .arch-ids directories ..."
927 egrep '(^|/)(CVS|\.svn|\{arch\}|\.arch-ids)(/|$)' untar.txt |
929 echo "Removing $x ..."
934 echo "Changeing into $builddir/$xsrcdir ..."
935 cd $builddir/$xsrcdir
940 [ $autopatch = 1 ] && apply_patchfiles
947 if [ "$createprefix" = 1 ]; then
948 echo "Creating $root/$prefix/<..> if required ..."
949 for x in $foodirlist; do
950 eval "x=\"$root\$$x\""
953 rmemptydir="$rmemptydir $x"
958 if [ ".$custmain" = "." ]
962 # Maybe generate a configure first
964 if [ "$autogen" = 1 -o \
965 \( -f configure.in -a ! -f configure -a "$autogen" != 0 \) ]; then
966 if [ -f autogen.sh ]; then
967 echo "Running package autogen script"
968 sed -i 's,.*/configure ,: # &,' autogen.sh
969 sh autogen.sh $(eval echo $confopt)
971 echo "Running builtin autogen script"
972 libtoolize --force --automake
973 aclocal $ACLOCAL_FLAGS
974 if grep AM_INIT_AUTOMAKE \
976 then automake --add-missing; fi
980 # Run configure scripts etc.
982 if [ "$runconf" = 1 ]; then
983 if [ -n "$(type -p $configscript)" -o "$autogen" = 1 ]; then
984 eval_config_command $(eval echo $confopt)
990 if [ "$runcmake" = 1 -a ! -f Makefile ] &&
991 [ -e $cmakelists -o -e ../$cmakelists ]; then
992 if atstage cross; then
993 create_cmake_toolchain_file >> t2.cmake
994 var_insert cmakeopt " " "-DCMAKE_TOOLCHAIN_FILE=t2.cmake"
997 # top-level CMakeLists?
998 [ ! -e $cmakelists ] && cmakelists="../$cmakelists"
1000 # already ending with a directory?
1001 [[ "$cmakeopt" = *. ]] || var_append cmakeopt ' ' "${cmakelists%%/*}"
1003 eval echo "Running cmake $cmakeopt"
1004 cmake $(eval echo $cmakeopt)
1007 # Automated package build
1009 # Styles without make run first:
1010 if [ -f pyproject.toml -a "$rungpepinstall" = 1 ]; then
1013 echo "Running gpep517 build-wheel --wheel-dir .dist --output-fd 3 3>&1 >&2"
1014 gpep517 build-wheel --wheel-dir .dist --output-fd 3 3>&1 >&2
1016 echo "Running python -m installer .dist/*.whl"
1017 python -m installer .dist/*.whl
1018 elif [ -f setup.py -a "$runpysetup" = 1 ]; then
1019 pyconfopt="${pyconfopt:=--prefix $root/$prefix}"
1021 eval echo "Running ${pyscript:-python} setup.py build install $pyconfopt"
1022 eval ${pyscript:-python} setup.py build install $pyconfopt
1024 # for backwards compatibility, but users should REALLY use rungpepinstall instead
1025 elif [ -f pyproject.toml -a "$runpipinstall" = 1 ]; then
1027 eval echo "Running ${pyscript:-python} -m pip install ."
1028 eval ${pyscript:-python} -m pip install --break-system-packages .
1030 elif [ -f meson.build -a "$runmeson" = 1 ]; then
1031 if atstage cross; then
1032 create_meson_cross >> cross.ini
1033 CC=cc CXX=c++ # make meson happy :-/
1034 var_append mesonopt " " "--cross-file cross.ini"
1037 eval echo "Running meson $mesonopt"
1038 eval "meson $mesonopt"
1040 eval echo "Running ninja -C objs/ $ninjaopt install"
1041 atstage cross && export DESTDIR=$root
1042 ninja -C objs/ $ninjaopt install
1044 elif [ -f build.ninja -a "$runninja" = 1 ]; then
1046 eval echo "Running ninja $ninjaopt"
1049 eval echo "Running ninja $ninjaopt install"
1050 atstage cross && export DESTDIR=$root
1051 ninja $ninjaopt install
1053 elif [ -f Cargo.toml -a "$runcargo" = 1 ]; then
1055 if [ "$cargoopt" -a ! "$cargoinstopt" ]; then
1056 eval echo "Running cargo $cargoopt"
1057 eval "cargo $cargoopt -j$SDECFG_PARALLEL_MAX"
1060 if [ "$cargoinstopt" ]; then
1061 eval echo "Running cargo $cargoinstopt"
1062 eval "cargo $cargoinstopt -j$SDECFG_PARALLEL_MAX"
1065 elif [ -f SConstruct -a "$runscons" = 1 ]; then
1067 if [ "$sconsopt" ]; then
1068 eval echo "Running scons $sconsopt"
1069 eval "scons $sconsopt"
1072 if [ "$sconsinstopt" ]; then
1073 eval echo "Running scons $sconsinstopt"
1074 eval "scons $sconsinstopt"
1077 elif [ -f build.zig -a "$runzig" = 1 ]; then # some projects still use makefile
1079 zigconfopt="${zigconfopt:=--prefix $root/$prefix}"
1080 eval echo "Running zig build $zigconfopt"
1081 eval "zig build $zigconfopt"
1083 eval echo "Running zig build install"
1084 eval "zig build install"
1086 elif [ -f go.mod -a "$rungo" = 1 ]; then # some projects still use makefile
1088 eval echo "Running go build $goconfopt"
1089 eval "go build $goconfopt"
1091 #eval "go install" # No universal way to install?
1093 elif [ -f META6.json -a "$runzef" = 1 ]; then
1095 var_append zefopt " " "--force-install --/depends --/test-depends --/build-depends"
1096 var_append zefopt " " "--install-to=inst#$root/$prefix/share/perl6/site"
1098 eval echo "Running zef install . $zefopt"
1099 eval "zef install . $zefopt"
1101 else # styles that include a make run
1102 if [ ! -f Makefile -a ! -f makefile -a \
1103 -f Makefile.PL -a "$runmkpl" = 1 ]; then
1104 echo "Running perl Makefile.PL ${plconfopt:-INSTALLDIRS=perl}"
1105 perl Makefile.PL ${plconfopt:-INSTALLDIRS=perl}
1106 if atstage cross; then
1107 sed -i "s,/TOOLCHAIN/cross/usr/lib,$libdir,g" Makefile
1108 sed -i "s,/TOOLCHAIN/cross,,g" Makefile
1109 var_append makeopt ' ' 'PERL=perl FULLPERL=perl'
1110 var_append makeinstopt ' ' 'PERL=perl FULLPERL=perl DESTDIR='
1114 if [ ! -f Makefile -a ! -f makefile -a \
1115 -f Imakefile -a "$runxmkmf" = 1 ]; then
1116 echo "Running xmkmf -a"
1123 if [ "$runmake" = 1 -a "$makeopt" ]; then
1124 eval echo "Running $MAKE $makeopt"
1125 eval "$MAKE $makeopt"
1128 if [ "$runmake" = 1 -a "$makeinstopt" ]; then
1129 eval echo "Running $MAKE $makeinstopt"
1130 eval "$MAKE $makeinstopt"
1135 echo_warning "The use of custmain is deprecated, please use hooks instead."
1137 for x in preconf premake inmake postmake; do
1138 if eval "[ -n \"\$hookdirty_$x\" ]"; then
1139 echo "Hook $x is still marked as dirty running it, now ..."
1145 if [ "$createdocs" != 0 ]; then
1146 if [ ! -e $root$docdir ]; then
1148 rmemptydir="$rmemptydir $root$docdir"
1150 [ -z "$createdocs" ] && createdocs="$SDECFG_CREATE_DOCS"
1153 if [ "$createdocs" = 1 ]; then
1154 echo "Trying to copy the default documentation ..."
1155 for x in [A-Z][A-Z]* *.lsm ChangeLog*; do
1156 [ "${x#*.[cho0-9]}" ] || continue
1157 [ "${x#*.info*}" ] || continue
1158 [ "${x#*.TAR*}" ] || continue
1159 [ "${x#*akefile*}" ] || continue
1160 [ -f $x ] && cp -v $x $root$docdir/$x
1163 echo "Trying to copy even more documentation ..."
1164 [ -d $builddir/$xsrcdir ] && cd $builddir/$xsrcdir
1165 for x in `find -type d \( -name 'doc' -o -name 'docs' \
1166 -o -name '[Dd]ocumentation' \) ! -empty`
1168 if [ -d "$x" -a "`echo $x/*`" != "$x/*" ]
1169 then cp -rLv $x/* $root$docdir || true; fi
1171 for x in $confdir/*.doc; do
1173 then cp -v $x $root$docdir/${x%.doc}; fi
1175 find $root$docdir/ -name '*.[0-9]' -o -name '*.info*' \
1176 -o -name '[Mm]akefile*' |
1177 xargs -r rm -f 2> /dev/null || true
1178 find $root$docdir/* -type d -empty 2> /dev/null |
1179 xargs -r rmdir 2> /dev/null || true
1183 if atstage native && [ -f /sbin/ldconfig ]; then
1184 echo "Running ldconfig"
1187 patchfiles="$saved_patchfiles"
1190 if [ "$rmemptydir" ]; then
1191 rmdir $rmemptydir 2> /dev/null || true
1197 # source_file cksum file url
1199 # Create the file path from 'file' and 'url'.
1200 # cksum and url are ignored
1201 # ([D] tag compatible format)
1204 local pre="" file="$2" url="$3" mirror="mirror"
1206 # '-' as $url prefix means, nomirrorable
1207 [ "${url:0:1}" == "-" ] && mirror="local"
1209 # inside Build-Pkg $archdir is set
1210 if [ -n "$archdir" ]; then
1214 echo ${pre}download/${mirror}/${file:0:1}/$file
1217 # match_source_file [-p] pattern [[package] ...]
1219 # Returns path and name of a downloaded file from a list of packages, matching
1220 # a grep pattern. Without -p it only returns it's name, not the path.
1222 match_source_file() {
1223 local pattern= package= showpath=0
1224 local x= file= url= mirror=
1229 -p) showpath=1; shift ;;
1230 *) break ;; # no abort as the pattern might start with a '-'
1235 for package in ${*:-$pkg}; do
1236 while read x x file url x; do
1239 if [ $showpath -eq 0 ]; then
1242 [ "${url:0:1}" == "-" ] && mirror="local" || mirror="mirror"
1243 echo $base/download/${mirror}/${file:0:1}/$file
1245 done < <(for f in $base/target/$target/package/$package/$package.desc \
1246 $base/architecture/$arch/package/$package/$package.desc \
1247 $base/package/*/$package/$package.desc; do
1248 grep -a -e "^\[D\] [^ ]* .*$pattern" $f 2> /dev/null
1249 grep -q -a -e "^\[D\]" $f 2> /dev/null && break
1255 # create the virtual $archdir symlinks
1257 populate_archdir() {
1259 for x in `match_source_file -p .`; do
1260 if [ ! -f $x ]; then
1261 echo_warning "File not found: ${x#$base/}"
1263 elif [ ! -e "$builddir/archdir/${x##*/}" ]; then
1264 ln -vs $x $builddir/archdir/
1267 if [ $missing -eq 1 ]; then
1268 echo_warning "Did you run scripts/Download for this package?"
1273 # search for the package confdir
1277 for x in package/*/$pkg/$pkg.desc; do
1278 [ -f "$x" ] || continue
1279 if [ "$confdir" ]; then
1280 echo_pkg_deny $stagelevel $pkg "in multiple trees"
1281 echo "Package $pkg in multiple trees!" \
1282 > $root/var/adm/logs/$stagelevel-$xpkg.err
1285 x=${x#package/} x=${x%%/*}
1286 confdir="$base/package/$x/$pkg"
1290 if [ -e architecture/$arch/package/$pkg/$pkg.desc ]
1291 then confdir="$base/architecture/$arch/package/$pkg"; fi
1293 if [ -e $base/target/$target/package/$pkg/$pkg.desc ]
1294 then confdir="$base/target/$target/package/$pkg"; fi
1297 # initialize standard vars and hooks
1299 init_vars_and_hooks() {
1300 makeopt='CC="$CC" CPP="$CPP" CXX="$CXX"'
1301 sconsopt='CC=$CC PREFIX=/$prefix LIBDIR=$libdir'
1303 cargoinstopt='install --path . --root $root/$prefix --no-track --force' # -Z no-index-update
1304 goconfopt='-buildmode=pie -trimpath -mod=readonly -ldflags=-linkmode=external'
1306 # support both lowercase GNU and uppercase BSD conventions
1307 if atstage toolchain; then
1308 makeopt="$makeopt"' prefix="$root/$prefix" PREFIX="$root/$prefix" docdir="$root$docdir"'
1309 cmakeopt='-DCMAKE_INSTALL_PREFIX="$root/$prefix" -DCMAKE_INSTALL_LIBDIR="$root$libdir" -DCMAKE_LIBRARY_PATH="$root$libdir"'
1311 makeopt="$makeopt"' prefix="/$prefix" PREFIX="/$prefix" docdir="$docdir"'
1312 cmakeopt='-DCMAKE_INSTALL_PREFIX="/$prefix" -DCMAKE_INSTALL_LIBDIR="$libdir" -DCMAKE_LIBRARY_PATH="$libdir"'
1315 if [ "$SDECFG_DEBUG" = 1 ]; then
1316 var_append cargoinstopt ' ' '--debug'
1317 var_append cmakeopt ' ' '-DCMAKE_BUILD_TYPE=Debug'
1319 var_append cargoopt ' ' '--release'
1320 var_append cmakeopt ' ' '-DCMAKE_BUILD_TYPE=Release'
1323 if ! atstage native; then
1324 makeopt="$makeopt"' CC_FOR_BUILD="$BUILDCC"'
1325 makeopt="$makeopt"' BUILDCC="$BUILDCC" BUILD_CC="$BUILD_CC"'
1326 makeopt="$makeopt"' HOSTCC="$HOSTCC" HOST_CC="$HOST_CC"'
1327 makeopt="$makeopt"' STRIP="$STRIP" AR="$AR" LD="$LD" AS="$AS"'
1328 makeopt="$makeopt"' RANLIB="$RANLIB" NM="$NM"'
1331 if atstage native; then
1332 flistdel="$flistdel|`echo $base | sed s,^/,,`/.*"
1335 if atstage cross; then
1336 cmakeopt="$cmakeopt -DCMAKE_SYSTEM_PROCESSOR=$(echo $arch | arch2uname)"
1338 # everyting non-DESTDIR is passed in the specific packages
1339 makeinstopt="$makeopt"' DESTDIR="$root" install'
1340 sconsinstopt='PREFIX=$root/$prefix LIBDIR=$root$libdir install'
1342 cargoopt="$cargoopt"' --target ${arch_target}' # /-t2-/-unknown-}
1343 cargoinstopt="$cargoinstopt"' --target ${arch_target}' # /-t2-/-unknown-}
1345 makeinstopt="$makeopt"' install'
1346 sconsinstopt="$sconsopt"' install'
1349 atstage cross && hook_add postflist 2 'postflist_fix_cross_scripts'
1350 [ "$SDECFG_DO_CHECK" = 1 ] && hook_add inmake 6 'run_check'
1351 [ "$SDECFG_STATIC_IN_USR" = 1 ] && hook_add postflist 3 'postflist_static_lib'
1356 configprefix="" autogen=
1357 configscript="./configure" extraconfopt=""
1358 cmakelists="CMakeLists.txt"
1360 srcdir=auto srctar=auto
1361 taropt="-xf" # --use-compress-program=zstd
1364 mainfunction="build_this_package"
1365 runconf=1 runmake=1 runxmkmf=1 runmkpl=1 runpysetup=1 runpipinstall=0 rungpepinstall=1
1366 runcmake=1 runmeson=1 runninja=1 runcargo=1 rungo=1 runscons=1 runzig=1 runzef=1
1367 autopatch=1 autoextract=1 chownsrcdir=1 nocvsinsrcdir=1 cleanconfopt=1
1368 patchopt="-bfp1 -z .orig"
1369 createprefix=1 createdocs="" rmemptydir=""
1375 badfiles="" badfiles_nr=0
1376 declare -a badfiles_desc
1379 # this is a 2nd lightweight and modular "build this package" implementation
1380 # currently only used for the postlinux stuff - later maybe for more -ReneR
1389 pkg="$1" xpkg="$pkg"
1390 [ "$2" ] && conffile="$2" || conffile="$pkg.conf"
1393 declare -a hook_functions='()'
1401 # Erase positional parameters to prevent unintended current
1402 # arguments pssing to the loaded script.
1406 echo_status "Building $xpkg within $super (using $conffile)"
1408 for x in $(get_expanded $base/target/%/pkg_$pkg.conf $targetchain) \
1409 $targetdir/package/$pkg/$pkg.conf \
1410 architecture/$arch/package/$pkg/$pkg.conf \
1411 $confdir/$conffile; do
1413 if [[ $x == */$conffile ]]; then
1414 echo "Reading package configuration ($conffile) from package directory."
1416 echo "Reading package configuration from $x."
1423 # short path - to not abort on missing downloads of postlinux.conf
1424 # packages that are not built anyway -ReneR
1425 if [ "$custmain" = "true" ]; then
1426 echo "Nothing is going to be done ayway - returning quickly."
1433 # dump for debugging
1434 hook_dump > $builddir/debug.hooks.$pkg
1435 dump_env > $builddir/debug.buildenv.$pkg
1437 echo "Running main build function '$mainfunction'"
1440 eval "$mainfunction"
1443 [ -f $logstamp ] || return 1