mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-03-26 05:49:03 +02:00
if coreboot itself is being handled, crossgcc has the correct makeargs, setting the number of build threads. however, other projects can specify "xtree" pointing to a given coreboot tree, and build crossgcc for it. one workaround may be to use trees -d coreboot TREE, but then extra code would have to be written to make it avoid other things like building cbfstool, which is not required for just building crossgcc. the cleanest way to do it is to simply hardcode it. the value is set exactly the same as regular coreboot makeargs. this fixes a bug, where some builds of crossgcc are made on a single thread, rather than using XBMK_THREADS. this patch forces it to always use CPUS=$XBMK_THREADS Signed-off-by: Leah Rowe <leah@libreboot.org>
308 lines
8.9 KiB
Bash
Executable File
308 lines
8.9 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 srcdir premake 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 \
|
|
defconfig postmake mkhelpercfg dry dest_dir mdir badhash`
|
|
|
|
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" && [ "$_f" = "-d" ] && dry=":"
|
|
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"; :
|
|
done && return 1
|
|
|
|
[ -f "config/git/$project/pkg.cfg" ] || $err "'$project' not defined"
|
|
|
|
for d in "elf" "config/data" "config" "src"; do
|
|
eval "${d#*/}dir=\"$d/$project\""
|
|
done; dest_dir="$elfdir"
|
|
listfile="$datadir/build.list"
|
|
[ -f "$listfile" ] || listfile="" # optional on all projects
|
|
|
|
mkhelpercfg="$datadir/mkhelper.cfg"
|
|
e "$mkhelpercfg" f missing && mkhelpercfg="$TMPDIR/mkhelper.cfg" && \
|
|
x_ touch "$mkhelpercfg"
|
|
|
|
targets="$@"
|
|
cmd="build_targets $targets" && singletree "$project" && \
|
|
cmd="build_project"
|
|
|
|
remkdir "${tmpgit%/*}"
|
|
}
|
|
|
|
build_project()
|
|
{
|
|
configure_project "$configdir" || return 0
|
|
[ ! -f "$listfile" ] || $dry elfcheck || return 0
|
|
|
|
[ "$mode" = "distclean" ] && mode="clean"
|
|
run_make_command || return 0
|
|
|
|
[ -n "$mode" ] || $dry copy_elf; return 0
|
|
}
|
|
|
|
build_targets()
|
|
{
|
|
[ -d "$configdir" ] || $err "directory, $configdir, does not exist"
|
|
[ $# -gt 0 ] || targets="$(ls -1 "$configdir")" || $err "!o $configdir"
|
|
|
|
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()
|
|
{
|
|
target_dir="$configdir/$target"
|
|
|
|
[ -f "CHANGELOG" ] || fetch_project "$project"
|
|
configure_project "$target_dir" || return 0
|
|
x_ mkdir -p "$elfdir/$target"
|
|
|
|
chkvars tree
|
|
srcdir="src/$project/$tree"
|
|
|
|
if [ "$mode" = "distclean" ] || [ "$mode" = "crossgcc-clean" ]; then
|
|
[ -d "$srcdir" ] || return 0
|
|
fi
|
|
[ -z "$mode" ] && $dry check_cross_compiler
|
|
|
|
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" ] || $dry copy_elf
|
|
done; return 0
|
|
}
|
|
|
|
configure_project()
|
|
{
|
|
eval `setvars "" xarch xlang build_depend autoconfargs xtree postmake \
|
|
tree_depend makeargs btype mkhelper bootstrapargs premake release \
|
|
badhash`
|
|
|
|
[ -f "$1/target.cfg" ] || btype="auto"
|
|
[ -f "$datadir/mkhelper.cfg" ] && eval `setcfg "$datadir/mkhelper.cfg"`
|
|
|
|
_tcfg="$1/target.cfg"
|
|
while [ -f "$_tcfg" ] || [ "$cmd" != "build_project" ]; 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
|
|
|
|
[ -z "$mode" ] && build_dependencies
|
|
|
|
mdir="$PWD/config/submodule/$project"
|
|
[ -n "$tree" ] && mdir="$mdir/$tree"
|
|
|
|
[ -f "CHANGELOG" ] || check_project_hashes
|
|
|
|
[ "$mode" = "fetch" ] || x_ ./update trees -f "$project" $target
|
|
[ "$mode" = "fetch" ] || return 0
|
|
|
|
[ -f "CHANGELOG" ] && return 1; fetch_${cmd#build_}; return 1
|
|
}
|
|
|
|
build_dependencies()
|
|
{
|
|
for bd in $build_depend; do
|
|
bd_p="${bd%%/*}"; bd_t="${bd##*/}"
|
|
[ -z "$bd_p" ] && $dry $err "$project/$tree: !bd '$bd'"
|
|
[ "${bd##*/}" = "$bd" ] && bd_t=""
|
|
[ -z "$bd_p" ] || $dry ./update trees -b $bd_p $bd_t \
|
|
|| $err "!mk $project/$tree $bd_p/$bd_t"; continue
|
|
done; return 0
|
|
}
|
|
|
|
check_project_hashes()
|
|
{
|
|
x_ mkdir -p cache/hash
|
|
|
|
old_pjhash=""
|
|
[ ! -f "cache/hash/$project$tree" ] || \
|
|
read -r old_pjhash < "cache/hash/$project$tree"
|
|
|
|
x_ rm -f "$TMPDIR/project.list" "$TMPDIR/project.hash" \
|
|
"$TMPDIR/project.tmp"; x_ touch "$TMPDIR/project.tmp"
|
|
x_ touch "$TMPDIR/project.hash"
|
|
|
|
for delcheck in "$datadir" "$configdir/$tree" "$mdir"; do
|
|
[ -d "$delcheck" ] || continue
|
|
find "$delcheck" -type f -not -path "*/.git*/*" \
|
|
>> "$TMPDIR/project.tmp" || \
|
|
$err "!find $delcheck > project.tmp"
|
|
done
|
|
sort "$TMPDIR/project.tmp" > "$TMPDIR/project.list" || \
|
|
$err "!sort project tmp/list"
|
|
|
|
while read -r delcheck; do
|
|
[ -f "$delcheck" ] || continue
|
|
sha512sum "$delcheck" | awk '{print $1}' >> \
|
|
"$TMPDIR/project.hash" || $err "!findhash $delcheck"
|
|
done < "$TMPDIR/project.list"
|
|
|
|
pjhash="$(sha512sum "$TMPDIR/project.hash" | awk '{print $1}')" || :
|
|
badhash="y" && [ "$pjhash" = "$old_pjhash" ] && badhash="n"
|
|
[ -f "cache/hash/$project$tree" ] || badhash="y"
|
|
|
|
printf "%s\n" "$pjhash" > "cache/hash/$project$tree" || \
|
|
$err "!mk cache/hash/$project$tree"
|
|
|
|
[ "$badhash" = "n" ] || rm -Rf "src/$project/$tree" \
|
|
"elf/$project/$tree" "elf/$project/$target" || \
|
|
$err "!rmproject $project $tree"; :
|
|
}
|
|
|
|
check_cross_compiler()
|
|
{
|
|
xgccargs="UPDATED_SUBMODULES=1 CPUS=$XBMK_THREADS"
|
|
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%-*} $xgccargs || \
|
|
make -C "$cbdir" crossgcc-${_xarch%-*} $xgccargs || \
|
|
$err "!mkxgcc $project/$xtree '${_xarch%-*}' '$xgccargs'"
|
|
done; return 0
|
|
}
|
|
|
|
check_defconfig()
|
|
{
|
|
[ -f "$defconfig" ] || $dry $err "$project/$target: missing defconfig"
|
|
dest_dir="$elfdir/$target/${defconfig#"$target_dir/config/"}"
|
|
|
|
$dry elfcheck || return 1 # skip build if a previous one exists
|
|
$dry 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()
|
|
{
|
|
$dry check_makefile "$srcdir" && x_ make clean -C "$srcdir"
|
|
[ -f "$defconfig" ] && x_ cp "$defconfig" "$srcdir/.config"
|
|
[ -n "$mode" ] || [ -n "$btype" ] || $dry make -C \
|
|
"$srcdir" silentoldconfig || make -C "$srcdir" oldconfig || :
|
|
|
|
run_make_command || $err "handle_makefile $srcdir: no makefile!"
|
|
|
|
_copy=".config" && [ "$mode" = "savedefconfig" ] && _copy="defconfig"
|
|
[ "${mode%config}" = "$mode" ] || \
|
|
$dry x_ cp "$srcdir/$_copy" "$defconfig"
|
|
|
|
[ -e "$srcdir/.git" ] && [ "$project" = "u-boot" ] && \
|
|
[ "$mode" = "distclean" ] && $dry x_ git -C "$srcdir" clean -fdx; :
|
|
}
|
|
|
|
run_make_command()
|
|
{
|
|
[ -z "$premake" ] || [ -n "$mode" ] || $premake || $err "!$premake"
|
|
|
|
$dry check_cmake "$srcdir" && [ -z "$mode" ] && $dry check_autoconf \
|
|
"$srcdir"; $dry check_makefile "$srcdir" || return 1
|
|
|
|
$dry make -C "$srcdir" $mode -j$XBMK_THREADS $makeargs || $err "!$mode"
|
|
[ -z "$mkhelper" ] || [ -n "$mode" ] || $mkhelper || $err "!$mkhelper"
|
|
|
|
[ "$mode" = "clean" ] && $dry make -C "$srcdir" distclean || :; :
|
|
}
|
|
|
|
check_cmake()
|
|
{
|
|
[ -z "$cmakedir" ] || $dry check_makefile "$1" || cmake -B "$1" \
|
|
"$1/$cmakedir" || $dry check_makefile "$1" || $err \
|
|
"$1: !cmk $cmakedir"
|
|
[ -z "$cmakedir" ] || $dry 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
|
|
}
|
|
|
|
copy_elf()
|
|
{
|
|
[ -f "$listfile" ] && x_ mkdir -p "$dest_dir" && while read -r f; do
|
|
[ -f "$srcdir/$f" ] && x_ cp "$srcdir/$f" "$dest_dir"
|
|
done < "$listfile"; x_ make clean -C "$srcdir"
|
|
}
|
|
|
|
main $@ || exit 0
|
|
. "$mkhelpercfg"
|
|
$cmd
|