7451fa629c
instead, make it a helper function, defined in target.cfg this means that we can also do the same with other projects in the future, and it is expected that we will have to. these helper functions are used in cases where we want additional actions to be performed. actually, the helper could be anything. for example, you could write: mkhelper="./build foo bar" and it would do that (at the point of execution, PWD is the root directory of the build system) Signed-off-by: Leah Rowe <leah@libreboot.org>
304 lines
8.2 KiB
Bash
Executable file
304 lines
8.2 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 config config_name xlang mode makeargs \
|
|
elfdir project target target_dir targets tree _f target1 bootstrapargs \
|
|
autoconfargs cmakedir listfile autogenargs xtree btype mkhelper`
|
|
|
|
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
|
|
[ -n "${OPTARG+x}" ] || $err "OPTARG not set"
|
|
project="${OPTARG#src/}"; shift 2
|
|
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_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()
|
|
{
|
|
if [ "$mode" = "fetch" ]; then
|
|
[ -f "CHANGELOG" ] && return 0
|
|
fetch_project_repo; return 0
|
|
fi
|
|
|
|
load_project_config "$cfgsdir" 0 || return 0
|
|
[ -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"
|
|
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" || return 1
|
|
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 btype mkhelper`
|
|
[ -f "$1/target.cfg" ] || btype="auto"
|
|
|
|
# target.cfg optional on single-tree so return if missing.
|
|
# target.cfg mandatory on multi-tree so err if missing.
|
|
_setcfgarg="" && [ $# -gt 1 ] && _setcfgarg="$2"
|
|
eval `setcfg "$1/target.cfg" $_setcfgarg`
|
|
|
|
[ -z "$btype" ] || [ "${mode%config}" = "$mode" ] || \
|
|
return 1; 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"
|
|
|
|
# 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=""
|
|
[ -z "$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
|
|
}
|
|
|
|
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" ] && e "$elftest" f && return 1
|
|
done; return 0
|
|
}
|
|
|
|
handle_makefile()
|
|
{
|
|
check_makefile "$cdir" && x_ make clean -C "$cdir"
|
|
x_ cp "$config" "$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" "$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$XBMK_THREADS $makeargs || $err "$cdir mk$mode"
|
|
|
|
[ -z "$mkhelper" ] || [ -n "$mode" ] || $mkhelper || \
|
|
$err "$cdir: helper command failed: $mkhelper" # eg 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 $@
|