summaryrefslogtreecommitdiff
path: root/test/abicheck.sh
blob: bc158e6c51ce12e5f5386fb9003efc6966335b39 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#!/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 is zlib-ng 2.0.0
  ABI_GIT_REPO=https://github.com/zlib-ng/zlib-ng.git
  ABI_GIT_COMMIT=2.0.0
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