2017-06-05 09:37:40 +02:00
|
|
|
#!/usr/bin/env bash
|
2017-02-08 21:15:24 +01:00
|
|
|
set -e
|
|
|
|
|
|
|
|
TOOLCHAINS_URL='http://autobuild.buildroot.org/toolchains/configs/toolchain-configs.csv'
|
|
|
|
|
|
|
|
main() {
|
|
|
|
local o O opts
|
2017-02-08 21:15:27 +01:00
|
|
|
local cfg dir pkg random toolchain
|
2017-04-07 13:16:17 +02:00
|
|
|
local ret nb nb_skip nb_fail nb_legal nb_tc build_dir
|
2017-02-08 21:15:24 +01:00
|
|
|
local -a toolchains
|
|
|
|
|
2017-02-08 21:15:27 +01:00
|
|
|
o='hc:d:p:r:'
|
|
|
|
O='help,config-snippet:build-dir:package:,random:'
|
2017-02-12 15:53:05 +01:00
|
|
|
opts="$(getopt -n "${my_name}" -o "${o}" -l "${O}" -- "${@}")"
|
2017-02-08 21:15:24 +01:00
|
|
|
eval set -- "${opts}"
|
|
|
|
|
2017-02-08 21:15:27 +01:00
|
|
|
random=0
|
2017-02-08 21:15:24 +01:00
|
|
|
while [ ${#} -gt 0 ]; do
|
|
|
|
case "${1}" in
|
|
|
|
(-h|--help)
|
|
|
|
help; exit 0
|
|
|
|
;;
|
|
|
|
(-c|--config-snippet)
|
|
|
|
cfg="${2}"; shift 2
|
|
|
|
;;
|
|
|
|
(-d|--build-dir)
|
|
|
|
dir="${2}"; shift 2
|
|
|
|
;;
|
|
|
|
(-p|--package)
|
|
|
|
pkg="${2}"; shift 2
|
|
|
|
;;
|
2017-02-08 21:15:27 +01:00
|
|
|
(-r|--random)
|
|
|
|
random="${2}"; shift 2
|
|
|
|
;;
|
2017-02-08 21:15:24 +01:00
|
|
|
(--)
|
|
|
|
shift; break
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
if [ -z "${cfg}" ]; then
|
|
|
|
printf "error: no config snippet specified\n" >&2; exit 1
|
|
|
|
fi
|
2017-02-12 15:53:06 +01:00
|
|
|
if [ ! -e "${cfg}" ]; then
|
|
|
|
printf "error: %s: no such file\n" "${cfg}" >&2; exit 1
|
|
|
|
fi
|
2017-02-08 21:15:24 +01:00
|
|
|
if [ -z "${dir}" ]; then
|
|
|
|
dir="${HOME}/br-test-pkg"
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Extract the URLs of the toolchains; drop internal toolchains
|
|
|
|
# E.g.: http://server/path/to/name.config,arch,libc
|
|
|
|
# --> http://server/path/to/name.config
|
2017-02-12 15:53:05 +01:00
|
|
|
toolchains=($(curl -s "${TOOLCHAINS_URL}" \
|
|
|
|
|sed -r -e 's/,.*//; /internal/d;' \
|
|
|
|
|if [ ${random} -gt 0 ]; then \
|
|
|
|
sort -R |head -n ${random}
|
|
|
|
else
|
|
|
|
cat
|
|
|
|
fi |sort
|
|
|
|
)
|
2017-02-08 21:15:24 +01:00
|
|
|
)
|
|
|
|
|
2017-04-06 20:18:42 +02:00
|
|
|
nb_tc="${#toolchains[@]}"
|
|
|
|
if [ ${nb_tc} -eq 0 ]; then
|
2017-02-08 21:15:24 +01:00
|
|
|
printf "error: no toolchain found (networking issue?)\n" >&2; exit 1
|
|
|
|
fi
|
|
|
|
|
2017-02-12 15:53:09 +01:00
|
|
|
nb=0
|
|
|
|
nb_skip=0
|
|
|
|
nb_fail=0
|
2017-04-07 13:16:17 +02:00
|
|
|
nb_legal=0
|
2017-04-07 13:16:16 +02:00
|
|
|
for toolchainconfig in "${toolchains[@]}"; do
|
2017-04-06 20:18:42 +02:00
|
|
|
: $((nb++))
|
2017-04-07 13:16:16 +02:00
|
|
|
# Using basename(1) on a URL works nicely
|
|
|
|
toolchain="$(basename "${toolchainconfig}" .config)"
|
|
|
|
build_dir="${dir}/${toolchain}"
|
|
|
|
printf "%40s [%*d/%d]: " "${toolchain}" ${#nb_tc} ${nb} ${nb_tc}
|
|
|
|
build_one "${build_dir}" "${toolchainconfig}" "${cfg}" "${pkg}" && ret=0 || ret=${?}
|
2017-02-12 15:53:09 +01:00
|
|
|
case ${ret} in
|
2017-04-06 20:18:42 +02:00
|
|
|
(0) printf "OK\n";;
|
|
|
|
(1) : $((nb_skip++)); printf "SKIPPED\n";;
|
|
|
|
(2) : $((nb_fail++)); printf "FAILED\n";;
|
2017-04-07 13:16:17 +02:00
|
|
|
(3) : $((nb_legal++)); printf "FAILED\n";;
|
2017-02-12 15:53:09 +01:00
|
|
|
esac
|
2017-02-08 21:15:24 +01:00
|
|
|
done
|
2017-02-12 15:53:09 +01:00
|
|
|
|
2017-04-07 13:16:17 +02:00
|
|
|
printf "%d builds, %d skipped, %d build failed, %d legal-info failed\n" \
|
|
|
|
${nb} ${nb_skip} ${nb_fail} ${nb_legal}
|
2017-02-08 21:15:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
build_one() {
|
|
|
|
local dir="${1}"
|
|
|
|
local url="${2}"
|
|
|
|
local cfg="${3}"
|
|
|
|
local pkg="${4}"
|
|
|
|
|
|
|
|
mkdir -p "${dir}"
|
|
|
|
|
|
|
|
if ! curl -s "${url}" >"${dir}/.config"; then
|
2017-02-12 15:53:09 +01:00
|
|
|
return 2
|
2017-02-08 21:15:24 +01:00
|
|
|
fi
|
|
|
|
|
2017-07-21 03:05:19 +02:00
|
|
|
cat "support/config-fragments/minimal.config" "${cfg}" >>"${dir}/.config"
|
2017-02-08 21:15:24 +01:00
|
|
|
|
2017-03-09 16:15:21 +01:00
|
|
|
if ! make O="${dir}" olddefconfig > "${dir}/logfile" 2>&1; then
|
2017-02-12 15:53:09 +01:00
|
|
|
return 2
|
2017-02-08 21:15:24 +01:00
|
|
|
fi
|
|
|
|
# We want all the options from the snippet to be present as-is (set
|
|
|
|
# or not set) in the actual .config; if one of them is not, it means
|
|
|
|
# some dependency from the toolchain or arch is not available, in
|
|
|
|
# which case this config is untestable and we skip it.
|
2017-02-12 15:53:07 +01:00
|
|
|
# We don't care about the locale to sort in, as long as both sort are
|
|
|
|
# done in the same locale.
|
|
|
|
comm -23 <(sort "${cfg}") <(sort "${dir}/.config") >"${dir}/missing.config"
|
|
|
|
if [ -s "${dir}/missing.config" ]; then
|
2017-02-12 15:53:09 +01:00
|
|
|
return 1
|
2017-02-08 21:15:25 +01:00
|
|
|
fi
|
|
|
|
# Remove file, it's empty anyway.
|
|
|
|
rm -f "${dir}/missing.config"
|
2017-02-08 21:15:24 +01:00
|
|
|
|
|
|
|
if [ -n "${pkg}" ]; then
|
|
|
|
if ! make O="${dir}" "${pkg}-dirclean" >> "${dir}/logfile" 2>&1; then
|
2017-02-12 15:53:09 +01:00
|
|
|
return 2
|
2017-02-08 21:15:24 +01:00
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
# shellcheck disable=SC2086
|
|
|
|
if ! make O="${dir}" ${pkg} >> "${dir}/logfile" 2>&1; then
|
2017-02-12 15:53:09 +01:00
|
|
|
return 2
|
2017-02-08 21:15:24 +01:00
|
|
|
fi
|
2017-04-07 13:16:17 +02:00
|
|
|
|
|
|
|
# legal-info done systematically, because some packages have different
|
|
|
|
# sources depending on the configuration (e.g. lua-5.2 vs. lua-5.3)
|
|
|
|
if [ -n "${pkg}" ]; then
|
|
|
|
if ! make O="${dir}" "${pkg}-legal-info" >> "${dir}/logfile" 2>&1; then
|
|
|
|
return 3
|
|
|
|
fi
|
|
|
|
fi
|
2017-02-08 21:15:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
help() {
|
|
|
|
cat <<_EOF_
|
|
|
|
test-pkg: test-build a package against various toolchains and architectures
|
|
|
|
|
|
|
|
The supplied config snippet is appended to each toolchain config, the
|
|
|
|
resulting configuration is checked to ensure it still contains all options
|
|
|
|
specified in the snippet; if any is missing, the build is skipped, on the
|
|
|
|
assumption that the package under test requires a toolchain or architecture
|
|
|
|
feature that is missing.
|
|
|
|
|
|
|
|
In case failures are noticed, you can fix the package and just re-run the
|
|
|
|
same command again; it will re-run the test where it failed. If you did
|
|
|
|
specify a package (with -p), the package build dir will be removed first.
|
|
|
|
|
|
|
|
The list of toolchains is retrieved from the Buildroot autobuilders, available
|
|
|
|
at ${TOOLCHAINS_URL}.
|
|
|
|
|
|
|
|
Options:
|
|
|
|
|
|
|
|
-h, --help
|
|
|
|
Print this help.
|
|
|
|
|
|
|
|
-c CFG, --config-snippet CFG
|
|
|
|
Use the CFG file as the source for the config snippet. This file
|
|
|
|
should contain all the config options required to build a package.
|
|
|
|
|
|
|
|
-d DIR, --build-dir DIR
|
|
|
|
Do the builds in directory DIR, one sub-dir per toolchain.
|
|
|
|
|
|
|
|
-p PKG, --package PKG
|
|
|
|
Test-build the package PKG, by running 'make PKG'; if not specified,
|
|
|
|
just runs 'make'.
|
|
|
|
|
2017-02-08 21:15:27 +01:00
|
|
|
-r N, --random N
|
|
|
|
Limit the tests to the N randomly selected toolchains, instead of
|
|
|
|
building with all toolchains.
|
|
|
|
|
2017-02-08 21:15:24 +01:00
|
|
|
Example:
|
|
|
|
|
|
|
|
Testing libcec would require a config snippet that contains:
|
|
|
|
BR2_PACKAGE_LIBCEC=y
|
|
|
|
|
|
|
|
Testing libcurl with openSSL support would require a snippet such as:
|
|
|
|
BR2_PACKAGE_OPENSSL=y
|
|
|
|
BR2_PACKAGE_LIBCURL=y
|
|
|
|
|
|
|
|
_EOF_
|
|
|
|
}
|
|
|
|
|
|
|
|
my_name="${0##*/}"
|
|
|
|
main "${@}"
|