mirror of
https://gitlab.com/buildroot.org/buildroot.git
synced 2026-08-08 00:20:38 -09:00
The trap was initially introduced inc5fa9308ea(core/br2-external: properly report unexpected errors), in 2017, to catch all unexpected errors, back when a single file was generated, and errors emitted to stderr. Since commitd027cd75d0(core: generate all br2-external files in one go), in 2019 the single output file 'ofile' is no longer created, as multiple output files were then introduced, while messages for *expected errors* were redirected to a Makefile variable assignment emitted on stdout, at which point the script just exits (in error); expected failures only occur in do_validate(). Unexpected errors can only occur on failure to create, or write to, output files, either '.br2-external.mk' in do_validate() or do_mk(), or any of the kconfig fragments in do_kconfig(). Cause for failure to create those can only be a no-space-left-on-device condition, as they are created in a directory that was just created by the script earlier in main(), and thus has the necessary mode; failure to create that directory is now caught explicitly. A trap on ERR is not called when the shell exits explicitly with a call to 'exit', thus, only failures to create or write to output file would be caught. In that case, we are better off not trying to write to those files anyway: failure to create the file would already be reported by the shell on stderr, while disk-full would not allow to store the output anyway... In any case, the script exits in error, which is going to be caught by the caller, which will terminate. So, drop the trap altogether. As a side effect, that squelches a shellcheck error. Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr> Signed-off-by: Romain Naour <romain.naour@smile.fr>
279 lines
9.5 KiB
Bash
Executable File
279 lines
9.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -e
|
|
|
|
# This script must be able to run with bash-3.1, so it can't use
|
|
# associative arrays. Instead, it emulates them using 'eval'. It
|
|
# can however use indexed arrays, supported since at least bash-3.0.
|
|
|
|
# The names of the br2-external trees, once validated.
|
|
declare -a BR2_EXT_NAMES
|
|
|
|
# URL to manual for help in converting old br2-external trees.
|
|
# Escape '#' so that make does not consider it a comment.
|
|
MANUAL_URL='https://buildroot.org/manual.html\#br2-external-converting'
|
|
|
|
main() {
|
|
local OPT OPTARG
|
|
local br2_ext outputdir
|
|
|
|
while getopts :d: OPT; do
|
|
case "${OPT}" in
|
|
d) outputdir="${OPTARG}";;
|
|
:) error "option '%s' expects a mandatory argument\n" "${OPTARG}";;
|
|
\?) error "unknown option '%s'\n" "${OPTARG}";;
|
|
esac
|
|
done
|
|
# Forget options; keep only positional args
|
|
shift $((OPTIND-1))
|
|
|
|
if [ -z "${outputdir}" ]; then
|
|
error "no output directory specified (-d)\n"
|
|
fi
|
|
|
|
if ! mkdir -p "${outputdir}"; then
|
|
error "Cannot create output directory '%s'\n" "${outputdir}"
|
|
fi
|
|
|
|
do_validate "${outputdir}" ${@//:/ }
|
|
do_mk "${outputdir}"
|
|
do_kconfig "${outputdir}"
|
|
}
|
|
|
|
# Validates the br2-external trees passed as arguments. Makes each of
|
|
# them canonical and store them in the global arrays BR2_EXT_NAMES
|
|
# and BR2_EXT_PATHS.
|
|
#
|
|
# Note: since this script is always first called from Makefile context
|
|
# to generate the Makefile fragment before it is called to generate the
|
|
# Kconfig snippet, we're sure that any error in do_validate will be
|
|
# interpreted in Makefile context. Going up to generating the Kconfig
|
|
# snippet means that there were no error.
|
|
#
|
|
do_validate() {
|
|
local outputdir="${1}"
|
|
local br2_ext
|
|
shift
|
|
|
|
if [ ${#} -eq 0 ]; then
|
|
# No br2-external tree is valid
|
|
return
|
|
fi
|
|
|
|
for br2_ext in "${@}"; do
|
|
do_validate_one "${br2_ext}"
|
|
done >"${outputdir}/.br2-external.mk"
|
|
}
|
|
|
|
do_validate_one() {
|
|
local br2_ext="${1}"
|
|
local br2_name br2_desc br2_ver n d
|
|
|
|
if [ ! -d "${br2_ext}" ]; then
|
|
error "'%s': no such file or directory\n" "${br2_ext}"
|
|
fi
|
|
if [ ! -r "${br2_ext}" -o ! -x "${br2_ext}" ]; then
|
|
error "'%s': permission denied\n" "${br2_ext}"
|
|
fi
|
|
if [ ! -f "${br2_ext}/external.desc" ]; then
|
|
error "'%s': does not have an 'external.desc'. See %s\n" \
|
|
"${br2_ext}" "${MANUAL_URL}"
|
|
fi
|
|
br2_name="$(sed -r -e '/^name: +(.*)$/!d; s//\1/' "${br2_ext}/external.desc")"
|
|
if [ -z "${br2_name}" ]; then
|
|
error "'%s/external.desc': does not define the name\n" "${br2_ext}"
|
|
fi
|
|
# Only ASCII chars in [A-Za-z0-9_] are permitted
|
|
n="$(sed -r -e 's/[A-Za-z0-9_]//g' <<<"${br2_name}" )"
|
|
if [ -n "${n}" ]; then
|
|
# Escape '$' so that it gets printed
|
|
error "'%s': name '%s' contains invalid chars: '%s'\n" \
|
|
"${br2_ext}" "${br2_name//\$/\$\$}" "${n//\$/\$\$}"
|
|
fi
|
|
eval d="\"\${BR2_EXT_PATHS_${br2_name}}\""
|
|
if [ -n "${d}" ]; then
|
|
error "'%s': name '%s' is already used in '%s'\n" \
|
|
"${br2_ext}" "${br2_name}" "${d}"
|
|
fi
|
|
br2_desc="$(sed -r -e '/^desc: +(.*)$/!d; s//\1/' "${br2_ext}/external.desc")"
|
|
if [ ! -f "${br2_ext}/external.mk" ]; then
|
|
error "'%s/external.mk': no such file or directory\n" "${br2_ext}"
|
|
fi
|
|
if [ ! -f "${br2_ext}/Config.in" ]; then
|
|
error "'%s/Config.in': no such file or directory\n" "${br2_ext}"
|
|
fi
|
|
|
|
# Register this br2-external tree, use an absolute canonical path
|
|
br2_ext="$( cd "${br2_ext}"; pwd )"
|
|
br2_ver="$( support/scripts/setlocalversion "${br2_ext}" )"
|
|
BR2_EXT_NAMES+=( "${br2_name}" )
|
|
eval BR2_EXT_PATHS_${br2_name}="\"\${br2_ext}\""
|
|
eval BR2_EXT_VERS_${br2_name}="\"\${br2_ver}\""
|
|
eval BR2_EXT_DESCS_${br2_name}="\"\${br2_desc:-\${br2_name}}\""
|
|
}
|
|
|
|
# Generate the .mk snippet that defines makefile variables
|
|
# for the br2-external tree
|
|
do_mk() {
|
|
local outputdir="${1}"
|
|
local br2_name br2_desc br2_ext br2_ver
|
|
|
|
{
|
|
printf '#\n# Automatically generated file; DO NOT EDIT.\n#\n'
|
|
printf '\n'
|
|
|
|
printf 'BR2_EXTERNAL ?='
|
|
for br2_name in "${BR2_EXT_NAMES[@]}"; do
|
|
eval br2_ext="\"\${BR2_EXT_PATHS_${br2_name}}\""
|
|
printf ' %s' "${br2_ext}"
|
|
done
|
|
printf '\n'
|
|
|
|
printf 'export BR2_EXTERNAL_NAMES = \n'
|
|
printf 'BR2_EXTERNAL_DIRS = \n'
|
|
printf 'BR2_EXTERNAL_MKS = \n'
|
|
|
|
if [ ${#BR2_EXT_NAMES[@]} -eq 0 ]; then
|
|
printf '\n'
|
|
printf '# No br2-external tree defined.\n'
|
|
return
|
|
fi
|
|
|
|
for br2_name in "${BR2_EXT_NAMES[@]}"; do
|
|
eval br2_desc="\"\${BR2_EXT_DESCS_${br2_name}}\""
|
|
eval br2_ext="\"\${BR2_EXT_PATHS_${br2_name}}\""
|
|
eval br2_ver="\"\${BR2_EXT_VERS_${br2_name}}\""
|
|
printf '\n'
|
|
printf 'BR2_EXTERNAL_NAMES += %s\n' "${br2_name}"
|
|
printf 'BR2_EXTERNAL_DIRS += %s\n' "${br2_ext}"
|
|
printf 'BR2_EXTERNAL_MKS += %s/external.mk\n' "${br2_ext}"
|
|
printf 'export BR2_EXTERNAL_%s_PATH = %s\n' "${br2_name}" "${br2_ext}"
|
|
printf 'export BR2_EXTERNAL_%s_DESC = %s\n' "${br2_name}" "${br2_desc}"
|
|
printf 'export BR2_EXTERNAL_%s_VERSION = %s\n' "${br2_name}" "${br2_ver}"
|
|
done
|
|
} >"${outputdir}/.br2-external.mk"
|
|
}
|
|
|
|
# Generate the kconfig snippets for the br2-external tree.
|
|
do_kconfig() {
|
|
local outputdir="${1}"
|
|
local br2_name br2_desc br2_ext br2_ver br2
|
|
local -a items
|
|
|
|
items=(
|
|
paths
|
|
menus
|
|
toolchains
|
|
jpeg
|
|
openssl
|
|
skeleton
|
|
init
|
|
linux
|
|
)
|
|
|
|
for br2 in "${items[@]}"; do
|
|
{
|
|
printf '#\n# Automatically generated file; DO NOT EDIT.\n#\n'
|
|
printf '\n'
|
|
if [ ${#BR2_EXT_NAMES[@]} -eq 0 ]; then
|
|
printf '# No br2-external tree defined.\n'
|
|
fi
|
|
} >"${outputdir}/.br2-external.in.${br2}"
|
|
done
|
|
if [ ${#BR2_EXT_NAMES[@]} -eq 0 ]; then
|
|
return
|
|
fi
|
|
|
|
printf 'menu "External options"\n\n' >>"${outputdir}/.br2-external.in.menus"
|
|
|
|
{
|
|
printf 'config BR2_EXTERNAL_NAMES\n'
|
|
printf '\tstring\n'
|
|
# Use star-expansion: we really one a single arg.
|
|
printf '\tdefault "%s"\n' "${BR2_EXT_NAMES[*]}"
|
|
printf '\n'
|
|
} >>"${outputdir}/.br2-external.in.paths"
|
|
|
|
for br2_name in "${BR2_EXT_NAMES[@]}"; do
|
|
eval br2_desc="\"\${BR2_EXT_DESCS_${br2_name}}\""
|
|
eval br2_ext="\"\${BR2_EXT_PATHS_${br2_name}}\""
|
|
eval br2_ver="\"\${BR2_EXT_VERS_${br2_name}}\""
|
|
|
|
{
|
|
printf 'config BR2_EXTERNAL_%s_PATH\n' "${br2_name}"
|
|
printf '\tstring\n'
|
|
printf '\tdefault "%s"\n' "${br2_ext}"
|
|
printf 'config BR2_EXTERNAL_%s_VERSION\n' "${br2_name}"
|
|
printf '\tstring\n'
|
|
printf '\tdefault "%s"\n' "${br2_ver}"
|
|
printf '\n'
|
|
} >>"${outputdir}/.br2-external.in.paths"
|
|
|
|
{
|
|
if [ ${#BR2_EXT_NAMES[@]} -gt 1 ]; then
|
|
printf 'menu "%s"\n' "${br2_desc}"
|
|
fi
|
|
printf 'comment "%s (in %s)"\n' "${br2_desc}" "${br2_ext}"
|
|
printf 'source "%s/Config.in"\n' "${br2_ext}"
|
|
if [ ${#BR2_EXT_NAMES[@]} -gt 1 ]; then
|
|
printf 'endmenu # %s\n' "${br2_name}"
|
|
fi
|
|
printf '\n'
|
|
} >>"${outputdir}/.br2-external.in.menus"
|
|
|
|
if [ -f "${br2_ext}/provides/toolchains.in" ]; then
|
|
printf 'comment "Toolchains from: %s"\n' "${br2_desc}"
|
|
printf 'source "%s/provides/toolchains.in"\n' "${br2_ext}"
|
|
printf '\n'
|
|
else
|
|
printf '# No toolchain from: %s\n\n' "${br2_desc}"
|
|
fi >>"${outputdir}/.br2-external.in.toolchains"
|
|
|
|
if [ -f "${br2_ext}/provides/jpeg.in" ]; then
|
|
printf 'comment "jpeg from: %s"\n' "${br2_desc}"
|
|
printf 'source "%s/provides/jpeg.in"\n' "${br2_ext}"
|
|
printf '\n'
|
|
else
|
|
printf '# No jpeg from: %s\n\n' "${br2_desc}"
|
|
fi >>"${outputdir}/.br2-external.in.jpeg"
|
|
|
|
if [ -f "${br2_ext}/provides/openssl.in" ]; then
|
|
printf 'comment "openssl from: %s"\n' "${br2_desc}"
|
|
printf 'source "%s/provides/openssl.in"\n' "${br2_ext}"
|
|
printf '\n'
|
|
else
|
|
printf '# No openssl from: %s\n\n' "${br2_desc}"
|
|
fi >>"${outputdir}/.br2-external.in.openssl"
|
|
|
|
if [ -f "${br2_ext}/provides/skeleton.in" ]; then
|
|
printf 'comment "skeleton from: %s"\n' "${br2_desc}"
|
|
printf 'source "%s/provides/skeleton.in"\n' "${br2_ext}"
|
|
printf '\n'
|
|
else
|
|
printf '# No skeleton from: %s\n\n' "${br2_desc}"
|
|
fi >>"${outputdir}/.br2-external.in.skeleton"
|
|
|
|
if [ -f "${br2_ext}/provides/init.in" ]; then
|
|
printf 'comment "init from: %s"\n' "${br2_desc}"
|
|
printf 'source "%s/provides/init.in"\n' "${br2_ext}"
|
|
printf '\n'
|
|
else
|
|
printf '# No init from: %s\n\n' "${br2_desc}"
|
|
fi >>"${outputdir}/.br2-external.in.init"
|
|
|
|
if [ -f "${br2_ext}/linux/Config.ext.in" ]; then
|
|
printf 'comment "linux extension from: %s"\n' "${br2_desc}"
|
|
printf 'source "%s/linux/Config.ext.in"\n' "${br2_ext}"
|
|
printf '\n'
|
|
else
|
|
printf '# No linux extension from: %s\n\n' "${br2_desc}"
|
|
fi >>"${outputdir}/.br2-external.in.linux"
|
|
done
|
|
|
|
printf 'endmenu\n' >>"${outputdir}/.br2-external.in.menus"
|
|
}
|
|
|
|
error() { local fmt="${1}"; shift; printf "BR2_EXTERNAL_ERROR = ${fmt}" "${@}"; exit 1; }
|
|
|
|
my_name="${0##*/}"
|
|
main "${@}"
|