Francois Perrad | 9cbe364 | 2017-06-05 09:37:40 +0200 | [diff] [blame] | 1 | #!/usr/bin/env bash |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 2 | set -e |
| 3 | |
Arnout Vandecappelle | e7b9afa | 2017-07-21 03:05:24 +0200 | [diff] [blame] | 4 | TOOLCHAINS_CSV='support/config-fragments/autobuild/toolchain-configs.csv' |
Vadim Kochan | a946813 | 2019-03-01 14:33:42 +0200 | [diff] [blame] | 5 | TEMP_CONF="" |
| 6 | |
| 7 | do_clean() { |
| 8 | if [ ! -z "${TEMP_CONF}" ]; then |
| 9 | rm -f "${TEMP_CONF}" |
| 10 | fi |
| 11 | } |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 12 | |
| 13 | main() { |
| 14 | local o O opts |
Thomas De Schampheleire | 989cda1 | 2019-02-05 22:21:41 +0100 | [diff] [blame] | 15 | local cfg dir pkg random toolchains_csv toolchain all number mode |
Thomas De Schampheleire | 72bf486 | 2019-02-05 22:21:42 +0100 | [diff] [blame] | 16 | local ret nb nb_skip nb_fail nb_legal nb_tc build_dir keep |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 17 | local -a toolchains |
Vadim Kochan | a946813 | 2019-03-01 14:33:42 +0200 | [diff] [blame] | 18 | local pkg_br_name |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 19 | |
Thomas De Schampheleire | 72bf486 | 2019-02-05 22:21:42 +0100 | [diff] [blame] | 20 | o='hakc:d:n:p:r:t:' |
| 21 | O='help,all,keep,config-snippet:,build-dir:,number:,package:,random:,toolchains-csv:' |
Yann E. MORIN | 67a221b | 2017-02-12 15:53:05 +0100 | [diff] [blame] | 22 | opts="$(getopt -n "${my_name}" -o "${o}" -l "${O}" -- "${@}")" |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 23 | eval set -- "${opts}" |
| 24 | |
Yann E. MORIN | 9e7885d | 2017-02-08 21:15:27 +0100 | [diff] [blame] | 25 | random=0 |
Thomas Petazzoni | 0534da0 | 2018-03-23 22:48:14 +0100 | [diff] [blame] | 26 | all=0 |
Thomas De Schampheleire | 72bf486 | 2019-02-05 22:21:42 +0100 | [diff] [blame] | 27 | keep=0 |
Thomas Petazzoni | 0534da0 | 2018-03-23 22:48:14 +0100 | [diff] [blame] | 28 | number=0 |
| 29 | mode=0 |
Arnout Vandecappelle | ed59f81 | 2017-07-25 23:36:12 +0200 | [diff] [blame] | 30 | toolchains_csv="${TOOLCHAINS_CSV}" |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 31 | while [ ${#} -gt 0 ]; do |
| 32 | case "${1}" in |
| 33 | (-h|--help) |
| 34 | help; exit 0 |
| 35 | ;; |
Thomas Petazzoni | 0534da0 | 2018-03-23 22:48:14 +0100 | [diff] [blame] | 36 | (-a|--all) |
| 37 | all=1; shift 1 |
| 38 | ;; |
Thomas De Schampheleire | 72bf486 | 2019-02-05 22:21:42 +0100 | [diff] [blame] | 39 | (-k|--keep) |
| 40 | keep=1; shift 1 |
| 41 | ;; |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 42 | (-c|--config-snippet) |
| 43 | cfg="${2}"; shift 2 |
| 44 | ;; |
| 45 | (-d|--build-dir) |
| 46 | dir="${2}"; shift 2 |
| 47 | ;; |
Thomas Petazzoni | 0534da0 | 2018-03-23 22:48:14 +0100 | [diff] [blame] | 48 | (-n|--number) |
| 49 | number="${2}"; shift 2 |
| 50 | ;; |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 51 | (-p|--package) |
| 52 | pkg="${2}"; shift 2 |
| 53 | ;; |
Yann E. MORIN | 9e7885d | 2017-02-08 21:15:27 +0100 | [diff] [blame] | 54 | (-r|--random) |
| 55 | random="${2}"; shift 2 |
| 56 | ;; |
Arnout Vandecappelle | ed59f81 | 2017-07-25 23:36:12 +0200 | [diff] [blame] | 57 | (-t|--toolchains-csv) |
| 58 | toolchains_csv="${2}"; shift 2 |
| 59 | ;; |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 60 | (--) |
| 61 | shift; break |
| 62 | ;; |
| 63 | esac |
| 64 | done |
Vadim Kochan | a946813 | 2019-03-01 14:33:42 +0200 | [diff] [blame] | 65 | |
| 66 | trap do_clean INT TERM HUP EXIT |
| 67 | |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 68 | if [ -z "${cfg}" ]; then |
Vadim Kochan | a946813 | 2019-03-01 14:33:42 +0200 | [diff] [blame] | 69 | pkg_br_name="${pkg//-/_}" |
| 70 | pkg_br_name="BR2_PACKAGE_${pkg_br_name^^}" |
| 71 | TEMP_CONF=$(mktemp /tmp/test-${pkg}-config.XXXXXX) |
| 72 | echo "${pkg_br_name}=y" > ${TEMP_CONF} |
| 73 | cfg="${TEMP_CONF}" |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 74 | fi |
Yann E. MORIN | 55bbbe0 | 2017-02-12 15:53:06 +0100 | [diff] [blame] | 75 | if [ ! -e "${cfg}" ]; then |
| 76 | printf "error: %s: no such file\n" "${cfg}" >&2; exit 1 |
| 77 | fi |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 78 | if [ -z "${dir}" ]; then |
| 79 | dir="${HOME}/br-test-pkg" |
| 80 | fi |
| 81 | |
Thomas Petazzoni | 0534da0 | 2018-03-23 22:48:14 +0100 | [diff] [blame] | 82 | if [ ${random} -gt 0 ]; then |
| 83 | mode=$((mode+1)) |
| 84 | fi |
| 85 | |
| 86 | if [ ${number} -gt 0 ]; then |
| 87 | mode=$((mode+1)) |
| 88 | fi |
| 89 | |
| 90 | if [ ${all} -eq 1 ]; then |
| 91 | mode=$((mode+1)) |
| 92 | fi |
| 93 | |
| 94 | # Default mode is to test the N first toolchains, which have been |
| 95 | # chosen to be a good selection of toolchains. |
| 96 | if [ ${mode} -eq 0 ] ; then |
Thomas Petazzoni | d13c3d1 | 2018-04-05 21:50:15 +0200 | [diff] [blame] | 97 | number=6 |
Thomas Petazzoni | 0534da0 | 2018-03-23 22:48:14 +0100 | [diff] [blame] | 98 | elif [ ${mode} -gt 1 ] ; then |
| 99 | printf "error: --all, --number and --random are mutually exclusive\n" >&2; exit 1 |
| 100 | fi |
| 101 | |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 102 | # Extract the URLs of the toolchains; drop internal toolchains |
| 103 | # E.g.: http://server/path/to/name.config,arch,libc |
| 104 | # --> http://server/path/to/name.config |
Thomas Petazzoni | 9272eb4 | 2017-10-29 18:14:37 +0100 | [diff] [blame] | 105 | toolchains=($(sed -r -e 's/,.*//; /internal/d; /^#/d; /^$/d;' "${toolchains_csv}" \ |
Yann E. MORIN | 67a221b | 2017-02-12 15:53:05 +0100 | [diff] [blame] | 106 | |if [ ${random} -gt 0 ]; then \ |
| 107 | sort -R |head -n ${random} |
Thomas Petazzoni | 0534da0 | 2018-03-23 22:48:14 +0100 | [diff] [blame] | 108 | elif [ ${number} -gt 0 ]; then \ |
| 109 | head -n ${number} |
| 110 | else |
| 111 | sort |
| 112 | fi |
Yann E. MORIN | 67a221b | 2017-02-12 15:53:05 +0100 | [diff] [blame] | 113 | ) |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 114 | ) |
| 115 | |
Yann E. MORIN | 762cd7c | 2017-04-06 20:18:42 +0200 | [diff] [blame] | 116 | nb_tc="${#toolchains[@]}" |
| 117 | if [ ${nb_tc} -eq 0 ]; then |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 118 | printf "error: no toolchain found (networking issue?)\n" >&2; exit 1 |
| 119 | fi |
| 120 | |
Yann E. MORIN | 5bf12ad | 2017-02-12 15:53:09 +0100 | [diff] [blame] | 121 | nb=0 |
| 122 | nb_skip=0 |
| 123 | nb_fail=0 |
Yann E. MORIN | 37308b9 | 2017-04-07 13:16:17 +0200 | [diff] [blame] | 124 | nb_legal=0 |
Arnout Vandecappelle | 92b10f6 | 2017-04-07 13:16:16 +0200 | [diff] [blame] | 125 | for toolchainconfig in "${toolchains[@]}"; do |
Yann E. MORIN | 762cd7c | 2017-04-06 20:18:42 +0200 | [diff] [blame] | 126 | : $((nb++)) |
Arnout Vandecappelle | 92b10f6 | 2017-04-07 13:16:16 +0200 | [diff] [blame] | 127 | toolchain="$(basename "${toolchainconfig}" .config)" |
| 128 | build_dir="${dir}/${toolchain}" |
| 129 | printf "%40s [%*d/%d]: " "${toolchain}" ${#nb_tc} ${nb} ${nb_tc} |
| 130 | build_one "${build_dir}" "${toolchainconfig}" "${cfg}" "${pkg}" && ret=0 || ret=${?} |
Yann E. MORIN | 5bf12ad | 2017-02-12 15:53:09 +0100 | [diff] [blame] | 131 | case ${ret} in |
Yann E. MORIN | 762cd7c | 2017-04-06 20:18:42 +0200 | [diff] [blame] | 132 | (0) printf "OK\n";; |
| 133 | (1) : $((nb_skip++)); printf "SKIPPED\n";; |
| 134 | (2) : $((nb_fail++)); printf "FAILED\n";; |
Yann E. MORIN | 37308b9 | 2017-04-07 13:16:17 +0200 | [diff] [blame] | 135 | (3) : $((nb_legal++)); printf "FAILED\n";; |
Yann E. MORIN | 5bf12ad | 2017-02-12 15:53:09 +0100 | [diff] [blame] | 136 | esac |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 137 | done |
Yann E. MORIN | 5bf12ad | 2017-02-12 15:53:09 +0100 | [diff] [blame] | 138 | |
Yann E. MORIN | 37308b9 | 2017-04-07 13:16:17 +0200 | [diff] [blame] | 139 | printf "%d builds, %d skipped, %d build failed, %d legal-info failed\n" \ |
| 140 | ${nb} ${nb_skip} ${nb_fail} ${nb_legal} |
Heiko Thiery | 5093435 | 2019-10-10 12:24:26 +0200 | [diff] [blame] | 141 | |
| 142 | return $((nb_fail + nb_legal)) |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 143 | } |
| 144 | |
| 145 | build_one() { |
| 146 | local dir="${1}" |
Arnout Vandecappelle | e7b9afa | 2017-07-21 03:05:24 +0200 | [diff] [blame] | 147 | local toolchainconfig="${2}" |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 148 | local cfg="${3}" |
| 149 | local pkg="${4}" |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 150 | |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 151 | mkdir -p "${dir}" |
| 152 | |
Nasser Afshin | 8ca206e | 2018-11-14 11:16:05 +0330 | [diff] [blame] | 153 | CONFIG_= support/kconfig/merge_config.sh -O "${dir}" \ |
Arnout Vandecappelle | de46cc9 | 2017-07-21 03:05:30 +0200 | [diff] [blame] | 154 | "${toolchainconfig}" "support/config-fragments/minimal.config" "${cfg}" \ |
Yann E. MORIN | 2664022 | 2018-07-08 12:26:59 +0200 | [diff] [blame] | 155 | >> "${dir}/logfile" 2>&1 |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 156 | # We want all the options from the snippet to be present as-is (set |
| 157 | # or not set) in the actual .config; if one of them is not, it means |
| 158 | # some dependency from the toolchain or arch is not available, in |
| 159 | # which case this config is untestable and we skip it. |
Yann E. MORIN | aeabb58 | 2017-02-12 15:53:07 +0100 | [diff] [blame] | 160 | # We don't care about the locale to sort in, as long as both sort are |
| 161 | # done in the same locale. |
| 162 | comm -23 <(sort "${cfg}") <(sort "${dir}/.config") >"${dir}/missing.config" |
| 163 | if [ -s "${dir}/missing.config" ]; then |
Yann E. MORIN | 5bf12ad | 2017-02-12 15:53:09 +0100 | [diff] [blame] | 164 | return 1 |
Yann E. MORIN | d5c58ce | 2017-02-08 21:15:25 +0100 | [diff] [blame] | 165 | fi |
| 166 | # Remove file, it's empty anyway. |
| 167 | rm -f "${dir}/missing.config" |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 168 | |
| 169 | if [ -n "${pkg}" ]; then |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 170 | if ! make O="${dir}" "${pkg}-dirclean" >> "${dir}/logfile" 2>&1; then |
Yann E. MORIN | 5bf12ad | 2017-02-12 15:53:09 +0100 | [diff] [blame] | 171 | return 2 |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 172 | fi |
| 173 | fi |
| 174 | |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 175 | # shellcheck disable=SC2086 |
Adam Duskett | bbf32a7 | 2019-01-02 10:49:20 -0500 | [diff] [blame] | 176 | if ! BR_FORCE_CHECK_DEPENDENCIES=YES make O="${dir}" ${pkg} >> "${dir}/logfile" 2>&1; then |
Yann E. MORIN | 5bf12ad | 2017-02-12 15:53:09 +0100 | [diff] [blame] | 177 | return 2 |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 178 | fi |
Yann E. MORIN | 37308b9 | 2017-04-07 13:16:17 +0200 | [diff] [blame] | 179 | |
| 180 | # legal-info done systematically, because some packages have different |
| 181 | # sources depending on the configuration (e.g. lua-5.2 vs. lua-5.3) |
Yann E. MORIN | 17cd914 | 2018-01-07 23:50:05 +0100 | [diff] [blame] | 182 | if ! make O="${dir}" legal-info >> "${dir}/logfile" 2>&1; then |
| 183 | return 3 |
Yann E. MORIN | 37308b9 | 2017-04-07 13:16:17 +0200 | [diff] [blame] | 184 | fi |
Thomas De Schampheleire | 72bf486 | 2019-02-05 22:21:42 +0100 | [diff] [blame] | 185 | |
| 186 | # If we get here, the build was successful. Clean up the build/host |
| 187 | # directories to save disk space, unless 'keep' was set. |
| 188 | if [ ${keep} -ne 1 ]; then |
| 189 | make O="${dir}" clean >> "${dir}/logfile" 2>&1 |
| 190 | fi |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 191 | } |
| 192 | |
| 193 | help() { |
| 194 | cat <<_EOF_ |
| 195 | test-pkg: test-build a package against various toolchains and architectures |
| 196 | |
| 197 | The supplied config snippet is appended to each toolchain config, the |
| 198 | resulting configuration is checked to ensure it still contains all options |
| 199 | specified in the snippet; if any is missing, the build is skipped, on the |
| 200 | assumption that the package under test requires a toolchain or architecture |
| 201 | feature that is missing. |
| 202 | |
| 203 | In case failures are noticed, you can fix the package and just re-run the |
| 204 | same command again; it will re-run the test where it failed. If you did |
| 205 | specify a package (with -p), the package build dir will be removed first. |
| 206 | |
Arnout Vandecappelle | ed59f81 | 2017-07-25 23:36:12 +0200 | [diff] [blame] | 207 | The list of toolchains is retrieved from ${TOOLCHAINS_CSV}. |
| 208 | Only the external toolchains are tried, because building a Buildroot toolchain |
| 209 | would take too long. An alternative toolchains CSV file can be specified with |
| 210 | the -t option. This file should have lines consisting of the path to the |
| 211 | toolchain config fragment and the required host architecture, separated by a |
| 212 | comma. The config fragments should contain only the toolchain and architecture |
| 213 | settings. |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 214 | |
Thomas Petazzoni | 0534da0 | 2018-03-23 22:48:14 +0100 | [diff] [blame] | 215 | By default, a useful subset of toolchains is tested. If needed, all |
| 216 | toolchains can be tested (-a), an arbitrary number of toolchains (-n |
| 217 | in order, -r for random). |
| 218 | |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 219 | Options: |
| 220 | |
| 221 | -h, --help |
| 222 | Print this help. |
| 223 | |
| 224 | -c CFG, --config-snippet CFG |
| 225 | Use the CFG file as the source for the config snippet. This file |
| 226 | should contain all the config options required to build a package. |
| 227 | |
| 228 | -d DIR, --build-dir DIR |
| 229 | Do the builds in directory DIR, one sub-dir per toolchain. |
| 230 | |
| 231 | -p PKG, --package PKG |
| 232 | Test-build the package PKG, by running 'make PKG'; if not specified, |
| 233 | just runs 'make'. |
| 234 | |
Thomas Petazzoni | 0534da0 | 2018-03-23 22:48:14 +0100 | [diff] [blame] | 235 | -a, --all |
| 236 | Test all toolchains, instead of the default subset defined by |
| 237 | Buildroot developers. |
| 238 | |
| 239 | -n N, --number N |
| 240 | Test N toolchains, in the order defined in the toolchain CSV |
| 241 | file. |
| 242 | |
Yann E. MORIN | 9e7885d | 2017-02-08 21:15:27 +0100 | [diff] [blame] | 243 | -r N, --random N |
Thomas Petazzoni | 0534da0 | 2018-03-23 22:48:14 +0100 | [diff] [blame] | 244 | Limit the tests to the N randomly selected toolchains. |
Yann E. MORIN | 9e7885d | 2017-02-08 21:15:27 +0100 | [diff] [blame] | 245 | |
Arnout Vandecappelle | ed59f81 | 2017-07-25 23:36:12 +0200 | [diff] [blame] | 246 | -t CSVFILE, --toolchains-csv CSVFILE |
| 247 | CSV file containing the paths to config fragments of toolchains to |
| 248 | try. If not specified, the toolchains in ${TOOLCHAINS_CSV} will be |
| 249 | used. |
| 250 | |
Thomas De Schampheleire | 72bf486 | 2019-02-05 22:21:42 +0100 | [diff] [blame] | 251 | -k, --keep |
| 252 | Keep the build directories even if the build succeeds. |
| 253 | Note: the logfile and configuration is always retained, even without |
| 254 | this option. |
| 255 | |
Yann E. MORIN | 47d5da8 | 2017-02-08 21:15:24 +0100 | [diff] [blame] | 256 | Example: |
| 257 | |
| 258 | Testing libcec would require a config snippet that contains: |
| 259 | BR2_PACKAGE_LIBCEC=y |
| 260 | |
| 261 | Testing libcurl with openSSL support would require a snippet such as: |
| 262 | BR2_PACKAGE_OPENSSL=y |
| 263 | BR2_PACKAGE_LIBCURL=y |
| 264 | |
| 265 | _EOF_ |
| 266 | } |
| 267 | |
| 268 | my_name="${0##*/}" |
| 269 | main "${@}" |