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
165
166
167
168
169
170
171
172
173
174
175
176
|
#!/bin/sh
usage() {
cat <<"_EOF_"
Usage: sh test/pkgcheck.sh [--zlib-compat]
Verifies that the various build systems produce identical results on a Unixlike system.
If --zlib-compat, tests with zlib compatible builds.
To build the 32 bit version for the current 64 bit arch:
$ sudo apt install ninja-build diffoscope gcc-multilib
$ export CMAKE_ARGS="-DCMAKE_C_FLAGS=-m32" CFLAGS=-m32 LDFLAGS=-m32
$ sh test/pkgcheck.sh
To cross-build, install the appropriate qemu and gcc packages,
and set the environment variables used by configure or cmake.
On Ubuntu, for example (values taken from .github/workflows/pkgconf.yml):
arm HF:
$ sudo apt install ninja-build diffoscope qemu gcc-arm-linux-gnueabihf libc6-dev-armhf-cross
$ export CHOST=arm-linux-gnueabihf
$ export CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DCMAKE_C_COMPILER_TARGET=${CHOST}"
aarch64:
$ sudo apt install ninja-build diffoscope qemu gcc-aarch64-linux-gnu libc6-dev-arm64-cross
$ export CHOST=aarch64-linux-gnu
$ export CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DCMAKE_C_COMPILER_TARGET=${CHOST}"
ppc (32 bit big endian):
$ sudo apt install ninja-build diffoscope qemu gcc-powerpc-linux-gnu libc6-dev-powerpc-cross
$ export CHOST=powerpc-linux-gnu
$ export CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake"
ppc64le:
$ sudo apt install ninja-build diffoscope qemu gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross
$ export CHOST=powerpc64le-linux-gnu
$ export CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake"
then:
$ export CC=${CHOST}-gcc
$ sh test/pkgcheck.sh [--zlib-compat]
Note: on Mac, you may also need to do 'sudo xcode-select -r' to get cmake to match configure/make's behavior (i.e. omit -isysroot).
_EOF_
}
set -ex
# Caller can also set CMAKE_ARGS or CONFIGURE_ARGS if desired
CMAKE_ARGS=${CMAKE_ARGS}
CONFIGURE_ARGS=${CONFIGURE_ARGS}
case "$1" in
--zlib-compat)
suffix=""
CMAKE_ARGS="$CMAKE_ARGS -DZLIB_COMPAT=ON"
CONFIGURE_ARGS="$CONFIGURE_ARGS --zlib-compat"
;;
"")
suffix="-ng"
;;
*)
echo "Unknown arg '$1'"
usage
exit 1
;;
esac
if ! test -f "configure"
then
echo "Please run from top of source tree"
exit 1
fi
# Tell GNU's ld etc. to use Jan 1 1970 when embedding timestamps
# Probably only needed on older systems (ubuntu 14.04, BSD?)
export SOURCE_DATE_EPOCH=0
case $(uname) in
Darwin)
# Tell Apple's ar etc. to use zero timestamps
export ZERO_AR_DATE=1
# What CPU are we running on, exactly?
sysctl -n machdep.cpu.brand_string
sysctl -n machdep.cpu.features
sysctl -n machdep.cpu.leaf7_features
sysctl -n machdep.cpu.extfeatures
;;
esac
# Use same compiler for make and cmake builds
if test "$CC"x = ""x
then
if clang --version
then
export CC=clang
elif gcc --version
then
export CC=gcc
fi
fi
# New build system
# Happens to delete top-level zconf.h
# (which itself is a bug, https://github.com/madler/zlib/issues/162 )
# which triggers another bug later in configure,
# https://github.com/madler/zlib/issues/499
rm -rf btmp2 pkgtmp2
mkdir btmp2 pkgtmp2
export DESTDIR=$(pwd)/pkgtmp2
cd btmp2
cmake -G Ninja ${CMAKE_ARGS} ..
ninja -v
ninja install
cd ..
# Original build system
rm -rf btmp1 pkgtmp1
mkdir btmp1 pkgtmp1
export DESTDIR=$(pwd)/pkgtmp1
cd btmp1
case $(uname) in
Darwin)
export LDFLAGS="-Wl,-headerpad_max_install_names"
;;
esac
../configure $CONFIGURE_ARGS
make -j2
make install
cd ..
repack_ar() {
if ! cmp --silent pkgtmp1/usr/local/lib/libz$suffix.a pkgtmp2/usr/local/lib/libz$suffix.a
then
echo "libz$suffix.a does not match. Probably filenames differ (.o vs .c.o). Unpacking and renaming..."
# Note: %% is posix shell syntax meaning "Remove Largest Suffix Pattern", see
# https://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02
cd pkgtmp1; ar x usr/local/lib/libz$suffix.a; rm usr/local/lib/libz$suffix.a; cd ..
cd pkgtmp2; ar x usr/local/lib/libz$suffix.a; rm usr/local/lib/libz$suffix.a; for a in *.c.o; do mv $a ${a%%.c.o}.o; done; cd ..
# Also, remove __.SYMDEF SORTED if present, as it has those funky .c.o names embedded in it.
rm -f pkgtmp[12]/__.SYMDEF\ SORTED
fi
}
case $(uname) in
Darwin)
# Remove the build uuid.
dylib1=$(find pkgtmp1 -type f -name '*.dylib*')
dylib2=$(find pkgtmp2 -type f -name '*.dylib*')
strip -x -no_uuid "$dylib1"
strip -x -no_uuid "$dylib2"
;;
esac
# The ar on newer systems defaults to -D (i.e. deterministic),
# but FreeBSD 12.1, Debian 8, and Ubuntu 14.04 seem to not do that.
# I had trouble passing -D safely to the ar inside CMakeLists.txt,
# so punt and unpack the archive if needed before comparing.
# Also, cmake uses different .o suffix anyway...
repack_ar
if diff -Nur pkgtmp1 pkgtmp2
then
echo pkgcheck-cmake-bits-identical PASS
else
echo pkgcheck-cmake-bits-identical FAIL
dylib1=$(find pkgtmp1 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print)
dylib2=$(find pkgtmp2 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print)
diffoscope $dylib1 $dylib2 | cat
exit 1
fi
rm -rf btmp1 btmp2 pkgtmp1 pkgtmp2
# any failure would have caused an early exit already
echo "pkgcheck: PASS"
|