mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-03-26 22:09:03 +02:00
config/data/PROJECT/mkhelper.cfg can be provided, for configuration, and it is loaded *before* target.cfg there are certain instances where we repeat a lot of config per tree, in multi-tree projects. for example, we have the exact same config per grub tree, besides tree name and revision number, for things like autoconf arguments. this last problem will be addressed, in a follow-up patch, and then expanded upon for other projects. Signed-off-by: Leah Rowe <leah@libreboot.org>
302 lines
8.5 KiB
Bash
Executable File
302 lines
8.5 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=$XBMK_THREADS"
|
|
eval `setvars "" xarch cdir defconfig cmakedir xlang mode makeargs elfdir cmd \
|
|
project target target_dir targets xtree _f target1 bootstrapargs mkhelper \
|
|
autoconfargs listfile autogenargs btype tree rev tree_depend`
|
|
|
|
main()
|
|
{
|
|
while getopts f:b:m:u:c:x:s:l:n: option; do
|
|
[ -n "$_f" ] && $err "only one flag is permitted"
|
|
_f="$1"
|
|
case "$1" in
|
|
-b) mode="" ;;
|
|
-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
|
|
[ -z "${OPTARG+x}" ] && shift 1 && break
|
|
project="${OPTARG#src/}"; shift 2
|
|
done
|
|
[ -z "$_f" ] && $err "missing flag (-m/-u/-b/-c/-x/-f/-s/-l/-n)"
|
|
[ -z "$project" ] && for p in $(ls -1 config/git); do
|
|
./update trees $_f "$p" || $err "!./update trees $_f $p"
|
|
[ "$XBMK_RELEASE" != "y" ] || singletree "$p" || \
|
|
x_ rm Rf "src/$p/$p"; continue
|
|
done && return 0
|
|
|
|
[ -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_targets" && singletree "$project" && cmd="build_project"
|
|
$cmd $@
|
|
|
|
[ "$target1" = "utils" ] && [ "$project" = "coreboot" ] && return 0
|
|
|
|
[ -f "$listfile" ] || return 0
|
|
[ -z "$mode" ] && printf "\n\nOK! Check %s/\n\n" "$elfdir"; return 0
|
|
}
|
|
|
|
build_project()
|
|
{
|
|
load_target_config "$cfgsdir" || return 0
|
|
[ -f "$listfile" ] || listfile="" # optional on single-tree
|
|
|
|
dest_dir="$elfdir"
|
|
[ ! -f "$listfile" ] || elfcheck || return 0
|
|
|
|
cdir="src/${project}"
|
|
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
|
|
defconfig="$y"
|
|
|
|
[ -n "$mode" ] || check_defconfig || continue
|
|
handle_makefile
|
|
[ -n "$mode" ] || copy_elf
|
|
done; return 0
|
|
}
|
|
|
|
handle_src_tree()
|
|
{
|
|
target_dir="$cfgsdir/$target"
|
|
|
|
[ -f "CHANGELOG" ] || fetch_project "$project"
|
|
load_target_config "$target_dir" || return 1
|
|
x_ mkdir -p "$elfdir/$target"
|
|
|
|
chkvars tree
|
|
cdir="src/$project/$tree"
|
|
|
|
if [ "$mode" = "distclean" ] || [ "$mode" = "crossgcc-clean" ]; then
|
|
[ -d "$cdir" ] || return 1
|
|
fi
|
|
x_ ./update trees -f "$project" "$target"
|
|
|
|
[ "$target1" = "utils" ] && [ "$project" = "coreboot" ] && return 0
|
|
[ -z "$mode" ] && check_cross_compiler; return 0
|
|
}
|
|
|
|
load_target_config()
|
|
{
|
|
eval `setvars "" xarch xlang bootstrapargs autoconfargs xtree \
|
|
tree_depend makeargs btype mkhelper`
|
|
[ -f "$1/target.cfg" ] || btype="auto"
|
|
[ -f "$datadir/mkhelper.cfg" ] && eval `setcfg "$datadir/mkhelper.cfg"`
|
|
|
|
_tcfg="$1/target.cfg"
|
|
while [ -f "$_tcfg" ] || [ "$cmd" = "build_targets" ]; do
|
|
eval `setvars "" rev tree`
|
|
|
|
printf "Loading %s config: %s\n" "$project" "$_tcfg"
|
|
eval `setcfg "$_tcfg"`
|
|
[ "$cmd" = "build_project" ] && break
|
|
[ "$mode" = "fetch" ] || break
|
|
|
|
[ "${_tcfg%/*/target.cfg}" = "${_tcfg%"/$tree/target.cfg"}" ] \
|
|
&& break; _tcfg="${_tcfg%/*/target.cfg}/$tree/target.cfg"
|
|
done
|
|
|
|
[ -z "$btype" ] || [ "${mode%config}" = "$mode" ] || return 1
|
|
|
|
[ "$mode" = "fetch" ] || return 0
|
|
[ -f "CHANGELOG" ] && return 1; fetch_${cmd#build_}; return 1
|
|
}
|
|
|
|
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"
|
|
|
|
# sometimes buildgcc fails for like no reason. try twice.
|
|
make -C "$cbdir" crossgcc-${_xarch%-*} $cbmakeargs || \
|
|
make -C "$cbdir" crossgcc-${_xarch%-*} $cbmakeargs || \
|
|
$err "!mkxgcc $project/$xtree '${_xarch%-*}' '$cbmakeargs'"
|
|
done; return 0
|
|
}
|
|
|
|
check_coreboot_utils()
|
|
{
|
|
for util in cbfstool ifdtool; do
|
|
utilelfdir="elf/$util/$1"
|
|
utilsrcdir="src/coreboot/$1/util/$util"
|
|
|
|
utilmode="" && [ -n "$mode" ] && utilmode="clean"
|
|
x_ make -C "$utilsrcdir" $utilmode -j$XBMK_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; return 0
|
|
}
|
|
|
|
check_defconfig()
|
|
{
|
|
[ -f "$defconfig" ] || $err "$project/$target: missing defconfig"
|
|
|
|
dest_dir="$elfdir/$target/${defconfig#"$target_dir/config/"}"
|
|
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" ] && e "$elftest" f && return 1
|
|
done; return 0
|
|
}
|
|
|
|
handle_makefile()
|
|
{
|
|
check_makefile "$cdir" && x_ make clean -C "$cdir"
|
|
x_ cp "$defconfig" "$cdir/.config"
|
|
[ -n "$mode" ] || [ -n "$btype" ] || 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" "$defconfig"
|
|
|
|
[ -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$XBMK_THREADS $makeargs || $err "$cdir mk$mode"
|
|
[ -z "$mkhelper" ] || [ -n "$mode" ] || $mkhelper || $err "!$mkhelper"
|
|
|
|
[ "$mode" = "clean" ] && make -C "$cdir" distclean || :; return 0
|
|
}
|
|
|
|
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"`
|
|
|
|
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 $@
|