run.sh 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. #!/bin/bash
  2. set -eo pipefail
  3. TESTS_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
  4. export TESTS_DIR="$TESTS_DIR"
  5. CYAN='\033[1;36m'
  6. BLUE='\033[1;34m'
  7. YELLOW='\033[1;33m'
  8. GREEN='\033[1;32m'
  9. NC='\033[0m'
  10. ARGS_CPP=""
  11. ARGS_VALID_CPP_STANDARDS=",11,14,17,20,23,"
  12. ARGS_CPP_STANDARDS=","
  13. ARGS_CPP_VERSIONS=","
  14. ARGS_TESTS=","
  15. ARGS_CPP_BITS=""
  16. for arg in "$@"; do
  17. if [[ "$arg" == test-* ]]; then
  18. ARGS_TESTS="${ARGS_TESTS}${arg},"
  19. continue
  20. fi
  21. if [[ "$arg" == "32" || "$arg" == "64" ]]; then
  22. if [[ -n "$ARGS_CPP_BITS" ]]; then
  23. echo Expected at most one bits-argument: 32 or 64
  24. exit 1
  25. fi
  26. ARGS_CPP_BITS="$arg"
  27. continue
  28. fi
  29. if [[ "$ARGS_VALID_CPP_STANDARDS" == *,$arg,* ]]; then
  30. ARGS_CPP_STANDARDS="$ARGS_CPP_STANDARDS$arg,"
  31. else
  32. if [[ "$arg" == v* ]]; then
  33. ARGS_CPP_VERSIONS="$ARGS_CPP_VERSIONS${arg:1},"
  34. else
  35. if [[ -n "$ARGS_CPP" ]]; then
  36. echo Expected just one non-version argument: g++, clang++ or msvc, but found "$ARGS_CPP" and "$arg"
  37. exit 1
  38. fi
  39. if [[ ! "$arg" == "g++" && ! "$arg" == "clang++" && ! "$arg" == "msvc" ]]; then
  40. echo Expected just one non-version argument: g++, clang++ or msvc, but "$arg" found
  41. exit 1
  42. fi
  43. ARGS_CPP="$arg"
  44. fi
  45. fi
  46. done
  47. if [[ ! "$ARGS_TESTS" == "," ]]; then
  48. echo [INFO] Filter tests: ${ARGS_TESTS:1:${#ARGS_TESTS}-2}
  49. fi
  50. if [[ ! "$ARGS_CPP" == "" ]]; then
  51. echo [INFO] Filter CPP: "$ARGS_CPP"
  52. fi
  53. if [[ ! "$ARGS_CPP_STANDARDS" == "," ]]; then
  54. echo [INFO] Filter standards: ${ARGS_CPP_STANDARDS:1:${#ARGS_CPP_STANDARDS}-2}
  55. fi
  56. if [[ ! "$ARGS_CPP_VERSIONS" == "," ]]; then
  57. echo [INFO] Filter versions: ${ARGS_CPP_VERSIONS:1:${#ARGS_CPP_VERSIONS}-2}
  58. fi
  59. if [[ ! "$ARGS_CPP_BITS" == "" ]]; then
  60. echo [INFO] Filter target arch.: "$ARGS_CPP_BITS"
  61. fi
  62. COMPILERS=('clang++' 'g++')
  63. if [[ ! "$ARGS_CPP" == "" ]]; then
  64. if [[ "$ARGS_CPP" == "msvc" ]]; then
  65. COMPILERS=()
  66. else
  67. COMPILERS=("$ARGS_CPP")
  68. fi
  69. fi
  70. echo ""
  71. echo GNU-like compilers:
  72. printf ' %s\n' "${COMPILERS[@]}"
  73. CPP_STANDARDS=()
  74. MSVC_CPP_STANDARDS=()
  75. for v in 11 14 17 20 23; do
  76. if [[ "$ARGS_CPP_STANDARDS" == "," || "$ARGS_CPP_STANDARDS" == *,$v,* ]]; then
  77. CPP_STANDARDS+=("--std=c++$v")
  78. MSVC_CPP_STANDARDS+=("-std:c++$v")
  79. fi
  80. done
  81. echo ""
  82. echo Standards:
  83. printf ' %s\n' "${CPP_STANDARDS[@]}"
  84. uname_output="$(uname -s)"
  85. case "${uname_output}" in
  86. Linux*) machine=Linux ;;
  87. Darwin*) machine=Mac ;;
  88. CYGWIN*) machine=Windows ;;
  89. MINGW*) machine=Windows ;;
  90. MSYS*) machine=Windows ;;
  91. *) echo "Unknown system '${uname_output}'" && exit 1 ;;
  92. esac
  93. export MACHINE="$machine"
  94. if [[ "$machine" == "Windows" && ("$ARGS_CPP" == "" || "$ARGS_CPP" == "msvc") ]]; then
  95. for f in msvc-2022-include windows-kit-10.0.19041.0-include; do
  96. rm -rf "${TESTS_DIR:?}"/lib/$f && mkdir -p "$TESTS_DIR"/lib/$f
  97. 7z x -o"${TESTS_DIR:?}"/lib/$f "$TESTS_DIR"/lib/$f.7z
  98. done
  99. fi
  100. run_tests() {
  101. export INVOCATION_ID=$RANDOM
  102. export CPP="$1"
  103. export CPP_STANDARD="$2"
  104. echo -e Running tests \(${CYAN}"$CPP"@"$CPP_STANDARD"${NC}\)
  105. echo ""
  106. for test_dir in "$TESTS_DIR"/*/; do
  107. test=$(basename "$test_dir")
  108. if [[ $test == test-* ]]; then
  109. if [[ "$ARGS_TESTS" == "," || "$ARGS_TESTS" == *,$test,* ]]; then
  110. echo -e Running "${BLUE}${test}${NC}" \("$CPP"@"$CPP_STANDARD"\)
  111. export TEST_DIR="$test_dir"
  112. export CPP_INCLUDE_DIR=${TESTS_DIR}/..
  113. export CPP_OPTS=""
  114. if [[ -n "$ARGS_CPP_BITS" ]]; then
  115. export CPP_OPTS="-m$ARGS_CPP_BITS"
  116. fi
  117. pushd "$test_dir" 1>/dev/null 2>&1
  118. bash "${test_dir}run.sh"
  119. echo -e Done "${BLUE}$test${NC}" \(${CYAN}"$CPP"@"$CPP_STANDARD"${NC}\)
  120. echo ""
  121. popd 1>&2 1>/dev/null 2>&1
  122. fi
  123. fi
  124. done
  125. rm -rf "$TESTS_DIR"/tester-lcmp
  126. echo -e Done all tests \(${CYAN}"$CPP"@"$CPP_STANDARD"${NC}\)
  127. echo ""
  128. }
  129. VALGRIND=""
  130. valgrind_output=$(valgrind 2>&1 || true)
  131. if [[ $valgrind_output == *"--help"* ]]; then
  132. VALGRIND="valgrind -q"
  133. echo Valgrind mode is ON
  134. else
  135. echo Valgrind mode is OFF
  136. fi
  137. export VALGRIND="$VALGRIND"
  138. done=""
  139. if [[ "$machine" == "Windows" && ("$ARGS_CPP" == "" || "$ARGS_CPP" == "msvc") ]]; then
  140. VS_RELEASES=("Professional" "Enterprise" "Community")
  141. PROGRAM_FILES=("${PROGRAMFILES}" "${PROGRAMFILES} (x86)")
  142. for vs_release in "${VS_RELEASES[@]}"; do
  143. for program_files in "${PROGRAM_FILES[@]}"; do
  144. for ((version = 2000; version <= 2100; version++)); do
  145. vs_dir="$program_files\\Microsoft Visual Studio\\$version\\$vs_release\\VC\\Auxiliary\\Build"
  146. if [[ -d $vs_dir ]]; then
  147. for bits in 32 64; do
  148. vcvars_bat_file="$vs_dir\\vcvars$bits.bat"
  149. if [[ -f $vcvars_bat_file ]]; then
  150. echo "Compiler Visual Studio $version ($vs_release-$bits) has been found"
  151. echo call \""$vcvars_bat_file"\" >do-vcvars.bat
  152. echo "bash -c export > vcvars.env" >>do-vcvars.bat
  153. ./do-vcvars.bat
  154. source vcvars.env
  155. rm -f do-vcvars.bat vcvars.env
  156. for cpp_standard in "${MSVC_CPP_STANDARDS[@]}"; do
  157. touch empty_file.cpp
  158. cpp_output=$(cl.exe "$cpp_standard" empty_file.cpp 2>&1 || true)
  159. rm -f empty_file.*
  160. if [[ ! $cpp_output == *"unknown"* ]]; then
  161. echo Testing msvc-"$version"-$bits@"$cpp_standard"
  162. run_tests "cl.exe" "$cpp_standard"
  163. if [[ ! "$done" == "" ]]; then
  164. done="$done, "
  165. fi
  166. done="${done}msvc-$version-$bits@$cpp_standard"
  167. fi
  168. done
  169. fi
  170. done
  171. fi
  172. done
  173. done
  174. done
  175. fi
  176. for compiler in "${COMPILERS[@]}"; do
  177. for version in 0 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
  178. if [[ "$ARGS_CPP_VERSIONS" == "," || "$ARGS_CPP_VERSIONS" == *,$version,* ]]; then
  179. cpp="$compiler-$version"
  180. if [[ "$version" == 0 ]]; then
  181. cpp="$compiler"
  182. fi
  183. cpp_output=$($cpp 2>&1 || true)
  184. if [[ $cpp_output == *"no input files"* ]]; then
  185. echo "Compiler '$cpp' has been found"
  186. for cpp_standard in "${CPP_STANDARDS[@]}"; do
  187. touch empty_file.cpp
  188. cpp_output=$($cpp "$cpp_standard" empty_file.cpp 2>&1 || true)
  189. if [[ ! $cpp_output == *"unrecognized"* && ! $cpp_output == *"standard"* ]]; then
  190. if [[ "$machine" == "Windows" && "$cpp" == "clang++" && "$cpp_standard" == "--std=c++11" ]]; then
  191. echo Ignore "$cpp" "$cpp_standard" on $machine
  192. continue
  193. fi
  194. run_tests "$cpp" "$cpp_standard"
  195. if [[ ! "$done" == "" ]]; then
  196. done="$done, "
  197. fi
  198. done="$done$cpp@$cpp_standard"
  199. fi
  200. rm -f empty_file.*
  201. done
  202. fi
  203. fi
  204. done
  205. done
  206. if [[ "$machine" == "Windows" ]]; then
  207. for f in msvc-2022-include windows-kit-10.0.19041.0-include; do
  208. rm -rf "${TESTS_DIR:?}"/lib/$f
  209. done
  210. fi
  211. if [[ -z "$done" ]]; then
  212. echo "[ERROR] No compilers found"
  213. exit 1
  214. fi
  215. echo -e "${GREEN}Successfully tested on${NC}: $done\n"