Elliott Hughes | 7247294 | 2018-01-10 08:36:10 -0800 | [diff] [blame] | 1 | #! /bin/bash |
| 2 | # Copyright (C) Sebastian Pipping <sebastian@pipping.org> |
| 3 | # Licensed under the MIT license |
| 4 | |
| 5 | export PS4='# ' |
| 6 | |
| 7 | |
| 8 | _get_source_dir() { |
| 9 | echo "source__${version}" |
| 10 | } |
| 11 | |
| 12 | |
| 13 | _get_build_dir() { |
| 14 | local libbsd_part= |
| 15 | if ${with_libbsd}; then |
| 16 | libbsd_part=__libbsd |
| 17 | fi |
| 18 | |
| 19 | local mingw_part= |
| 20 | if ${with_mingw}; then |
| 21 | mingw_part=__windows |
| 22 | fi |
| 23 | |
| 24 | local char_part= |
| 25 | if ${with_unsigned_char}; then |
| 26 | char_part=__unsigned_char |
| 27 | fi |
| 28 | |
| 29 | echo "build__${version}__unicode_${unicode_enabled}__xml_context_${xml_context}${libbsd_part}${mingw_part}${char_part}" |
| 30 | } |
| 31 | |
| 32 | |
| 33 | _get_coverage_dir() { |
| 34 | echo "coverage__${version}" |
| 35 | } |
| 36 | |
| 37 | |
| 38 | _configure() { |
| 39 | local configure_args=() |
| 40 | |
| 41 | ${unicode_enabled} \ |
| 42 | && configure_args+=( CPPFLAGS='-DXML_UNICODE -DXML_UNICODE_WCHAR_T' ) |
| 43 | |
| 44 | if [[ ${xml_context} -eq 0 ]]; then |
| 45 | configure_args+=( --disable-xml-context ) |
| 46 | else |
| 47 | configure_args+=( --enable-xml-context=${xml_context} ) |
| 48 | fi |
| 49 | |
| 50 | ${with_libbsd} && configure_args+=( --with-libbsd ) |
| 51 | ${with_mingw} && configure_args+=( --host=i686-w64-mingw32 ) |
| 52 | |
| 53 | ( |
| 54 | set -x |
| 55 | ./buildconf.sh &> configure.log |
| 56 | ./configure "${configure_args[@]}" "$@" &>> configure.log |
| 57 | ) |
| 58 | } |
| 59 | |
| 60 | |
| 61 | _copy_to() { |
| 62 | local target_dir="$1" |
| 63 | [[ -d "${target_dir}" ]] && return 0 |
| 64 | |
| 65 | mkdir "${target_dir}" |
| 66 | git archive --format=tar "${version}" | ( cd "${target_dir}" && tar x ) |
| 67 | } |
| 68 | |
| 69 | |
| 70 | _copy_missing_mingw_libaries() { |
| 71 | # These extra files are copied because |
| 72 | # * coverage GCC flags make them needed |
| 73 | # * With WINEDLLPATH Wine looks for .dll.so in these folders, not .dll |
| 74 | local target="$1" |
| 75 | local mingw_gcc_dll_dir="$(dirname "$(ls -1 /usr/lib*/gcc/i686-w64-mingw32/*/libgcc_s_sjlj-1.dll | head -n1)")" |
| 76 | for dll in libgcc_s_sjlj-1.dll libstdc++-6.dll; do |
| 77 | ( |
| 78 | set -x |
| 79 | ln -s "${mingw_gcc_dll_dir}"/${dll} "${target}"/${dll} |
| 80 | ) |
| 81 | done |
| 82 | |
| 83 | local mingw_pthread_dll_dir="$(dirname "$(ls -1 /usr/i686-w64-mingw32/lib*/libwinpthread-1.dll | head -n1)")" |
| 84 | for dll in libwinpthread-1.dll; do |
| 85 | source="${mingw_pthread_dll_dir}"/${dll} |
| 86 | [[ -e "${source}" ]] || continue |
| 87 | ( |
| 88 | set -x |
| 89 | ln -s "${source}" "${target}"/${dll} |
| 90 | ) |
| 91 | done |
| 92 | } |
| 93 | |
| 94 | |
| 95 | _run() { |
| 96 | local source_dir="$1" |
| 97 | local build_dir="$2" |
| 98 | local capture_dir=lib |
| 99 | |
| 100 | local BASE_FLAGS='-pipe -Wall -Wextra -pedantic -Wno-overlength-strings' |
| 101 | BASE_FLAGS+=' --coverage --no-inline' |
| 102 | |
| 103 | ${with_unsigned_char} && BASE_FLAGS="${BASE_FLAGS} -funsigned-char" |
| 104 | |
| 105 | local CFLAGS="-std=c99 ${BASE_FLAGS}" |
| 106 | local CXXFLAGS="-std=c++98 ${BASE_FLAGS}" |
| 107 | |
| 108 | ( |
| 109 | set -e |
| 110 | cd "${build_dir}" |
| 111 | |
| 112 | _configure \ |
| 113 | CFLAGS="${BASE_FLAGS}" \ |
| 114 | CXXFLAGS="${BASE_FLAGS}" |
| 115 | |
| 116 | ( |
| 117 | set -x |
| 118 | make -C lib &> build.log |
| 119 | |
| 120 | lcov -c -d "${capture_dir}" -i -o "${coverage_info}-zero" &> run.log |
| 121 | ) |
| 122 | |
| 123 | if ${with_mingw}; then |
| 124 | for d in {tests,xmlwf}/.libs ; do |
| 125 | mkdir -p "${d}" |
| 126 | _copy_missing_mingw_libaries "${d}" |
| 127 | done |
| 128 | fi |
| 129 | |
| 130 | set -x |
| 131 | make all check run-xmltest |
| 132 | |
| 133 | lcov -c -d "${capture_dir}" -o "${coverage_info}-test" &>> run.log |
| 134 | lcov \ |
| 135 | -a "${coverage_info}-zero" \ |
| 136 | -a "${coverage_info}-test" \ |
| 137 | -o "${coverage_info}-all" \ |
| 138 | &>> run.log |
| 139 | |
| 140 | # Make sure that files overlap in report despite different build folders |
| 141 | sed "/SF:/ s,${build_dir}/,${source_dir}/," "${coverage_info}-all" > "${coverage_info}" |
| 142 | ) |& sed 's,^, ,' |
| 143 | res=${PIPESTATUS[0]} |
| 144 | |
| 145 | if [[ ${res} -eq 0 ]]; then |
| 146 | echo PASSED |
| 147 | else |
| 148 | echo FAILED >&2 |
| 149 | return 1 |
| 150 | fi |
| 151 | } |
| 152 | |
| 153 | |
| 154 | _merge_coverage_info() { |
| 155 | local coverage_dir="$1" |
| 156 | shift |
| 157 | local build_dirs=( "$@" ) |
| 158 | |
| 159 | mkdir -p "${coverage_dir}" |
| 160 | ( |
| 161 | local lcov_merge_args=() |
| 162 | for build_dir in "${build_dirs[@]}"; do |
| 163 | lcov_merge_args+=( -a "${build_dir}/${coverage_info}" ) |
| 164 | done |
| 165 | lcov_merge_args+=( -o "${coverage_dir}/${coverage_info}" ) |
| 166 | |
| 167 | set -x |
| 168 | lcov "${lcov_merge_args[@]}" |
| 169 | ) &> "${coverage_dir}/merge.log" |
| 170 | } |
| 171 | |
| 172 | |
| 173 | _render_html_report() { |
| 174 | local coverage_dir="$1" |
| 175 | genhtml -o "${coverage_dir}" "${coverage_dir}/${coverage_info}" &> "${coverage_dir}/render.log" |
| 176 | } |
| 177 | |
| 178 | |
| 179 | _show_summary() { |
| 180 | local coverage_dir="$1" |
| 181 | lcov -q -l "${coverage_dir}/${coverage_info}" | grep -v '^\[' |
| 182 | } |
| 183 | |
| 184 | |
| 185 | _main() { |
| 186 | version="$(git describe --tags)" |
| 187 | coverage_info=coverage.info |
| 188 | |
| 189 | local build_dirs=() |
| 190 | local source_dir="$(_get_source_dir)" |
| 191 | local coverage_dir="$(_get_coverage_dir)" |
| 192 | |
| 193 | _copy_to "${source_dir}" |
| 194 | |
| 195 | _build_case() { |
| 196 | local build_dir="$(_get_build_dir)" |
| 197 | |
| 198 | echo "[${build_dir}]" |
| 199 | _copy_to "${build_dir}" |
| 200 | _run "${source_dir}" "${build_dir}" |
| 201 | |
| 202 | build_dirs+=( "${build_dir}" ) |
| 203 | } |
| 204 | |
| 205 | # All combinations: |
| 206 | with_unsigned_char=false |
| 207 | with_libbsd=false |
| 208 | for with_mingw in true false ; do |
| 209 | for unicode_enabled in true false ; do |
| 210 | if ${unicode_enabled} && ! ${with_mingw} ; then |
| 211 | continue |
| 212 | fi |
| 213 | |
| 214 | for xml_context in 0 1024 ; do |
| 215 | _build_case |
| 216 | done |
| 217 | done |
| 218 | done |
| 219 | |
| 220 | # Single cases: |
| 221 | with_libbsd=true _build_case |
| 222 | with_unsigned_char=true _build_case |
| 223 | |
| 224 | echo |
| 225 | echo 'Merging coverage files...' |
| 226 | _merge_coverage_info "${coverage_dir}" "${build_dirs[@]}" |
| 227 | |
| 228 | echo 'Rendering HTML report...' |
| 229 | _render_html_report "${coverage_dir}" |
| 230 | echo "--> ${coverage_dir}/index.html" |
| 231 | |
| 232 | echo |
| 233 | _show_summary "${coverage_dir}" |
| 234 | } |
| 235 | |
| 236 | |
| 237 | _main |