mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-03-28 15:09:04 +02:00
this is now used in grub, for the FS_PAYLOAD_MODULES option in the make command lbmk should generalise as much logic as possible. in some parts of it, logic is hurrently hardcoded, specific to a given project that lbmk uses, but lbmk is essentially a source-based package manager, like what you might find on a small linux distro, so we need to try to be as generic as possible. lbmk is the "build system of build systems", so it has to work generically with as many of them as possible Signed-off-by: Leah Rowe <leah@libreboot.org>
263 lines
6.7 KiB
Bash
Executable File
263 lines
6.7 KiB
Bash
Executable File
#!/usr/bin/env sh
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
# SPDX-FileCopyrightText: 2022-2023 Alper Nebi Yasak <alpernebiyasak@gmail.com>
|
|
# SPDX-FileCopyrightText: 2022 Ferass El Hafidi <vitali64pmemail@protonmail.com>
|
|
# SPDX-FileCopyrightText: 2023 Leah Rowe <leah@libreboot.org>
|
|
|
|
set -u -e
|
|
|
|
. "include/err.sh"
|
|
. "include/option.sh"
|
|
. "include/git.sh"
|
|
|
|
eval "$(setvars "" xarch cfgsdir codedir config config_name xlang mode \
|
|
elfdir listfile project target target_dir targets tree _f target1 \
|
|
bootstrapargs autoconfargs cmakedir makeargs autogenargs)"
|
|
|
|
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" ;;
|
|
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"
|
|
elfdir="elf/${project}"
|
|
cfgsdir="config/${project}"
|
|
|
|
check_project
|
|
|
|
_cmd="build_projects"
|
|
[ -f "config/${project}/build.list" ] && _cmd="build_targets"
|
|
$_cmd $@
|
|
}
|
|
|
|
build_projects()
|
|
{
|
|
[ $# -gt 0 ] && x_ ./update trees $_f $@
|
|
[ "$mode" = "fetch" ] && eval "fetch_project_repo; return 0;"
|
|
|
|
load_project_config "$cfgsdir"
|
|
|
|
codedir="src/${project}"
|
|
[ -d "$codedir" ] || x_ ./update trees -f "$project"
|
|
|
|
[ "$mode" = "distclean" ] && mode="clean"
|
|
run_make_command || return 0
|
|
}
|
|
|
|
build_targets()
|
|
{
|
|
[ "$elfdir" = "elf/coreboot" ] && \
|
|
elfdir="elf/coreboot_nopayload_DO_NOT_FLASH"
|
|
|
|
[ -d "$cfgsdir" ] || err "directory, $cfgsdir, does not exist"
|
|
|
|
listfile="${cfgsdir}/build.list"
|
|
[ -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=$(items "$cfgsdir") || \
|
|
err "Cannot get options for $cfgsdir"
|
|
[ $# -gt 0 ] && targets=$@
|
|
|
|
[ -z "$mode" ] && x_ mkdir -p "$elfdir"
|
|
handle_targets
|
|
}
|
|
|
|
handle_targets()
|
|
{
|
|
for x in $targets; do
|
|
target="${x}"
|
|
printf "Running 'make %s' for project '%s, target '%s''\n" \
|
|
"$mode" "$project" "$target"
|
|
[ "$project" != "coreboot" ] || [ -n "$mode" ] || \
|
|
[ "$target1" = "utils" ] || \
|
|
x_ ./vendor download $target
|
|
x_ handle_defconfig
|
|
done
|
|
|
|
[ "$target1" = "utils" ] && [ "$project" = "coreboot" ] && return 0
|
|
[ -z "${mode}" ] && printf "Done! Check %s/\n\n" "$elfdir"; return 0
|
|
}
|
|
|
|
handle_defconfig()
|
|
{
|
|
handle_src_tree "$target" || return 0
|
|
|
|
[ "$target1" = "utils" ] && [ "$project" = "coreboot" ] && \
|
|
eval "handle_coreboot_utils \"$tree\"; return 0"
|
|
|
|
for y in "${target_dir}/config"/*; do
|
|
[ -f "$y" ] || continue
|
|
config="$y"
|
|
config_name="${config#"${target_dir}/config/"}"
|
|
|
|
printf "handle/make/config %s %s: handling config %s\n" \
|
|
"$project" "$target" "$config_name"
|
|
|
|
[ -n "$mode" ] || check_config || continue
|
|
handle_makefile
|
|
[ -n "$mode" ] || copy_elf
|
|
done
|
|
}
|
|
|
|
handle_src_tree()
|
|
{
|
|
target_dir="${cfgsdir}/${target}"
|
|
[ "$mode" = "fetch" ] && eval "fetch_project_trees; return 1;"
|
|
|
|
load_project_config "$target_dir"
|
|
|
|
x_ mkdir -p "${elfdir}/${target}"
|
|
|
|
[ -z "$tree" ] && err "handle_src_tree $project/$tree: tree unset"
|
|
|
|
codedir="src/${project}/${tree}"
|
|
|
|
if [ ! -d "$codedir" ]; then
|
|
if [ "$mode" = "distclean" ] || \
|
|
[ "$mode" = "crossgcc-clean" ]; then
|
|
printf "Directory %s missing; skipping clean\n" \
|
|
"$codedir" 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)"
|
|
|
|
[ -f "${1}/target.cfg" ] || return 0
|
|
. "${1}/target.cfg" || \
|
|
err "load_project_config ${1}: cannot load target.cfg"; return 0
|
|
}
|
|
|
|
check_cross_compiler()
|
|
{
|
|
for _xarch in $xarch; do
|
|
cbdir="src/coreboot/${tree}"
|
|
[ "$project" != "coreboot" ] && cbdir="src/coreboot/default"
|
|
|
|
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"
|
|
|
|
[ -d "${cbdir}/util/crossgcc/xgcc/${_xarch}/" ] && continue
|
|
x_ make -C "$cbdir" crossgcc-${_xarch%-*} CPUS=$(nproc)
|
|
done
|
|
}
|
|
|
|
check_config()
|
|
{
|
|
[ -f "$config" ] || err "check_config: ${project}/${target}: no config"
|
|
|
|
dest_dir="${elfdir}/${target}/${config_name}"
|
|
# TODO: very hacky check. do it properly (based on build.list)
|
|
for elftest in "${dest_dir}"/*; do
|
|
[ -f "$elftest" ] || continue
|
|
printf "Build already exists, so skipping build\n" 1>&2
|
|
return 1
|
|
done
|
|
x_ mkdir -p "$dest_dir"
|
|
}
|
|
|
|
handle_makefile()
|
|
{
|
|
x_ make clean -C "$codedir"
|
|
x_ cp "$config" "${codedir}/.config"
|
|
[ -n "$mode" ] || make -C "$codedir" silentoldconfig || \
|
|
make -C "$codedir" oldconfig || :
|
|
|
|
run_make_command || err "handle_makefile $codedir: no makefile!"
|
|
|
|
if [ -e "${codedir}/.git" ] && [ "$project" = "u-boot" ] && \
|
|
[ "$mode" = "distclean" ]; then
|
|
x_ git -C "$codedir" clean -fdx
|
|
elif [ "$mode" = "oldconfig" ] || [ "$mode" = "olddefconfig" ] || \
|
|
[ "$mode" = "menuconfig" ] || [ "$mode" = "nconfig" ]; then
|
|
x_ cp "${codedir}/.config" "$config"
|
|
elif [ "$mode" = "savedefconfig" ]; then
|
|
x_ cp "${codedir}/defconfig" "$config"
|
|
fi
|
|
}
|
|
|
|
run_make_command()
|
|
{
|
|
check_cmake "$codedir"
|
|
[ -z "$mode" ] && check_autoconf "$codedir"
|
|
check_makefile "$codedir" || return 1
|
|
|
|
[ "$project" = "coreboot" ] && [ -z "$mode" ] && \
|
|
x_ printf "%s\n" "${version%%-*}" \
|
|
> "${codedir}/.coreboot-version"
|
|
|
|
make $mode -j$(nproc) $makeargs -C "$codedir" || \
|
|
err "run_make $codedir: !make $mode"
|
|
|
|
[ "$mode" != "clean" ] && return 0
|
|
make -C "$codedir" distclean 2>/dev/null || :
|
|
}
|
|
|
|
check_cmake()
|
|
{
|
|
[ -z "${cmakedir}" ] || \
|
|
check_makefile "${1}" || \
|
|
cmake -B "${1}" "${1}/${cmakedir}" || \
|
|
check_makefile "${1}" || \
|
|
err "check_cmake ${1}: can't cmake ${cmakedir}"
|
|
[ -z "${cmakedir}" ] || check_makefile "${1}" || \
|
|
err "check_cmake ${1}: could not generate Makefile"
|
|
return 0
|
|
}
|
|
|
|
check_autoconf()
|
|
{
|
|
(
|
|
_cfgopt=""
|
|
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()
|
|
{
|
|
while read -r f; do
|
|
[ ! -f "${codedir}/$f" ] || \
|
|
x_ cp "${codedir}/${f}" "$dest_dir"
|
|
done < "$listfile"
|
|
x_ make clean -C "$codedir"
|
|
}
|
|
|
|
main $@
|