test-pkg 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #!/bin/bash
  2. set -e
  3. TOOLCHAINS_URL='http://autobuild.buildroot.org/toolchains/configs/toolchain-configs.csv'
  4. main() {
  5. local o O opts
  6. local cfg dir pkg random toolchain
  7. local -a toolchains
  8. o='hc:d:p:r:'
  9. O='help,config-snippet:build-dir:package:,random:'
  10. opts="$(getopt -n "${my_name}" -o "${o}" -l "${O}" -- "${@}")"
  11. eval set -- "${opts}"
  12. random=0
  13. while [ ${#} -gt 0 ]; do
  14. case "${1}" in
  15. (-h|--help)
  16. help; exit 0
  17. ;;
  18. (-c|--config-snippet)
  19. cfg="${2}"; shift 2
  20. ;;
  21. (-d|--build-dir)
  22. dir="${2}"; shift 2
  23. ;;
  24. (-p|--package)
  25. pkg="${2}"; shift 2
  26. ;;
  27. (-r|--random)
  28. random="${2}"; shift 2
  29. ;;
  30. (--)
  31. shift; break
  32. ;;
  33. esac
  34. done
  35. if [ -z "${cfg}" ]; then
  36. printf "error: no config snippet specified\n" >&2; exit 1
  37. fi
  38. if [ -z "${dir}" ]; then
  39. dir="${HOME}/br-test-pkg"
  40. fi
  41. # Extract the URLs of the toolchains; drop internal toolchains
  42. # E.g.: http://server/path/to/name.config,arch,libc
  43. # --> http://server/path/to/name.config
  44. toolchains=($(curl -s "${TOOLCHAINS_URL}" \
  45. |sed -r -e 's/,.*//; /internal/d;' \
  46. |if [ ${random} -gt 0 ]; then \
  47. sort -R |head -n ${random}
  48. else
  49. cat
  50. fi |sort
  51. )
  52. )
  53. if [ ${#toolchains[@]} -eq 0 ]; then
  54. printf "error: no toolchain found (networking issue?)\n" >&2; exit 1
  55. fi
  56. for toolchain in "${toolchains[@]}"; do
  57. build_one "${dir}" "${toolchain}" "${cfg}" "${pkg}"
  58. done
  59. }
  60. build_one() {
  61. local dir="${1}"
  62. local url="${2}"
  63. local cfg="${3}"
  64. local pkg="${4}"
  65. local toolchain line skip
  66. # Using basename(1) on a URL works nicely
  67. toolchain="$(basename "${url}" .config)"
  68. printf "%40s: " "${toolchain}"
  69. dir="${dir}/${toolchain}"
  70. mkdir -p "${dir}"
  71. printf "download config"
  72. if ! curl -s "${url}" >"${dir}/.config"; then
  73. printf ": FAILED\n"
  74. return
  75. fi
  76. cat >>"${dir}/.config" <<-_EOF_
  77. BR2_INIT_NONE=y
  78. BR2_SYSTEM_BIN_SH_NONE=y
  79. # BR2_PACKAGE_BUSYBOX is not set
  80. # BR2_TARGET_ROOTFS_TAR is not set
  81. _EOF_
  82. cat "${cfg}" >>"${dir}/.config"
  83. printf ", olddefconfig"
  84. if ! make O="${dir}" olddefconfig >/dev/null 2>&1; then
  85. printf ": FAILED\n"
  86. return
  87. fi
  88. # We want all the options from the snippet to be present as-is (set
  89. # or not set) in the actual .config; if one of them is not, it means
  90. # some dependency from the toolchain or arch is not available, in
  91. # which case this config is untestable and we skip it.
  92. skip=false
  93. while read line; do
  94. if ! grep "^${line}\$" "${dir}/.config" >/dev/null 2>&1; then
  95. printf "%s\n" "${line}"
  96. skip=true
  97. fi
  98. done <"${cfg}" >"${dir}/missing.config"
  99. if ${skip}; then
  100. printf ", SKIPPED\n"
  101. return
  102. fi
  103. # Remove file, it's empty anyway.
  104. rm -f "${dir}/missing.config"
  105. if [ -n "${pkg}" ]; then
  106. printf ", dirclean"
  107. if ! make O="${dir}" "${pkg}-dirclean" >> "${dir}/logfile" 2>&1; then
  108. printf ": FAILED\n"
  109. return
  110. fi
  111. fi
  112. printf ", build"
  113. # shellcheck disable=SC2086
  114. if ! make O="${dir}" ${pkg} >> "${dir}/logfile" 2>&1; then
  115. printf ": FAILED\n"
  116. return
  117. fi
  118. printf ": OK\n"
  119. }
  120. help() {
  121. cat <<_EOF_
  122. test-pkg: test-build a package against various toolchains and architectures
  123. The supplied config snippet is appended to each toolchain config, the
  124. resulting configuration is checked to ensure it still contains all options
  125. specified in the snippet; if any is missing, the build is skipped, on the
  126. assumption that the package under test requires a toolchain or architecture
  127. feature that is missing.
  128. In case failures are noticed, you can fix the package and just re-run the
  129. same command again; it will re-run the test where it failed. If you did
  130. specify a package (with -p), the package build dir will be removed first.
  131. The list of toolchains is retrieved from the Buildroot autobuilders, available
  132. at ${TOOLCHAINS_URL}.
  133. Options:
  134. -h, --help
  135. Print this help.
  136. -c CFG, --config-snippet CFG
  137. Use the CFG file as the source for the config snippet. This file
  138. should contain all the config options required to build a package.
  139. -d DIR, --build-dir DIR
  140. Do the builds in directory DIR, one sub-dir per toolchain.
  141. -p PKG, --package PKG
  142. Test-build the package PKG, by running 'make PKG'; if not specified,
  143. just runs 'make'.
  144. -r N, --random N
  145. Limit the tests to the N randomly selected toolchains, instead of
  146. building with all toolchains.
  147. Example:
  148. Testing libcec would require a config snippet that contains:
  149. BR2_PACKAGE_LIBCEC=y
  150. Testing libcurl with openSSL support would require a snippet such as:
  151. BR2_PACKAGE_OPENSSL=y
  152. BR2_PACKAGE_LIBCURL=y
  153. _EOF_
  154. }
  155. my_name="${0##*/}"
  156. main "${@}"