Files
lbmk/script/handle/make/config
T
Leah Rowe 8c03b886c4 Greatly simplify error handling in shell scripts
Instead of having detailed error messages, run most
commands through a function that calls err() under
fault conditions.

Where detail is still required, err() is still called
manually. Where it isn't, the error message is simply
whatever command was executed to cause the error.

This results in a massive sloccount reduction for lbmk;
specifically, 178 sloc reduction, or a 8.1% reduction.
The total sloccount is now 2022, for shell scripts.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2023-10-01 22:47:02 +01:00

274 lines
7.8 KiB
Bash
Executable File

#!/usr/bin/env sh
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: 2022 Alper Nebi Yasak <alpernebiyasak@gmail.com>
# SPDX-FileCopyrightText: 2022 Ferass El Hafidi <vitali64pmemail@protonmail.com>
# SPDX-FileCopyrightText: 2023 Leah Rowe <leah@libreboot.org>
[ "x${DEBUG+set}" = 'xset' ] && set -v
set -u -e
. "include/err.sh"
. "include/option.sh"
read projectname < projectname
read our_version < version
export LOCALVERSION="-${projectname}-${our_version}"
eval "$(setvars "" arch cfgsdir codedir config config_name crossgcc_ada mode \
elfdir listfile project romtype target target_dir targets tree cbfstool)"
tmpclean="$(mktemp -d -t makeclean.XXXXXXXXXX)" || fail "!mkdir tmpclean"
main()
{
while getopts b:m:u:c:x: option
do
case "${1}" in
-b) mode="all" ;;
-u) mode="oldconfig" ;;
-m) mode="menuconfig" ;;
-c) mode="distclean" ;;
-x) mode="crossgcc-clean" ;;
*) fail "Invalid option" ;;
esac
shift; project="${OPTARG}"; shift
done
[ -z "${mode}" ] && fail "mode not given (-m, -u, -b, -c or -x)"
[ -z "${project}" ] && fail "project name not specified"
handle_dependencies $@
handle_targets
}
handle_dependencies()
{
elfdir="elf/${project}"
cfgsdir="config/${project}"
[ -d "${cfgsdir}" ] || fail "directory, ${cfgsdir}, does not exist"
listfile="${cfgsdir}/build.list"
[ -f "${listfile}" ] || fail "list file, ${listfile}, does not exist"
# Build for all targets if no argument is given
targets=$(listitems "${cfgsdir}") || \
fail "Cannot get options for ${cfgsdir}"
[ $# -gt 0 ] && targets=$@
[ "${mode}" = "all" ] && xx_ mkdir -p "${elfdir}/"
}
handle_targets()
{
for x in ${targets}; do
target="${x}"
printf "Running 'make %s' for project '%s, target '%s''\n" \
"${mode}" "${project}" "${target}"
[ "${project}" != "coreboot" ] || [ "${mode}" != "all" ] || \
xx_ ./update blobs download ${target}
xx_ handle_defconfig
done
[ "${mode}" = "all" ] || return 0
printf "Done! The files are stored under %s/\n\n" "${elfdir}"
}
handle_defconfig()
{
handle_src_tree "${target}" || return 0
for y in "${target_dir}/config"/*; do
[ -f "${y}" ] || continue
config="${y}"
config_name="${config#$target_dir/config/}"
printf "handle/make/config %s %s: handling config %s\n" \
"${project}" "${target}" "${config_name}"
[ "${mode}" != "all" ] || check_config || continue
run_make_command
[ "${mode}" != "all" ] || copy_elf
done
}
handle_src_tree()
{
target_dir="${cfgsdir}/${target}"
xx_ mkdir -p "${elfdir}/${target}"
eval "$(setvars "undefined" arch tree)"
romtype="normal"
[ ! -f "${target_dir}/target.cfg" ] && \
fail "handle_src_tree: ${target_dir}: missing target.cfg"
# Override the above defaults using target.cfg
. "${target_dir}/target.cfg" # source
[ "${tree}" = "undefined" ] && \
fail "handle_src_tree: ${target_dir}: tree undefined"
[ "${arch}" = "undefined" ] && \
fail "handle_src_tree: ${target_dir}: undefined cpu type"
codedir="${project}/${tree}"
if [ ! -d "${codedir}" ]; then
if [ "${mode}" = "distclean" ] || \
[ "${mode}" = "crossgcc-clean" ]; then
printf "Directory %s doesn't exist; skipping clean\n" \
"${codedir}" 1>&2
return 1
fi
xx_ ./update project trees "${project}" "${target}"
elif [ "${mode}" = "distclean" ] || \
[ "${mode}" = "crossgcc-clean" ]; then
[ -f "${tmpclean}/${tree}" ] && return 1
touch "${tmpclean}/${tree}"
fi
# u-boot and coreboot are both compiled with coreboot's crossgcc
if [ "${project}" = "coreboot" ] || [ "${project}" = "u-boot" ]; then
[ "${mode}" != "all" ] || check_cross_compiler || \
fail "handle_src_tree ${project}/${target}: crossgcc"
cbfstool="cbutils/${tree}/cbfstool"
[ -f "${cbfstool}" ] || xx_ ./build coreboot utils "${tree}"
fi
}
# set up cross-compiler (coreboot crossgcc) for u-boot and coreboot
# (seabios and grub currently use hostcc, not crossgcc)
check_cross_compiler()
{
[ "${crossgcc_ada}" = "y" ] || [ "${crossgcc_ada}" = "n" ] || \
crossgcc_ada="y"
[ "${crossgcc_ada}" != "y" ] && \
export BUILD_LANGUAGES=c
cbdir="coreboot/${tree}"
[ "${project}" != "coreboot" ] && \
cbdir="coreboot/default" # not u-boot (e.g. linux will use it)
[ "${project}" = "u-boot" ] && \
cbdir="coreboot/cros" # u-boot only used on coreboot/cros
# only true if not building coreboot:
ctarget="${cbdir#coreboot/}"
[ -d "${cbdir}" ] || \
xx_ ./update project trees coreboot ${ctarget}
if [ "${arch}" = "x86_32" ] || [ "${arch}" = "x86_64" ]; then
[ -d "${cbdir}/util/crossgcc/xgcc/i386-elf/" ] || \
make -C "${cbdir}" crossgcc-i386 CPUS=$(nproc) || \
return 1
case "$(uname -m)" in
x86*|i*86|amd64) : ;;
*) export CROSS_COMPILE=i386-elf- ;;
esac
elif [ "${arch}" = "ARMv7" ]; then
[ -d "${cbdir}/util/crossgcc/xgcc/arm-eabi/" ] || \
make -C "${cbdir}" crossgcc-arm CPUS=$(nproc) || \
return 1
case "$(uname -m)" in
arm|arm32|armv6*|armv7*) : ;;
*) export CROSS_COMPILE=arm-eabi- ;;
esac
elif [ "${arch}" = "AArch64" ]; then
[ -d "${cbdir}/util/crossgcc/xgcc/aarch64-elf/" ] || \
make -C "${cbdir}" crossgcc-aarch64 CPUS=$(nproc) || \
return 1
# aarch64 also needs armv7 toolchain for arm-trusted-firmware
[ -d "${cbdir}/util/crossgcc/xgcc/arm-eabi/" ] || \
make -C "${cbdir}" crossgcc-arm CPUS=$(nproc) || \
return 1
case "$(uname -m)" in
arm64|aarch64) : ;;
*) export CROSS_COMPILE=aarch64-elf- ;;
esac
fi
# we *must* ensure that u-boot's build system uses crossgcc first
export PATH="$(pwd)/${cbdir}/util/crossgcc/xgcc/bin:$PATH"
}
check_config()
{
[ ! -f "${config}" ] && \
fail "check_config: ${project}/${target}: configs missing"
dest_dir="${elfdir}/${target}/${config_name}"
# TODO: very hacky check. do it properly (based on build.list)
for elftest in "${dest_dir}"/*; do
[ -f "${elftest}" ] || continue
printf "Build already exists, so skipping build\n" 1>&2
return 1
done
xx_ mkdir -p "${dest_dir}"
}
run_make_command()
{
xx_ ./handle make file -c "${codedir}"
xx_ cp "${config}" "${codedir}/.config"
[ "${mode}" != "all" ] || make -C "${codedir}" silentoldconfig || \
make -C "${codedir}" oldconfig || : # don't error on oldconfig
if [ "${project}" = "coreboot" ] && [ "${mode}" = "all" ]; then
printf "%s\n" "${our_version}" >"${codedir}/.coreboot-version" \
|| fail "run_make_command: ${codedir}: can't set version"
fi
xx_ make -C "${codedir}" -j$(nproc) ${mode}
if [ -e "${codedir}/.git" ] && [ "${project}" = "u-boot" ] && \
[ "${mode}" = "distclean" ]; then
xx_ git -C "${codedir}" clean -fdx
elif [ "${mode}" = "oldconfig" ] || [ "${mode}" = "menuconfig" ]; then
xx_ cp "${codedir}/.config" "${config}"
fi
}
copy_elf()
{
[ "${project}" != "coreboot" ] || xx_ modify_coreboot_rom
while read f; do
[ ! -f "${codedir}/$f" ] || \
xx_ cp "${codedir}/${f}" "${dest_dir}/"
done < ${listfile}
xx_ ./handle make file -c "${codedir}"
}
modify_coreboot_rom()
{
rompath="${codedir}/build/coreboot.rom"
[ -f "${rompath}" ] || \
fail "modify_coreboot_rom: does not exist: ${rompath}"
tmprom="$(mktemp -t rom.XXXXXXXXXX)"
xx_ rm -f "${tmprom}"
if [ "${romtype}" = "d8d16sas" ]; then
# pike2008 roms hang seabios. an empty rom will override
# the built-in one, thus disabling all execution of it
xx_ touch "${tmprom}"
for deviceID in "0072" "3050"; do
xx_ "${cbfstool}" "${rompath}" add -f "${tmprom}" \
-n "pci1000,${deviceID}.rom" -t raw
done
elif [ "${romtype}" = "i945 laptop" ]; then
# for bucts-based installation method from factory bios
xx_ dd if="${rompath}" of="${tmprom}" bs=1 \
skip=$(($(stat -c %s "${rompath}") - 0x10000)) \
count=64k
xx_ dd if="${tmprom}" of="${rompath}" bs=1 \
seek=$(($(stat -c %s "${rompath}") - 0x20000)) \
count=64k conv=notrunc
fi
xx_ rm -f "${tmprom}"
}
fail()
{
[ -z "${codedir}" ] || ./handle make file -c "${codedir}" || :
err "${1}"
}
main $@