Files
LibreELEC.tv/config/multithread

118 lines
3.7 KiB
Plaintext

# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2019-present Team LibreELEC (https://libreelec.tv)
THREADCOUNT=${THREADCOUNT:-$(nproc)}
# This function is passed a list of package.mk paths to be processed.
# Each package.mk is sourced with relevant variables output in JSON format.
json_worker() {
local packages="$@"
local pkgpath hierarchy exited
exit() { exited=1; }
. config/options ""
for pkgpath in ${packages}; do
pkgpath="${pkgpath%%@*}"
exited=0
if ! source_package "${pkgpath}/package.mk" &>/dev/null; then
unset -f exit
die "$(print_color CLR_ERROR "FAILURE: sourcing package ${pkgpath}/package.mk")"
fi
[ ${exited} -eq 1 ] && continue
[[ ${pkgpath} =~ ^${ROOT}/${PACKAGES}/ ]] && hierarchy="global" || hierarchy="local"
cat <<EOF
{
"name": "${PKG_NAME}",
"hierarchy": "${hierarchy}",
"section": "${PKG_SECTION}",
"bootstrap": "${PKG_DEPENDS_BOOTSTRAP}",
"init": "${PKG_DEPENDS_INIT}",
"host": "${PKG_DEPENDS_HOST}",
"target": "${PKG_DEPENDS_TARGET}"
},
EOF
done
}
export -f json_worker
start_multithread_build() {
local buildopts bootstrap result=0
# init thread control folder
rm -rf "${THREAD_CONTROL}"
mkdir -p "${THREAD_CONTROL}/locks"
echo -1 >"${THREAD_CONTROL}/progress.prev"
echo 0 >"${THREAD_CONTROL}/progress"
touch "${THREAD_CONTROL}/status"
# Increase file descriptors if building one thread/package
[ "${THREADCOUNT}" = "0" ] && ulimit -n ${ULIMITN:-10240}
# create a single log file by default for a single threaded build (or the builder is a masochist)
if [ ${THREADCOUNT} -eq 1 -a "${ONELOG,,}" != "no" ] || [ "${ONELOG,,}" = "yes" ]; then
buildopts+=" --no-log-burst"
bootstrap="&1"
else
mkdir -p "${THREAD_CONTROL}/logs"
buildopts+=" --log-burst"
bootstrap="${THREAD_CONTROL}/logs/0.log"
fi
buildopts+=" --log-combine ${LOGCOMBINE:-always}"
# When building addons, don't halt on error - keep building all packages/addons
[ "${MTADDONBUILD}" = "yes" ] && buildopts+=" --continue-on-error" || buildopts+=" --halt-on-error"
[ "${MTVERBOSE}" = "yes" ] && buildopts+=" --verbose"
[ "${MTDEBUG}" = "yes" ] && buildopts+=" --debug"
if [ "${DISABLE_COLORS}" = "yes" ]; then
buildopts+=" --colors=never"
else
buildopts+=" --colors=${MTCOLORS:-auto}"
fi
buildopts+=" --stats-interval ${MTINTERVAL:-60}"
# Bootstrap GNU parallel
if MTWITHLOCKS=no $SCRIPTS/build parallel:host 2>&1 &>${bootstrap}; then
[ "${LOGCOMBINE}" = "always" -a -f "${bootstrap}" ] && cat "${bootstrap}"
else
[ "${LOGCOMBINE}" != "never" -a -f "${bootstrap}" ] && cat "${bootstrap}"
die "Unable to bootstrap parallel package"
fi
# pipefail: return value of a pipeline is the value of the last (rightmost) command to exit with a non-zero status
set -o pipefail
cat ${_CACHE_PACKAGE_GLOBAL} ${_CACHE_PACKAGE_LOCAL} | \
${TOOLCHAIN}/bin/parallel --plain --no-notice --max-args 30 --halt now,fail=1 json_worker | \
${SCRIPTS}/genbuildplan.py --show-wants --with-json "${THREAD_CONTROL}"/plan.json \
--build ${@} > "${THREAD_CONTROL}"/plan || result=1
if [ ${result} -eq 0 ]; then
save_build_config
# export the following vars so that they will be available to subprocesses of pkgbuilder.py
export ROOT SCRIPTS THREAD_CONTROL
MTBUILDSTART=$(date +%s) MTWITHLOCKS=yes ${SCRIPTS}/pkgbuilder.py \
--plan "${THREAD_CONTROL}"/plan.json \
--joblog "${THREAD_CONTROL}"/joblog \
--loadstats "${THREAD_CONTROL}"/loadstats \
--max-procs ${THREADCOUNT} ${buildopts} || result=1
[ -f "${THREAD_CONTROL}"/history ] && echo && cat "${THREAD_CONTROL}"/history | ${ROOT}/tools/mtstats.py
rm -f "${THREAD_CONTROL}/parallel.pid"
fi
set +o pipefail
return ${result}
}