mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-03-27 14:51:15 +02:00
just run the make crossgcc command anyway. coreboot's own build system checks itself, and much more reliably, but the check is more thorough and a bit slower. in rare cases, lbmk may come into build issues with xgcc, and if you run the build again, it will always fail every time because the checks is based on whether the xgcc directory exists, rather than checking each individual crossgcc binary. checking every binary is also possible, but as i said, the coreboot build system already does that, so let's defer to coreboot's own handling of it. remove the directory check. this will slow down the build process a little bit, but should improve reliability under fault conditions. Signed-off-by: Leah Rowe <leah@libreboot.org>
299 lines
7.8 KiB
Bash
Executable File
299 lines
7.8 KiB
Bash
Executable File
#!/usr/bin/env sh
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
# Copyright (c) 2022-2023 Alper Nebi Yasak <alpernebiyasak@gmail.com>
|
|
# Copyright (c) 2022 Ferass El Hafidi <vitali64pmemail@protonmail.com>
|
|
# Copyright (c) 2023-2024 Leah Rowe <leah@libreboot.org>
|
|
|
|
set -u -e
|
|
|
|
. "include/lib.sh"
|
|
. "include/git.sh"
|
|
|
|
cbmakeargs="UPDATED_SUBMODULES=1 CPUS=$threads"
|
|
eval `setvars "" xarch cdir config config_name xlang mode makeargs \
|
|
listfile project target target_dir targets tree _f target1 bootstrapargs \
|
|
autoconfargs cmakedir elfdir autogenargs xtree`
|
|
|
|
main()
|
|
{
|
|
while getopts f:b:m:u:c:x:s:l:n: option; do
|
|
_f="$1"
|
|
case "$1" in
|
|
-b) : ;;
|
|
-u) mode="oldconfig" ;;
|
|
-m) mode="menuconfig" ;;
|
|
-c) mode="distclean" ;;
|
|
-x) mode="crossgcc-clean" ;;
|
|
-f) mode="fetch" ;;
|
|
-s) mode="savedefconfig" ;;
|
|
-l) mode="olddefconfig" ;;
|
|
-n) mode="nconfig" ;;
|
|
*) $err "invalid option '-$option'" ;;
|
|
esac
|
|
shift; project="${OPTARG#src/}"; shift
|
|
done
|
|
[ -z "$_f" ] && $err "missing flag (-m/-u/-b/-c/-x/-f/-s/-l/-n)"
|
|
[ -z "$project" ] && $err "project name not specified"
|
|
|
|
[ -f "config/git/$project/pkg.cfg" ] || $err "'$project' not defined"
|
|
|
|
elfdir="elf/$project"
|
|
datadir="config/data/$project"
|
|
cfgsdir="config/$project"
|
|
listfile="$datadir/build.list" # needed on multi, optional on single
|
|
|
|
remkdir "${tmpgit%/*}"
|
|
|
|
_cmd="build_projects"
|
|
singletree "$project" || _cmd="build_targets"
|
|
$_cmd $@
|
|
|
|
[ "$target1" = "utils" ] && [ "$project" = "coreboot" ] && return 0
|
|
|
|
[ -f "$listfile" ] || return 0
|
|
[ -z "$mode" ] && printf "\n\nDone! Check %s/\n\n" "$elfdir"; return 0
|
|
}
|
|
|
|
build_projects()
|
|
{
|
|
[ $# -gt 0 ] && x_ ./update trees $_f $@
|
|
|
|
if [ "$mode" = "fetch" ]; then
|
|
[ -f "CHANGELOG" ] && return 0
|
|
fetch_project_repo; return 0
|
|
fi
|
|
|
|
load_project_config "$cfgsdir"
|
|
[ -f "$listfile" ] || listfile="" # optional on single-tree
|
|
|
|
dest_dir="$elfdir"
|
|
[ ! -f "$listfile" ] || elfcheck || return 0
|
|
|
|
cdir="src/${project}"
|
|
[ -d "$cdir" ] || x_ ./update trees -f "$project"
|
|
|
|
[ "$mode" = "distclean" ] && mode="clean"
|
|
run_make_command || return 0
|
|
|
|
[ -n "$mode" ] || copy_elf; return 0
|
|
}
|
|
|
|
build_targets()
|
|
{
|
|
[ "$elfdir" = "elf/coreboot" ] && elfdir="$cbelfdir"
|
|
|
|
[ -d "$cfgsdir" ] || $err "directory, $cfgsdir, does not exist"
|
|
[ -f "$listfile" ] || $err "list file, $listfile, does not exist"
|
|
|
|
# Build for all targets if no argument is given
|
|
[ $# -gt 0 ] && target1="$1"
|
|
[ "$target1" = "utils" ] && [ "$project" = "coreboot" ] && shift 1
|
|
targets="$(ls -1 "$cfgsdir")" || $err "Can't get options for $cfgsdir"
|
|
[ $# -gt 0 ] && targets=$@
|
|
|
|
handle_targets
|
|
}
|
|
|
|
handle_targets()
|
|
{
|
|
for x in $targets; do
|
|
target="$x"
|
|
printf "'make %s', '%s', '%s'\n" "$mode" "$project" "$target"
|
|
[ "$project" != "coreboot" ] || [ -n "$mode" ] || \
|
|
[ "$target1" = "utils" ] || x_ ./vendor download $target
|
|
x_ handle_defconfig
|
|
done
|
|
}
|
|
|
|
handle_defconfig()
|
|
{
|
|
handle_src_tree "$target" || return 0
|
|
|
|
[ "$target1" = "utils" ] && [ "$project" = "coreboot" ] && \
|
|
eval "check_coreboot_utils \"$tree\"; return 0"
|
|
|
|
for y in "$target_dir/config"/*; do
|
|
[ -f "$y" ] || continue
|
|
config="$y"
|
|
config_name="${config#"$target_dir/config/"}"
|
|
|
|
[ -n "$mode" ] || check_config || continue
|
|
handle_makefile
|
|
[ -n "$mode" ] || copy_elf
|
|
done
|
|
}
|
|
|
|
handle_src_tree()
|
|
{
|
|
target_dir="$cfgsdir/$target"
|
|
if [ "$mode" = "fetch" ]; then
|
|
[ -f "CHANGELOG" ] && return 1
|
|
fetch_project_trees; return 1
|
|
fi
|
|
|
|
load_project_config "$target_dir"
|
|
x_ mkdir -p "$elfdir/$target"
|
|
|
|
chkvars tree
|
|
cdir="src/$project/$tree"
|
|
|
|
if [ ! -d "$cdir" ]; then
|
|
if [ "$mode" = "distclean" ] || \
|
|
[ "$mode" = "crossgcc-clean" ]; then
|
|
printf "Directory %s missing; skip\n" "$cdir" 1>&2
|
|
return 1
|
|
fi
|
|
x_ ./update trees -f "$project" "$target"
|
|
fi
|
|
|
|
[ "$target1" = "utils" ] && [ "$project" = "coreboot" ] && return 0
|
|
[ -z "$mode" ] && check_cross_compiler; return 0
|
|
}
|
|
|
|
load_project_config()
|
|
{
|
|
eval `setvars "" xarch xlang tree bootstrapargs autoconfargs xtree \
|
|
tree_depend makeargs`
|
|
eval `setcfg "$1/target.cfg" 0`; return 0
|
|
}
|
|
|
|
check_cross_compiler()
|
|
{
|
|
for _xarch in $xarch; do
|
|
cbdir="src/coreboot/$tree"
|
|
[ "$project" != "coreboot" ] && cbdir="src/coreboot/default"
|
|
[ -n "$xtree" ] && cbdir="src/coreboot/$xtree"
|
|
|
|
x_ ./update trees -f coreboot ${cbdir#src/coreboot/}
|
|
|
|
export PATH="$PWD/$cbdir/util/crossgcc/xgcc/bin:$PATH"
|
|
export CROSS_COMPILE="${xarch% *}-"
|
|
[ -n "$xlang" ] && export BUILD_LANGUAGES="$xlang"
|
|
|
|
x_ make -C "$cbdir" crossgcc-${_xarch%-*} $cbmakeargs
|
|
done
|
|
}
|
|
|
|
check_coreboot_utils()
|
|
{
|
|
for util in cbfstool ifdtool; do
|
|
utilelfdir="elf/$util/$1"
|
|
utilsrcdir="src/coreboot/$1/util/$util"
|
|
|
|
utilmode=""
|
|
[ -z "$mode" ] || utilmode="clean"
|
|
x_ make -C "$utilsrcdir" $utilmode -j$threads $cbmakeargs
|
|
[ -z "$mode" ] && [ ! -f "$utilelfdir/$util" ] && \
|
|
x_ mkdir -p "$utilelfdir" && \
|
|
x_ cp "$utilsrcdir/$util" "elf/$util/$1"
|
|
[ -z "$mode" ] || x_ rm -Rf "$utilelfdir"
|
|
done
|
|
}
|
|
|
|
check_config()
|
|
{
|
|
[ -f "$config" ] || $err "check_config $project/$target: no config"
|
|
|
|
dest_dir="$elfdir/$target/$config_name"
|
|
elfcheck || return 1 # skip build if a previous one exists
|
|
|
|
x_ mkdir -p "$dest_dir"
|
|
}
|
|
|
|
elfcheck()
|
|
{
|
|
# TODO: very hacky check. do it properly (based on build.list)
|
|
for elftest in "$dest_dir"/*; do
|
|
[ -e "$elftest" ] || continue
|
|
e "$elftest" f && return 1
|
|
done
|
|
}
|
|
|
|
handle_makefile()
|
|
{
|
|
[ "$project" = "grub" ] && [ "${mode%config}" != "$mode" ] && return 0
|
|
|
|
check_makefile "$cdir" && x_ make clean -C "$cdir"
|
|
x_ cp "$config" "$cdir/.config"
|
|
[ -n "$mode" ] || [ "$project" = "grub" ] || make -C "$cdir" \
|
|
silentoldconfig || make -C "$cdir" oldconfig || :
|
|
|
|
run_make_command || $err "handle_makefile $cdir: no makefile!"
|
|
|
|
_copy=".config"
|
|
[ "$mode" = "savedefconfig" ] && _copy="defconfig"
|
|
[ "${mode%config}" = "$mode" ] || x_ cp "$cdir/$_copy" "$config"
|
|
|
|
[ -e "$cdir/.git" ] && [ "$project" = "u-boot" ] && \
|
|
[ "$mode" = "distclean" ] && x_ git -C "$cdir" clean -fdx; return 0
|
|
}
|
|
|
|
run_make_command()
|
|
{
|
|
check_cmake "$cdir" && [ -z "$mode" ] && check_autoconf "$cdir"
|
|
check_makefile "$cdir" || return 1
|
|
|
|
[ "$project" = "coreboot" ] && [ -z "$mode" ] && x_ \
|
|
printf "%s\n" "${version%%-*}" > "$cdir/.coreboot-version" \
|
|
&& makeargs="$makeargs $cbmakeargs"
|
|
|
|
make -C "$cdir" $mode -j$threads $makeargs || $err "!mk $cdir $mode"
|
|
|
|
[ "$project" = "grub" ] && [ -z "$mode" ] && mkpayload_grub
|
|
|
|
[ "$mode" != "clean" ] && return 0
|
|
make -C "$cdir" distclean 2>/dev/null || :
|
|
}
|
|
|
|
check_cmake()
|
|
{
|
|
[ -z "$cmakedir" ] || check_makefile "$1" || cmake -B "$1" \
|
|
"$1/$cmakedir" || check_makefile "$1" || $err "$1: !cmk $cmakedir"
|
|
[ -z "$cmakedir" ] || check_makefile "$1" || \
|
|
$err "check_cmake $1: can't generate Makefile"; return 0
|
|
}
|
|
|
|
check_autoconf()
|
|
{
|
|
(
|
|
cd "$1" || $err "!cd $1"
|
|
[ -f "bootstrap" ] && x_ ./bootstrap $bootstrapargs
|
|
[ -f "autogen.sh" ] && x_ ./autogen.sh $autogenargs
|
|
[ -f "configure" ] && x_ ./configure $autoconfargs; return 0
|
|
) || $err "can't bootstrap project: $1"
|
|
}
|
|
|
|
check_makefile()
|
|
{
|
|
[ -f "$1/Makefile" ] || [ -f "$1/makefile" ] || \
|
|
[ -f "$1/GNUmakefile" ] || return 1; return 0
|
|
}
|
|
|
|
mkpayload_grub()
|
|
{
|
|
eval `setvars "" grub_modules grub_install_modules`
|
|
eval `setcfg "$grubdata/module/$tree"`
|
|
chkvars "grub_install_modules" "grub_modules"
|
|
|
|
x_ rm -f "$cdir/grub.elf"
|
|
|
|
"${cdir}/grub-mkstandalone" --grub-mkimage="${cdir}/grub-mkimage" \
|
|
-O i386-coreboot -o "${cdir}/grub.elf" -d "${cdir}/grub-core/" \
|
|
--fonts= --themes= --locales= --modules="$grub_modules" \
|
|
--install-modules="$grub_install_modules" \
|
|
"/boot/grub/grub_default.cfg=${cdir}/.config" \
|
|
"/boot/grub/grub.cfg=$grubdata/memdisk.cfg" \
|
|
"/background.png=$grubdata/background/background1280x800.png" || \
|
|
$err "$tree: cannot build grub.elf"; return 0
|
|
}
|
|
|
|
copy_elf()
|
|
{
|
|
[ -f "$listfile" ] && x_ mkdir -p "$dest_dir" && while read -r f; do
|
|
[ -f "$cdir/$f" ] && x_ cp "$cdir/$f" "$dest_dir"
|
|
done < "$listfile"
|
|
x_ make clean -C "$cdir"
|
|
}
|
|
|
|
main $@
|