1#!/bin/sh 2set -ex 3TESTDIR="$(cd $(dirname "$0"); pwd)" 4 5usage() { 6 cat <<_EOF_ 7Usage: $0 [--zlib-compat][--refresh][--refresh-if] 8 9Build shared library with -ggdb, then compare its ABI to the stable 10ABI, and abort if differences found. 11 12Options: 13--zlib-compat - check the ABI of the zlib-compatible flavor of zlib-ng. 14--refresh - build the reference library and extract its ABI rather than using a stored ABI file. 15--refresh-if - refresh only if ABI file not present. 16 17Obeys CHOST, CONFIGURE_ARGS, CFLAGS, and LDFLAGS. 18 19Requires libabigail (on Ubuntu, install package abigail-tools). 20_EOF_ 21} 22 23# Print the multiarch tuple for the current (non-cross) machine, 24# or the empty string if unavailable. 25detect_chost() { 26 dpkg-architecture -qDEB_HOST_MULTIARCH || 27 $CC -print-multiarch || 28 $CC -print-search-dirs | sed 's/:/\n/g' | grep -E '^/lib/[^/]+$' | sed 's%.*/%%' || 29 true 30} 31 32if ! test -f "configure" 33then 34 echo "Please run from top of source tree" 35 exit 1 36fi 37 38suffix="-ng" 39CONFIGURE_ARGS_NG="$CONFIGURE_ARGS" 40refresh=false 41refresh_if=false 42for arg 43do 44 case "$arg" in 45 --zlib-compat) 46 suffix="" 47 CONFIGURE_ARGS_NG="$CONFIGURE_ARGS_NG --zlib-compat" 48 ;; 49 --refresh) 50 refresh=true 51 ;; 52 --refresh_if) 53 refresh_if=true 54 ;; 55 --help) 56 usage 57 exit 0 58 ;; 59 *) 60 echo "Unknown arg '$arg'" 61 usage 62 exit 1 63 ;; 64 esac 65done 66 67# Choose reference repo and commit 68if test "$suffix" = "" 69then 70 # Reference is zlib 1.2.11 71 ABI_GIT_REPO=https://github.com/madler/zlib.git 72 ABI_GIT_COMMIT=v1.2.11 73else 74 # Reference should be the tag for zlib-ng 2.0 75 # but until that bright, shining day, use some 76 # random recent SHA. Annoyingly, can't shorten it. 77 ABI_GIT_REPO=https://github.com/zlib-ng/zlib-ng.git 78 ABI_GIT_COMMIT=56ce27343bf295ae9457f8e3d38ec96d2f949a1c 79fi 80# FIXME: even when using a tag, check the hash. 81 82# Test compat build for ABI compatibility with zlib 83if test "$CHOST" = "" 84then 85 # Note: don't export CHOST here, as we don't want configure seeing it 86 # when it's just the name for the build machine. 87 # Leave it as a plain shell variable, not an environment variable. 88 CHOST=$(detect_chost) 89 # Support -m32 for non-cross builds. 90 case "$CFLAGS" in 91 *-m32*) M32="-m32";; 92 *) M32="";; 93 esac 94fi 95 96# Canonicalize CHOST to work around bug in original zlib's configure 97export CHOST=$(sh $TESTDIR/../tools/config.sub $CHOST) 98 99if test "$CHOST" = "" 100then 101 echo "abicheck: SKIP, as we don't know CHOST" 102 exit 0 103fi 104 105ABIFILE="test/abi/zlib$suffix-$ABI_GIT_COMMIT-$CHOST$M32.abi" 106if ! $refresh && $refresh_if && ! test -f "$ABIFILE" 107then 108 refresh=true 109fi 110abidw --version 111 112if $refresh 113then 114 # Check out reference source 115 rm -rf btmp1 116 mkdir -p btmp1/src.d 117 cd btmp1/src.d 118 git init 119 git remote add origin $ABI_GIT_REPO 120 git fetch origin $ABI_GIT_COMMIT 121 git reset --hard FETCH_HEAD 122 cd .. 123 # Build unstripped, uninstalled, very debug shared library 124 CFLAGS="$CFLAGS -ggdb" sh src.d/configure $CONFIGURE_ARGS 125 make -j2 126 cd .. 127 # Find shared library, extract its abi 128 dylib1=$(find btmp1 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print) 129 abidw $dylib1 > "$ABIFILE" 130 # Maintainers may wish to check $ABIFILE into git when a new 131 # target is added, or when a major release happens that is 132 # intended to change the ABI. Alternately, this script could 133 # just always rebuild the reference source, and dispense with 134 # caching abi files in git (but that would slow builds down). 135fi 136 137if test -f "$ABIFILE" 138then 139 ABIFILE="$ABIFILE" 140else 141 echo "abicheck: SKIP: $ABIFILE not found; rerun with --refresh or --refresh_if" 142 exit 0 143fi 144 145# Build unstripped, uninstalled, very debug shared library 146rm -rf btmp2 147mkdir btmp2 148cd btmp2 149CFLAGS="$CFLAGS -ggdb" ../configure $CONFIGURE_ARGS_NG 150make -j2 151cd .. 152# Find shared library, extract its abi 153dylib2=$(find btmp2 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print) 154abidw $dylib2 > btmp2/zlib${suffix}-built.abi 155 156# Compare it to the reference 157# FIXME: use --no-added-syms for now, but we probably want to be more strict. 158if abidiff --no-added-syms --suppressions test/abi/ignore "$ABIFILE" btmp2/zlib${suffix}-built.abi 159then 160 echo "abicheck: PASS" 161else 162 echo "abicheck: FAIL" 163 exit 1 164fi 165