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