#!/bin/sh set -ex TESTDIR="$(cd $(dirname "$0"); pwd)" usage() { cat <<_EOF_ Usage: $0 [--zlib-compat][--refresh][--refresh-if] Build shared library with -ggdb, then compare its ABI to the stable ABI, and abort if differences found. Options: --zlib-compat - check the ABI of the zlib-compatible flavor of zlib-ng. --refresh - build the reference library and extract its ABI rather than using a stored ABI file. --refresh-if - refresh only if ABI file not present. Obeys CHOST, CONFIGURE_ARGS, CFLAGS, and LDFLAGS. Requires libabigail (on Ubuntu, install package abigail-tools). _EOF_ } # Print the multiarch tuple for the current (non-cross) machine, # or the empty string if unavailable. detect_chost() { dpkg-architecture -qDEB_HOST_MULTIARCH || $CC -print-multiarch || $CC -print-search-dirs | sed 's/:/\n/g' | grep -E '^/lib/[^/]+$' | sed 's%.*/%%' || true } if ! test -f "configure" then echo "Please run from top of source tree" exit 1 fi suffix="-ng" CONFIGURE_ARGS_NG="$CONFIGURE_ARGS" refresh=false refresh_if=false for arg do case "$arg" in --zlib-compat) suffix="" CONFIGURE_ARGS_NG="$CONFIGURE_ARGS_NG --zlib-compat" ;; --refresh) refresh=true ;; --refresh-if) refresh_if=true ;; --help) usage exit 0 ;; *) echo "Unknown arg '$arg'" usage exit 1 ;; esac done # Choose reference repo and commit if test "$suffix" = "" then # Reference is zlib 1.2.11 ABI_GIT_REPO=https://github.com/madler/zlib.git ABI_GIT_COMMIT=v1.2.11 else # Reference should be the tag for zlib-ng 2.0 # but until that bright, shining day, use some # random recent SHA. Annoyingly, can't shorten it. ABI_GIT_REPO=https://github.com/zlib-ng/zlib-ng.git ABI_GIT_COMMIT=56ce27343bf295ae9457f8e3d38ec96d2f949a1c fi # FIXME: even when using a tag, check the hash. # Test compat build for ABI compatibility with zlib if test "$CHOST" = "" then # Note: don't export CHOST here, as we don't want configure seeing it # when it's just the name for the build machine. # Leave it as a plain shell variable, not an environment variable. CHOST=$(detect_chost) # Support -m32 for non-cross builds. case "$CFLAGS" in *-m32*) M32="-m32";; *) M32="";; esac fi # Canonicalize CHOST to work around bug in original zlib's configure # (Don't export it if it wasn't already exported, else may cause # default compiler detection failure and shared library link error # when building both zlib and zlib-ng. # See https://github.com/zlib-ng/zlib-ng/issues/1219) CHOST=$(sh $TESTDIR/../tools/config.sub $CHOST) if test "$CHOST" = "" then echo "abicheck: SKIP, as we don't know CHOST" exit 0 fi ABIFILE="test/abi/zlib$suffix-$ABI_GIT_COMMIT-$CHOST$M32.abi" if ! $refresh && $refresh_if && ! test -f "$ABIFILE" then refresh=true fi abidw --version if $refresh then # Check out reference source rm -rf btmp1 mkdir -p btmp1/src.d cd btmp1/src.d git init git remote add origin $ABI_GIT_REPO git fetch origin $ABI_GIT_COMMIT git reset --hard FETCH_HEAD cd .. # Build unstripped, uninstalled, very debug shared library CFLAGS="$CFLAGS -ggdb" src.d/configure $CONFIGURE_ARGS make -j2 cd .. # Find shared library, extract its abi dylib1=$(find btmp1 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print) abidw $dylib1 > "$ABIFILE" # Maintainers may wish to check $ABIFILE into git when a new # target is added, or when a major release happens that is # intended to change the ABI. Alternately, this script could # just always rebuild the reference source, and dispense with # caching abi files in git (but that would slow builds down). fi if ! test -f "$ABIFILE" then echo "abicheck: SKIP: $ABIFILE not found; rerun with --refresh or --refresh-if" exit 1 fi # Build unstripped, uninstalled, very debug shared library rm -rf btmp2 mkdir btmp2 cd btmp2 CFLAGS="$CFLAGS -ggdb" ../configure $CONFIGURE_ARGS_NG make -j2 cd .. # Find shared library, extract its abi dylib2=$(find btmp2 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print) abidw $dylib2 > btmp2/zlib${suffix}-built.abi # Compare it to the reference # FIXME: use --no-added-syms for now, but we probably want to be more strict. if abidiff --no-added-syms --suppressions test/abi/ignore "$ABIFILE" btmp2/zlib${suffix}-built.abi then echo "abicheck: PASS" else echo "abicheck: FAIL" exit 1 fi