mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-03-26 22:09:03 +02:00
move the coreboot-specific includes into mkhelper.cfg for that project. on some projects, we need variables from mkhelper.cfg to be global, so I was including serprog and coreboot mkhelper.cfg files in this script. instead, set a new variable "mkhelpercfg" pointing to the config file. if it doesn't exist, create and then point to a temporary (empty) mkhelper.cfg file. the rom.sh include has been moved to coreboot mkhelper.cfg The only remaining project-specific logic, in this trees script, is now the coreboot crossgcc handling, but this needs to be there as it's also used to build U-Boot. The way this now works, certain includes are done twice. For example, include/rom.sh will be included once globally, outside of main(), and then again in configure_project(). This means that certain functions will be defined twice. I'm uncertain if shell has anything equivalent to an ifdef guard as in C, but we actually want this here anyway, and it shouldn't cause any problems. It's a bit of a hack, but otherwise results in much cleaner code. Signed-off-by: Leah Rowe <leah@libreboot.org>
296 lines
8.1 KiB
Bash
Executable File
296 lines
8.1 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"
|
|
|
|
eval `setvars "" xarch cdir defconfig cmakedir xlang mode makeargs elfdir cmd \
|
|
project target target_dir targets xtree _f release bootstrapargs mkhelper \
|
|
autoconfargs listfile autogenargs btype tree rev tree_depend build_depend \
|
|
premake postmake mkhelpercfg`
|
|
|
|
main()
|
|
{
|
|
while getopts f:b:m:u:c:x:s:l:n:d: option; do
|
|
[ -n "$_f" ] && $err "only one flag is permitted"
|
|
_f="$1"
|
|
case "$1" in
|
|
-d) mode="" ;;
|
|
-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
|
|
[ -f "$listfile" ] || listfile="" # optional on all projects
|
|
|
|
mkhelpercfg="$datadir/mkhelper.cfg"
|
|
|
|
targets="$@"
|
|
remkdir "${tmpgit%/*}"
|
|
}
|
|
|
|
handle_project()
|
|
{
|
|
cmd="build_targets $targets" && singletree "$project" && \
|
|
cmd="build_project"; $cmd
|
|
|
|
[ -f "$listfile" ] || return 0
|
|
[ -z "$mode" ] && [ "$_f" = "-b" ] && \
|
|
printf "\n\nOK! Check %s/\n\n" "$elfdir"; return 0
|
|
}
|
|
|
|
build_project()
|
|
{
|
|
configure_project "$cfgsdir" || return 0
|
|
|
|
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()
|
|
{
|
|
[ -d "$cfgsdir" ] || $err "directory, $cfgsdir, does not exist"
|
|
|
|
[ $# -gt 0 ] || \
|
|
targets="$(ls -1 "$cfgsdir")" || $err "$cfgsdir: Canot get options"
|
|
|
|
handle_targets
|
|
}
|
|
|
|
handle_targets()
|
|
{
|
|
for x in $targets; do
|
|
[ "$x" = "list" ] && x_ ls -1 "config/$project" && \
|
|
listfile="" && break
|
|
target="$x"
|
|
printf "'make %s', '%s', '%s'\n" "$mode" "$project" "$target"
|
|
x_ handle_defconfig
|
|
[ -n "$mode" ] || [ -z "$postmake" ] || $postmake || \
|
|
$err "$project/$target: !postmake: $postmake"; continue
|
|
done; return 0
|
|
}
|
|
|
|
handle_defconfig()
|
|
{
|
|
handle_src_tree "$target" || return 0
|
|
|
|
for y in "$target_dir/config"/*; do
|
|
[ "$_f" = "-d" ] || [ -f "$y" ] || continue
|
|
[ "$_f" = "-d" ] || 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"
|
|
configure_project "$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"
|
|
|
|
[ -z "$mode" ] && [ "$_f" = "-b" ] && check_cross_compiler; return 0
|
|
}
|
|
|
|
configure_project()
|
|
{
|
|
eval `setvars "" xarch xlang build_depend autoconfargs xtree postmake \
|
|
tree_depend makeargs btype mkhelper bootstrapargs premake release`
|
|
[ -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"`
|
|
|
|
[ "$_f" = "-d" ] && build_depend="" # dry run
|
|
[ "$cmd" = "build_project" ] && break
|
|
[ "$mode" = "fetch" ] || break
|
|
|
|
[ "${_tcfg%/*/target.cfg}" = "${_tcfg%"/$tree/target.cfg"}" ] \
|
|
&& break; _tcfg="${_tcfg%/*/target.cfg}/$tree/target.cfg"
|
|
done
|
|
|
|
[ "$XBMK_RELEASE" = "y" ] && [ "$release" = "n" ] && return 1
|
|
[ -z "$btype" ] || [ "${mode%config}" = "$mode" ] || return 1
|
|
|
|
if [ "$_f" = "-d" ]; then
|
|
:
|
|
elif [ -z "$mode" ]; then
|
|
for bd in $build_depend; do
|
|
bd_project="${bd%%/*}"; bd_tree="${bd##*/}"
|
|
[ -z "$bd_project" ] && \
|
|
$err "$project/$tree: bad bd: '$bd'"
|
|
[ "${bd##*/}" = "$bd" ] && bd_tree=""
|
|
[ -z "$bd_project" ] || ./update trees -b $bd_project \
|
|
$bd_tree || $err "$project/$tree: !bd $bd"
|
|
done
|
|
fi
|
|
|
|
[ "$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%-*} $makeargs || \
|
|
make -C "$cbdir" crossgcc-${_xarch%-*} $makeargs || \
|
|
$err "!mkxgcc $project/$xtree '${_xarch%-*}' '$makeargs'"
|
|
done; return 0
|
|
}
|
|
|
|
check_defconfig()
|
|
{
|
|
[ "$_f" = "-d" ] && return 0
|
|
[ -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()
|
|
{
|
|
[ "$_f" = "-d" ] && return 0 # dry run. assume a build exists.
|
|
|
|
# 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"
|
|
[ -f "$defconfig" ] && x_ cp "$defconfig" "$cdir/.config"
|
|
[ "$_f" = "-d" ] || [ -n "$mode" ] || [ -n "$btype" ] || make -C \
|
|
"$cdir" silentoldconfig || make -C "$cdir" oldconfig || :
|
|
|
|
run_make_command || $err "handle_makefile $cdir: no makefile!"
|
|
[ "$_f" = "-d" ] && return 0
|
|
|
|
_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()
|
|
{
|
|
[ -z "$premake" ] || [ -n "$mode" ] || $premake || $err "!$premake"
|
|
|
|
check_cmake "$cdir" && [ -z "$mode" ] && check_autoconf "$cdir"
|
|
check_makefile "$cdir" || return 1
|
|
|
|
[ "$_f" = "-d" ] || make -C "$cdir" $mode -j$XBMK_THREADS $makeargs \
|
|
|| $err "$cdir mk$mode"
|
|
[ -z "$mkhelper" ] || [ -n "$mode" ] || $mkhelper || $err "!$mkhelper"
|
|
|
|
[ "$_f" = "-d" ] && return 0
|
|
[ "$mode" = "clean" ] && make -C "$cdir" distclean || :; return 0
|
|
}
|
|
|
|
check_cmake()
|
|
{
|
|
[ "$_f" = "-d" ] && return 0 # dry run
|
|
[ -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()
|
|
{
|
|
[ "$_f" = "-d" ] && return 0 # dry run
|
|
(
|
|
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" = "-d" ] && return 0 # dry run
|
|
[ -f "$1/Makefile" ] || [ -f "$1/makefile" ] || \
|
|
[ -f "$1/GNUmakefile" ] || return 1; return 0
|
|
}
|
|
|
|
copy_elf()
|
|
{
|
|
[ "$_f" = "-d" ] && return 0 # dry run
|
|
[ -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 $@
|
|
e "$mkhelpercfg" f missing && mkhelpercfg="$TMPDIR/mkhelper.cfg" && x_ \
|
|
touch "$mkhelpercfg"
|
|
. "$mkhelpercfg"
|
|
handle_project
|