Files
lbmk/include/init.sh
T
Leah Rowe dc722b5bb8 init.sh: switch back to old TMPDIR checks
the new check is still retained, to the extent that
the lock file still contains the TMPDIR string, and
it's checked whether this changed during execution.

however, the current TMPDIR handling is over-engineered
and prevents the re-use of project source caches when
doing release builds; this means that the release builds
happen much more slowly, especially for slow internet
connections.

this change *fixes* that bug. now release builds once
again re-use the main cache/ directory.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2025-09-24 23:26:11 +01:00

422 lines
9.9 KiB
Bash

# SPDX-License-Identifier: GPL-3.0-only
# Copyright (c) 2022 Caleb La Grange <thonkpeasant@protonmail.com>
# Copyright (c) 2022 Ferass El Hafidi <vitali64pmemail@protonmail.com>
# Copyright (c) 2020-2025 Leah Rowe <leah@libreboot.org>
# Copyright (c) 2025 Alper Nebi Yasak <alpernebiyasak@gmail.com>
export LC_COLLATE=C
export LC_ALL=C
projectname="libreboot"
projectsite="https://libreboot.org/"
if [ -z "${PATH+x}" ]; then
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"
fi
eval "`setvars "" _nogit board reinstall versiondate aur_notice configdir \
datadir version xbmkpwd relname xbmkpwd xbtmp python pyver xbmklock \
cvxbmk cvchk xbmkpath is_child basetmp`"
xbmk_init()
{
xbmkpwd="`pwd || err "Cannot generate PWD"`" || err "!" xbmk_init "$@"
xbmklock="$xbmkpwd/lock"
basetmp="$xbmkpwd/xbmkwd"
if [ $# -gt 0 ] && [ "$1" = "dependencies" ]; then
x_ xbmkpkg "$@"
exit 0
fi
export PWD="$xbmkpwd"
x_ mkdir -p "$basetmp"
id -u 1>/dev/null 2>/dev/null || \
err "suid check failed" "xbmk_init" "$@"
if [ "$(id -u)" = "0" ]; then
err "this command as root is not permitted" "xbmk_init" "$@"
fi
for init_cmd in get_version set_env set_threads git_init child_exec; do
if ! xbmk_$init_cmd "$@"; then
break
fi
done
}
xbmkpkg()
{
xchk xbmkpkg "$@"
if [ $# -gt 2 ]; then
reinstall="$3"
fi
eval "`setcfg "config/dependencies/$2"`"
chkvars pkg_add pkglist
x_ $pkg_add $pkglist
if [ -n "$aur_notice" ]; then
printf "You need AUR packages: %s\n" "$aur_notice" 1>&2
fi
}
xbmk_get_version()
{
if [ -f ".version" ]; then
read -r version < ".version" || \
err "can't read version file" "xbmk_get_version" "$@"
fi
if [ -f ".versiondate" ]; then
read -r versiondate < ".versiondate" || \
err "can't read versiondate" xbmk_get_version "$@"
fi
if [ -f ".version" ]; then
chkvars version
fi
if [ -f ".versiondate" ]; then
chkvars versiondate
fi
if [ ! -e ".git" ] && [ ! -f ".version" ]; then
version="unknown"
fi
if [ ! -e ".git" ] && [ ! -f ".versiondate" ]; then
versiondate="1716415872"
fi
xbmk_sanitize_version
if [ -n "$version" ]; then
relname="$projectname-$version"
fi
}
# a parent instance will cause this function to return 0.
# a child instance will return 1, skipping further initialisation
# after this function is called.
xbmk_set_env()
{
is_child="n"
xbmkpath="$PATH"
# unify all temporary files/directories in a single TMPDIR
if [ -n "${TMPDIR+x}" ] && [ "${TMPDIR%_*}" != "$basetmp/xbmk" ]; then
unset TMPDIR
fi
if [ -n "${TMPDIR+x}" ]; then
export TMPDIR="$TMPDIR"
xbtmp="$TMPDIR"
fi
if [ -n "${TMPDIR+x}" ]; then
is_child="y"
fi
if [ "$is_child" = "y" ]
then
# child instance of xbmk, so we stop init after this point:
xbmk_child_set_tmp
if [ -z "${XBMK_CACHE+x}" ]; then
err "XBMK_CACHE unset on child" "xbmk_set_env" "$@"
fi
if [ -z "${XBMK_THREADS+x}" ]; then
xbmk_set_threads; :
fi
return 1
else
# parent instance of xbmk, so we continue initialising.
# a parent instance of xbmk never processes its own
# command directly; instead, it calls a child instance
# of xbmk, and exits with the corresponding return status.
xbmk_parent_check_tmp
printf "%s\n" "$xbtmp" > "$xbmklock" || \
err "cannot create '$xbmklock'" xbmk_set_env "$@"; :
# not really critical for security, but it's a barrier
# against the user to make them think twice before deleting it
# in case an actual instance of xbmk is already running:
x_ chmod -w "$xbmklock"
xbmk_parent_set_export
xbmk_set_version
remkdir "$xbtmp" "$xbtmp/gnupath" "$xbtmp/xbmkpath"
xbmk_set_pyver
return 0
fi
}
xbmk_child_set_tmp()
{
eval `setvars "" badtmp xbtmpchk locktmp`
xbtmpchk="`findpath "$TMPDIR" || err "!findpath $TMPDIR"`" || \
err "!findpath '$TMPDIR'" xbmk_child_set_tmp "$@"
read -r locktmp < "$xbmklock" || \
err "can't read '$xbmklock'" xbmk_child_set_tmp "$@"
if [ "$locktmp" != "$xbtmpchk" ]; then
badtmp="TMPDIR '$xbtmpchk' changed; was '$locktmp'"
printf "bad TMPDIR init, '%s': %s\n" "$TMPDIR" "$badtmp" 1>&2
err "'$xbmklock' present with bad tmpdir. is a build running?"
fi
xbtmp="$xbtmpchk"
export TMPDIR="$xbtmpchk"
}
xbmk_parent_check_tmp()
{
export TMPDIR="$basetmp"
xbmklist="`mktemp || err "can't make tmplist"`" || \
err "can't make tmplist" xbmk_parent_check_tmp "$@"
x_ rm -f "$xbmklist"
x_ touch "$xbmklist"
for xtmpdir in "$basetmp"/xbmk_*; do
if [ -e "$xtmpdir" ]; then
printf "%s\n" "$xtmpdir" >> "$xbmklist" || \
err "can't write '$xtmpdir' to '$xbmklist'" \
"xbmk_parent_check_tmp" "$@"; :
fi
done
# set up a unified temporary directory, for common deletion later:
export TMPDIR="`x_ mktemp -d -t xbmk_XXXXXXXX`" || \
err "can't export TMPDIR" "xbmk_parent_check_tmp" "$@"
xbtmp="$TMPDIR"
while read -r xtmpdir; do
if [ "$xtmpdir" = "$xbtmp" ]; then
err "pre-existing '$xbtmp'" "xbmk_parent_check_tmp" "$@"
fi
done < "$xbmklist" || \
err "Can't read xbmklist: '$xbmklist'" "xbmk_parent_check_tmp" "$@"
x_ rm -f "$xbmklist"
}
xbmk_parent_set_export()
{
export XBMK_CACHE="$xbmkpwd/cache"
if [ -L "$XBMK_CACHE" ] && [ "$XBMK_CACHE" = "$xbmkpwd/cache" ]; then
err "cachedir '$xbmkpwd/cache' is a symlink" \
"xbmk_parent_set_export" "$@"
fi
if [ -e "$XBMK_CACHE" ] && [ ! -d "$XBMK_CACHE" ]; then
err "cachedir '$XBMK_CACHE' is a file" \
"xbmk_parent_set_export" "$@"
fi
export PATH="$xbtmp/xbmkpath:$xbtmp/gnupath:$PATH"
xbmkpath="$PATH"
# if "y": a coreboot target won't be built if target.cfg says release=n
# (this is used to exclude certain build targets from releases)
if [ -z "${XBMK_RELEASE+x}" ]; then
export XBMK_RELEASE="n"
fi
if [ "$XBMK_RELEASE" = "Y" ]; then
export XBMK_RELEASE="y"
fi
if [ "$XBMK_RELEASE" != "y" ]; then
export XBMK_RELEASE="n"
fi
}
xbmk_set_threads()
{
if [ -z "${XBMK_THREADS+x}" ]; then
export XBMK_THREADS=1
fi
if ! expr "X$XBMK_THREADS" : "X-\{0,1\}[0123456789][0123456789]*$" \
1>/dev/null 2>/dev/null; then
export XBMK_THREADS=1
fi
}
xbmk_set_version()
{
version_="$version"
if [ -e ".git" ]; then
version="$(git describe --tags HEAD 2>&1)" || \
version="git-$(git rev-parse HEAD 2>&1)" || \
version="$version_"
fi
versiondate_="$versiondate"
if [ -e ".git" ]; then
versiondate="$(git show --no-patch --no-notes \
--pretty='%ct' HEAD)" || versiondate="$versiondate_"
fi
chkvars version versiondate
update_xbmkver "."
relname="$projectname-$version"
export LOCALVERSION="-$projectname-${version%%-*}"
}
xbmk_set_pyver()
{
pyv="import sys; print(sys.version_info[:])"
python="python3"
pyver="2"
if ! pybin python3 1>/dev/null; then
python="python"
fi
if [ "$python" = "python3" ]; then
pyver="3"
fi
if ! pybin "$python" 1>/dev/null; then
pyver=""
fi
if [ -n "$pyver" ]; then
"`x_ pybin "$python"`" -c "$pyv" 1>/dev/null \
2>/dev/null || \
err "Can't detect Python version." "xbmk_set_pyver" "$@"
fi
if [ -n "$pyver" ]; then
# TODO: very sus; possible holes in error management
# TODO: maybe use sed?
pyver="$("$(pybin "$python")" -c "$pyv" | awk '{print $1}')"
pyver="${pyver#(}"
pyver="${pyver%,}"
fi
if [ "${pyver%%.*}" != "3" ]; then
err "Bad python version (must by 3.x)" "xbmk_set_pyver" "$@"
fi
# set up python in PATH (environmental variable):
(
x_ cd "$xbtmp/xbmkpath"
x_ ln -s "`x_ pybin "$python"`" python || \
err "can't make symlink" "xbmk_set_pyver" "$@"
) || \
err "Can't link Python in $xbtmp/xbmkpath" "xbmk_set_pyver" "$@"; :
}
# Use direct path, to prevent a hang if Python is using a virtual environment,
# not command -v, to prevent a hang when checking python's version
# See: https://docs.python.org/3/library/venv.html#how-venvs-work
pybin()
{
py="import sys; quit(1) if sys.prefix == sys.base_prefix else quit(0)"
venv=1
if ! command -v "$1" 1>/dev/null 2>/dev/null; then
venv=0
fi
if [ $venv -gt 0 ]; then
if ! "$1" -c "$py" 1>/dev/null 2>/dev/null; then
venv=0
fi
fi
# ideally, don't rely on PATH or hardcoded paths if python venv.
# use the *real*, direct executable linked to by the venv symlink:
if [ $venv -gt 0 ] && [ -L "`command -v "$1" 2>/dev/null`" ]; then
# TODO: very sus; possible hole in error management:
pypath="$(findpath \
"$(command -v "$1" 2>/dev/null)" 2>/dev/null || :)"
if [ -e "$pypath" ] && [ ! -d "$pypath" ] && \
[ -x "$pypath" ]; then
printf "%s\n" "$pypath"
return 0
fi
fi
# if python venv: fall back to common PATH directories for checking
[ $venv -gt 0 ] && for pypath in "/usr/local/bin" "/usr/bin"; do
[ -e "$pypath/$1" ] && [ ! -d "$pypath/$1" ] && \
[ -x "$pypath/$1" ] && printf "%s/%s\n" "$pypath" "$1" && \
return 0
done && return 1
# Defer to normal command -v if not a venv
if ! command -v "$1" 2>/dev/null; then
return 1
fi
}
xbmk_git_init()
{
for gitarg in "--global user.name" "--global user.email"; do
gitcmd="git config $gitarg"; $gitcmd 1>/dev/null 2>/dev/null \
|| err "Run this first: $gitcmd \"your ${gitcmd##*.}\"" \
"xbmk_git_init" "$@"
done
if [ -L ".git" ]; then
err "'$xbmkpwd/.git' is a symlink" "xbmk_git_init" "$@"
fi
if [ -e ".git" ]; then
return 0
fi
# GNU-specific extensions of date are used.
# TODO: that is a bug. fix it!
x_ date --version | grep "GNU coreutils" 1>/dev/null 2>/dev/null || \
err "Non-GNU date implementation" "xbmk_git_init" "$@"
eval "$(setvars "$(x_ date -Rud @$versiondate)" cdate _nogit || err)" \
|| err "can't get date" "xbmk_git_init" "$@"
x_ git init 1>/dev/null 2>/dev/null
x_ git add -A . 1>/dev/null 2>/dev/null
x_ git commit -m "$projectname $version" --date "$cdate" \
--author="xbmk <xbmk@example.com>" 1>/dev/null 2>/dev/null
x_ git tag -a "$version" -m "$projectname $version" 1>/dev/null \
2>/dev/null; :
}
xbmk_child_exec()
{
xbmk_rval=0
( x_ ./mk "$@" ) || xbmk_rval=1
( x_ rm -Rf "$xbtmp" ) || xbmk_rval=1
( x_ rm -f "$xbmklock" ) || xbmk_rval=1
exit $xbmk_rval
}
xbmk_init "$@"