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 97# (Don't export it if it wasn't already exported, else may cause 98# default compiler detection failure and shared library link error 99# when building both zlib and zlib-ng. 100# See https://github.com/zlib-ng/zlib-ng/issues/1219) 101CHOST=$(sh $TESTDIR/../tools/config.sub $CHOST) 102 103if test "$CHOST" = "" 104then 105 echo "abicheck: SKIP, as we don't know CHOST" 106 exit 0 107fi 108 109ABIFILE="test/abi/zlib$suffix-$ABI_GIT_COMMIT-$CHOST$M32.abi" 110if ! $refresh && $refresh_if && ! test -f "$ABIFILE" 111then 112 refresh=true 113fi 114abidw --version 115 116if $refresh 117then 118 # Check out reference source 119 rm -rf btmp1 120 mkdir -p btmp1/src.d 121 cd btmp1/src.d 122 git init 123 git remote add origin $ABI_GIT_REPO 124 git fetch origin $ABI_GIT_COMMIT 125 git reset --hard FETCH_HEAD 126 cd .. 127 # Build unstripped, uninstalled, very debug shared library 128 CFLAGS="$CFLAGS -ggdb" src.d/configure $CONFIGURE_ARGS 129 make -j2 130 cd .. 131 # Find shared library, extract its abi 132 dylib1=$(find btmp1 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print) 133 abidw $dylib1 > "$ABIFILE" 134 # Maintainers may wish to check $ABIFILE into git when a new 135 # target is added, or when a major release happens that is 136 # intended to change the ABI. Alternately, this script could 137 # just always rebuild the reference source, and dispense with 138 # caching abi files in git (but that would slow builds down). 139fi 140 141if ! test -f "$ABIFILE" 142then 143 echo "abicheck: SKIP: $ABIFILE not found; rerun with --refresh or --refresh-if" 144 exit 1 145fi 146 147# Build unstripped, uninstalled, very debug shared library 148rm -rf btmp2 149mkdir btmp2 150cd btmp2 151CFLAGS="$CFLAGS -ggdb" ../configure $CONFIGURE_ARGS_NG 152make -j2 153cd .. 154# Find shared library, extract its abi 155dylib2=$(find btmp2 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print) 156abidw $dylib2 > btmp2/zlib${suffix}-built.abi 157 158# Compare it to the reference 159# FIXME: use --no-added-syms for now, but we probably want to be more strict. 160if abidiff --no-added-syms --suppressions test/abi/ignore "$ABIFILE" btmp2/zlib${suffix}-built.abi 161then 162 echo "abicheck: PASS" 163else 164 echo "abicheck: FAIL" 165 exit 1 166fi 167