Files
lbmk/script/update/trees
Leah Rowe f72a72af96 don't download projects on release archives
the changelog file is only present in releases, so
use the presence of this file for the test.

someone who wants to fetch projects within a release
archive can simply use the git repo, or delete the file.

Signed-off-by: Leah Rowe <leah@libreboot.org>
2024-01-21 22:11:00 +00:00

267 lines
6.8 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-2024 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 xtree)"
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}"
remkdir "${tmpgit%/*}"
check_project
_cmd="build_projects"
[ -f "config/${project}/build.list" ] && _cmd="build_targets"
$_cmd $@
}
build_projects()
{
[ $# -gt 0 ] && x_ ./update trees $_f $@
[ "$mode" = "fetch" ] && [ ! -f "CHANGELOG" ] && \
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" ] && [ ! -f "CHANGELOG" ] && \
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"
[ -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"
[ -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 $@