| #!/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 |