mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-07-12 14:32:42 +02:00
90ac30b163
only call crossgcc for coreboot and u-boot, but use hostcc for everything else. simplify the checking of which architecture to compile for. "arch" in target.cfg files has been modified, to allow further simplification. without this patch, the logic currently only *barely* avoids using crossgcc on things like utils, and only works in practise because, in practise, lbmk only works on x86_64 anyway. the new logic, as per this patch, is simpler and more robust. Signed-off-by: Leah Rowe <leah@libreboot.org>
260 lines
6.8 KiB
Bash
Executable File
260 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 Leah Rowe <leah@libreboot.org>
|
|
|
|
set -u -e
|
|
|
|
. "include/err.sh"
|
|
. "include/option.sh"
|
|
. "include/git.sh"
|
|
|
|
export LOCALVERSION="-${projectname}-${version%%-*}"
|
|
|
|
eval "$(setvars "" arch cfgsdir codedir config config_name crossgcc_ada mode \
|
|
elfdir listfile project romtype target target_dir targets tree _f target1)"
|
|
|
|
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"
|
|
|
|
if [ -f "config/${project}/build.list" ]; then
|
|
build_targets $@
|
|
else
|
|
build_projects $@
|
|
fi
|
|
}
|
|
|
|
build_projects()
|
|
{
|
|
[ $# -gt 0 ] && x_ ./update trees ${_f} ${@}
|
|
|
|
if [ "${mode}" = "fetch" ]; then
|
|
fetch_project_repo
|
|
return 0
|
|
fi
|
|
|
|
codedir="src/${project}"
|
|
[ -d "${codedir}" ] || x_ ./update trees -f "${project}"
|
|
|
|
if [ "${project}" = "uefitool" ]; then
|
|
(
|
|
x_ cd src/uefitool
|
|
cmake UEFIExtract/ || [ -f Makefile ] || \
|
|
err "build_projects: !cmake UEFIExtract/"
|
|
) || err "can't build cmake on uefiextract"
|
|
fi
|
|
|
|
[ "${mode}" = "distclean" ] && mode="clean"
|
|
run_make_command || return 0
|
|
}
|
|
|
|
build_targets()
|
|
{
|
|
elfdir="elf/${project}"
|
|
[ "${elfdir}" = "elf/coreboot" ] && \
|
|
elfdir="elf/coreboot_nopayload_DO_NOT_FLASH"
|
|
|
|
cfgsdir="config/${project}"
|
|
[ -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}" ] || \
|
|
x_ ./vendor download ${target}
|
|
x_ handle_defconfig
|
|
done
|
|
|
|
[ "${target1}" = "utils" ] && [ "${project}" = "coreboot" ] && return 0
|
|
[ -z "${mode}" ] || return 0
|
|
printf "Done! The files are stored under %s/\n\n" "${elfdir}"
|
|
}
|
|
|
|
handle_defconfig()
|
|
{
|
|
handle_src_tree "${target}" || return 0
|
|
|
|
if [ "${target1}" = "utils" ] && [ "${project}" = "coreboot" ]; then
|
|
handle_coreboot_utils "${tree}"
|
|
return 0
|
|
fi
|
|
|
|
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()
|
|
{
|
|
romtype="normal"
|
|
target_dir="${cfgsdir}/${target}"
|
|
|
|
if [ "${mode}" = "fetch" ]; then
|
|
fetch_project_trees
|
|
return 1
|
|
fi
|
|
|
|
x_ mkdir -p "${elfdir}/${target}"
|
|
eval "$(setvars "" arch tree)"
|
|
|
|
. "${target_dir}/target.cfg" || \
|
|
err "handle_src_tree ${target_dir}: cannot load target.cfg"
|
|
|
|
[ -z "${arch}" ] && err "handle_src_tree $project/$tree: arch unset"
|
|
[ -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 doesn't exist; skipping clean\n" \
|
|
"${codedir}" 1>&2
|
|
return 1
|
|
fi
|
|
x_ ./update trees -f "${project}" "${target}"
|
|
fi
|
|
|
|
[ "${target1}" = "utils" ] && [ "${project}" = "coreboot" ] && return 0
|
|
[ "$project" != "coreboot" ] && [ "$project" != "u-boot" ] && return 0
|
|
|
|
# u-boot and coreboot are both compiled with coreboot's crossgcc
|
|
[ -z "${mode}" ] || return 0
|
|
check_cross_compiler
|
|
}
|
|
|
|
# set up cross-compiler (coreboot crossgcc) for u-boot and coreboot
|
|
# (seabios and grub currently use hostcc, not crossgcc)
|
|
check_cross_compiler()
|
|
{
|
|
[ "$project" = "u-boot" ] || [ "$project" = "coreboot" ] || return 0
|
|
[ -z "${arch}" ] && return 0
|
|
|
|
_arch="${arch}"
|
|
[ "${arch}" = "aarch64-elf" ] && _arch="aarch64-elf arm-eabi"
|
|
|
|
[ "${crossgcc_ada}" = "y" ] || [ "${crossgcc_ada}" = "n" ] || \
|
|
crossgcc_ada="y"
|
|
[ "${crossgcc_ada}" = "y" ] || export BUILD_LANGUAGES=c
|
|
|
|
cbdir="src/coreboot/${tree}"
|
|
[ "${project}" != "coreboot" ] && cbdir="src/coreboot/default"
|
|
x_ ./update trees -f coreboot ${cbdir#src/coreboot/}
|
|
|
|
for xarch in ${_arch}; do
|
|
[ -d "${cbdir}/util/crossgcc/xgcc/${xarch}/" ] && continue
|
|
x_ make -C "${cbdir}" crossgcc-${xarch%-*} CPUS=$(nproc)
|
|
done
|
|
|
|
# we *must* ensure that u-boot's build system uses crossgcc first
|
|
export PATH="${PWD}/${cbdir}/util/crossgcc/xgcc/bin:$PATH"
|
|
export CROSS_COMPILE="${_arch% *}-"
|
|
}
|
|
|
|
check_config()
|
|
{
|
|
[ ! -f "${config}" ] && \
|
|
err "check_config: ${project}/${target}: configs missing"
|
|
|
|
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()
|
|
{
|
|
[ -f "${codedir}/Makefile" ] || [ -f "${codedir}/makefile" ] || \
|
|
[ -f "${codedir}/GNUmakefile" ] || return 1
|
|
[ "${project}" = "coreboot" ] && [ -z "${mode}" ] && \
|
|
x_ printf "%s\n" "${version%%-*}" >"$codedir/.coreboot-version"
|
|
|
|
x_ make ${mode} -j$(nproc) -C "${codedir}"
|
|
|
|
[ "${mode}" != "clean" ] && return 0
|
|
make -C "${codedir}" distclean 2>/dev/null || :
|
|
}
|
|
|
|
copy_elf()
|
|
{
|
|
while read -r f; do
|
|
[ ! -f "${codedir}/$f" ] || \
|
|
x_ cp "${codedir}/${f}" "${dest_dir}/"
|
|
done < "${listfile}"
|
|
|
|
x_ make clean -C "${codedir}"
|
|
}
|
|
|
|
main $@
|