mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-07-11 14:02:52 +02:00
62cc895c3c
in the future, we may start downloading files that aren't blobs, such as mxm port configs (on mainboards that use MXM graphics) this directory will contain all of those files generally change the language used, across lbmk, to make use of "vendorfile" instead of "blob" Signed-off-by: Leah Rowe <leah@libreboot.org>
301 lines
8.2 KiB
Python
Executable File
301 lines
8.2 KiB
Python
Executable File
#!/usr/bin/env sh
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
# SPDX-FileCopyrightText: 2022 Alper Nebi Yasak <alpernebiyasak@gmail.com>
|
|
# SPDX-FileCopyrightText: 2022 Ferass El Hafidi <vitali64pmemail@protonmail.com>
|
|
# SPDX-FileCopyrightText: 2023 Leah Rowe <leah@libreboot.org>
|
|
|
|
[ "x${DEBUG+set}" = 'xset' ] && set -v
|
|
set -u -e
|
|
|
|
. "include/err.sh"
|
|
. "include/option.sh"
|
|
|
|
read projectname < projectname
|
|
read version < version
|
|
|
|
export LOCALVERSION="-${projectname}-${version}"
|
|
|
|
eval "$(setvars "" arch cfgsdir codedir config config_name crossgcc_ada mode \
|
|
elfdir listfile project romtype target target_dir targets tree cbfstool _f)"
|
|
|
|
tmpclean="$(mktemp -d -t makeclean.XXXXXXXXXX)"
|
|
|
|
main()
|
|
{
|
|
while getopts b:m:u:c:x: option
|
|
do
|
|
_f="${1}"
|
|
case "${1}" in
|
|
-b) : ;;
|
|
-u) mode="oldconfig" ;;
|
|
-m) mode="menuconfig" ;;
|
|
-c) mode="distclean" ;;
|
|
-x) mode="crossgcc-clean" ;;
|
|
*) err "Invalid option" ;;
|
|
esac
|
|
shift; project="${OPTARG#src/}"; shift
|
|
done
|
|
[ -z ${_f} ] && err "flag not specified (-m, -u, -b, -c or -x)"
|
|
[ -z ${project} ] && err "project name not specified"
|
|
|
|
if [ ! -f "config/${project}/build.list" ]; then
|
|
build_projects $@
|
|
else
|
|
build_targets $@
|
|
fi
|
|
}
|
|
|
|
build_projects()
|
|
{
|
|
[ $# -gt 0 ] && x_ ./update project build ${_f} ${@}
|
|
codedir="src/${project}"
|
|
|
|
[ -d "${codedir}" ] || x_ ./update project repo "${project}"
|
|
|
|
if [ "${project}" = "uefitool" ]; then
|
|
(
|
|
x_ cd src/uefitool
|
|
cmake UEFIExtract/ || [ -f Makefile ] || \
|
|
err "build_targets: !cmake UEFIExtract/"
|
|
)
|
|
fi
|
|
|
|
[ "${mode}" = "distclean" ] && mode="clean"
|
|
run_make_command || return 0
|
|
}
|
|
|
|
build_targets()
|
|
{
|
|
elfdir="elf/${project}"
|
|
|
|
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
|
|
targets=$(listitems "${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" ] || [ ! -z ${mode} ] || \
|
|
x_ ./update vendor download ${target}
|
|
x_ handle_defconfig
|
|
done
|
|
|
|
[ -z ${mode} ] || return 0
|
|
printf "Done! The files are stored under %s/\n\n" "${elfdir}"
|
|
}
|
|
|
|
handle_defconfig()
|
|
{
|
|
handle_src_tree "${target}" || 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}"
|
|
|
|
[ ! -z ${mode} ] || check_config || continue
|
|
handle_makefile
|
|
[ ! -z ${mode} ] || copy_elf
|
|
done
|
|
}
|
|
|
|
handle_src_tree()
|
|
{
|
|
target_dir="${cfgsdir}/${target}"
|
|
x_ mkdir -p "${elfdir}/${target}"
|
|
|
|
eval "$(setvars "" arch tree)"
|
|
romtype="normal"
|
|
|
|
[ -f "${target_dir}/target.cfg" ] || \
|
|
err "handle_src_tree: ${target_dir}: missing target.cfg"
|
|
|
|
# Override the above defaults using target.cfg
|
|
. "${target_dir}/target.cfg" # source
|
|
|
|
[ -z ${tree} ] && \
|
|
err "handle_src_tree: ${target_dir}: tree undefined"
|
|
[ -z ${arch} ] && \
|
|
err "handle_src_tree: ${target_dir}: undefined cpu type"
|
|
|
|
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 project trees "${project}" "${target}"
|
|
elif [ "${mode}" = "distclean" ] || \
|
|
[ "${mode}" = "crossgcc-clean" ]; then
|
|
[ -f "${tmpclean}/${tree}" ] && return 1
|
|
touch "${tmpclean}/${tree}"
|
|
fi
|
|
|
|
# u-boot and coreboot are both compiled with coreboot's crossgcc
|
|
if [ "${project}" = "coreboot" ] || [ "${project}" = "u-boot" ]; then
|
|
[ ! -z ${mode} ] || check_cross_compiler || \
|
|
err "handle_src_tree ${project}/${target}: crossgcc"
|
|
cbfstool="cbutils/${tree}/cbfstool"
|
|
[ -f "${cbfstool}" ] || x_ ./build coreboot utils "${tree}"
|
|
fi
|
|
}
|
|
|
|
# set up cross-compiler (coreboot crossgcc) for u-boot and coreboot
|
|
# (seabios and grub currently use hostcc, not crossgcc)
|
|
check_cross_compiler()
|
|
{
|
|
[ "${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" # not u-boot (e.g. linux)
|
|
[ "${project}" = "u-boot" ] && \
|
|
cbdir="src/coreboot/cros" # u-boot only used on coreboot/cros
|
|
|
|
# only true if not building coreboot:
|
|
ctarget="${cbdir#src/coreboot/}"
|
|
[ -d "${cbdir}" ] || \
|
|
x_ ./update project trees coreboot ${ctarget}
|
|
|
|
if [ "${arch}" = "x86_32" ] || [ "${arch}" = "x86_64" ]; then
|
|
[ -d "${cbdir}/util/crossgcc/xgcc/i386-elf/" ] || \
|
|
make -C "${cbdir}" crossgcc-i386 CPUS=$(nproc) || \
|
|
return 1
|
|
case "$(uname -m)" in
|
|
x86*|i*86|amd64) : ;;
|
|
*) export CROSS_COMPILE=i386-elf- ;;
|
|
esac
|
|
elif [ "${arch}" = "ARMv7" ]; then
|
|
[ -d "${cbdir}/util/crossgcc/xgcc/arm-eabi/" ] || \
|
|
make -C "${cbdir}" crossgcc-arm CPUS=$(nproc) || \
|
|
return 1
|
|
case "$(uname -m)" in
|
|
arm|arm32|armv6*|armv7*) : ;;
|
|
*) export CROSS_COMPILE=arm-eabi- ;;
|
|
esac
|
|
elif [ "${arch}" = "AArch64" ]; then
|
|
[ -d "${cbdir}/util/crossgcc/xgcc/aarch64-elf/" ] || \
|
|
make -C "${cbdir}" crossgcc-aarch64 CPUS=$(nproc) || \
|
|
return 1
|
|
# aarch64 also needs armv7 toolchain for arm-trusted-firmware
|
|
[ -d "${cbdir}/util/crossgcc/xgcc/arm-eabi/" ] || \
|
|
make -C "${cbdir}" crossgcc-arm CPUS=$(nproc) || \
|
|
return 1
|
|
case "$(uname -m)" in
|
|
arm64|aarch64) : ;;
|
|
*) export CROSS_COMPILE=aarch64-elf- ;;
|
|
esac
|
|
fi
|
|
|
|
# we *must* ensure that u-boot's build system uses crossgcc first
|
|
export PATH="$(pwd)/${cbdir}/util/crossgcc/xgcc/bin:$PATH"
|
|
}
|
|
|
|
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"
|
|
[ ! -z ${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}" = "menuconfig" ]; then
|
|
x_ cp "${codedir}/.config" "${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 -C "${codedir}" -j$(nproc) ${mode}
|
|
[ "${mode}" != "clean" ] && return 0
|
|
make -C "${codedir}" distclean 2>/dev/null || :
|
|
}
|
|
|
|
copy_elf()
|
|
{
|
|
[ "${project}" != "coreboot" ] || x_ modify_coreboot_rom
|
|
while read f; do
|
|
[ ! -f "${codedir}/$f" ] || \
|
|
x_ cp "${codedir}/${f}" "${dest_dir}/"
|
|
done < ${listfile}
|
|
|
|
x_ make clean -C "${codedir}"
|
|
}
|
|
|
|
modify_coreboot_rom()
|
|
{
|
|
rompath="${codedir}/build/coreboot.rom"
|
|
[ -f "${rompath}" ] || \
|
|
err "modify_coreboot_rom: does not exist: ${rompath}"
|
|
tmprom="$(mktemp -t rom.XXXXXXXXXX)"
|
|
x_ rm -f "${tmprom}"
|
|
|
|
if [ "${romtype}" = "d8d16sas" ]; then
|
|
# pike2008 roms hang seabios. an empty rom will override
|
|
# the built-in one, thus disabling all execution of it
|
|
x_ touch "${tmprom}"
|
|
for deviceID in "0072" "3050"; do
|
|
x_ "${cbfstool}" "${rompath}" add -f "${tmprom}" \
|
|
-n "pci1000,${deviceID}.rom" -t raw
|
|
done
|
|
elif [ "${romtype}" = "i945 laptop" ]; then
|
|
# for bucts-based installation method from factory bios
|
|
x_ dd if="${rompath}" of="${tmprom}" bs=1 \
|
|
skip=$(($(stat -c %s "${rompath}") - 0x10000)) \
|
|
count=64k
|
|
x_ dd if="${tmprom}" of="${rompath}" bs=1 \
|
|
seek=$(($(stat -c %s "${rompath}") - 0x20000)) \
|
|
count=64k conv=notrunc
|
|
fi
|
|
x_ rm -f "${tmprom}"
|
|
}
|
|
|
|
main $@
|