From: Dan Kegel Date: Fri, 19 Jun 2020 15:50:13 +0000 (-0700) Subject: Make static libraries produced by cmake and configure identical. X-Git-Tag: 1.9.9-b1~133 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1e2877069fcd2d02802b00c0b65f0bf4d6ade63f;p=thirdparty%2Fzlib-ng.git Make static libraries produced by cmake and configure identical. Also make compat mode .pc files identical. - cmake: don't do runtime feature checks when doing native builds. - test/pkgcheck.sh: also compare .a, check compat mode, and handle mac better - CMakeLists.txt: get Version right in compat mode .pc file - .github/workflows/pkgcheck.sh: test on more systems, including mac Fixes #681 --- diff --git a/.github/workflows/pkgcheck.yml b/.github/workflows/pkgcheck.yml index 6084eecd..58b2c0dd 100644 --- a/.github/workflows/pkgcheck.yml +++ b/.github/workflows/pkgcheck.yml @@ -8,28 +8,90 @@ jobs: fail-fast: false matrix: name: [ - Ubuntu GCC + Ubuntu GCC, + Ubuntu GCC -m32, + Ubuntu GCC ARM HF, + Ubuntu GCC AARCH64, + Ubuntu GCC PPC, + Ubuntu GCC PPC64LE, + macOS Clang ] include: - name: Ubuntu GCC os: ubuntu-latest compiler: gcc - packages: ninja-build + + - name: Ubuntu GCC -m32 + os: ubuntu-latest + compiler: gcc + packages: gcc-multilib + cmake-args: -DCMAKE_C_FLAGS=-m32 + cflags: -m32 + ldflags: -m32 + + - name: Ubuntu GCC ARM HF + os: ubuntu-latest + chost: arm-linux-gnueabihf + compiler: arm-linux-gnueabihf-gcc + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DCMAKE_C_COMPILER_TARGET=arm-linux-gnueabihf + packages: qemu gcc-arm-linux-gnueabihf libc6-dev-armhf-cross + + - name: Ubuntu GCC AARCH64 + os: ubuntu-latest + chost: aarch64-linux-gnu + compiler: aarch64-linux-gnu-gcc + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake + packages: qemu gcc-aarch64-linux-gnu libc6-dev-arm64-cross + + - name: Ubuntu GCC PPC + os: ubuntu-latest + chost: powerpc-linux-gnu + compiler: powerpc-linux-gnu-gcc + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake + packages: qemu gcc-powerpc-linux-gnu libc6-dev-powerpc-cross + + - name: Ubuntu GCC PPC64LE + os: ubuntu-latest + chost: powerpc64le-linux-gnu + compiler: powerpc64le-linux-gnu-gcc + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake + packages: qemu gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross + + - name: macOS Clang + os: macOS-latest + compiler: clang steps: - name: Checkout repository uses: actions/checkout@v1 - name: Install packages (Ubuntu) - if: runner.os == 'Linux' && matrix.packages + if: runner.os == 'Linux' run: | sudo apt-get update - sudo apt-get install -y ${{ matrix.packages }} + sudo apt-get install -y --no-install-recommends ninja-build ${{ matrix.packages }} + + - name: Install packages (macOS) + if: runner.os == 'macOS' + run: | + brew install ninja ${{ matrix.packages }} + + - name: Compare builds + run: | + sh test/pkgcheck.sh + env: + CC: ${{ matrix.compiler }} + CFLAGS: ${{ matrix.cflags }} + CHOST: ${{ matrix.chost }} + CMAKE_ARGS: ${{ matrix.cmake-args }} + LDFLAGS: ${{ matrix.ldflags }} - - name: Compare output of configure and cmake + - name: Compare builds (compat) run: | - mkdir ${{ matrix.build-dir || '.not-used' }} - cd ${{ matrix.build-dir || '.' }} - sh ${{ matrix.build-src-dir || '.' }}/test/pkgcheck.sh + sh test/pkgcheck.sh --zlib-compat env: CC: ${{ matrix.compiler }} + CFLAGS: ${{ matrix.cflags }} + CHOST: ${{ matrix.chost }} + CMAKE_ARGS: ${{ matrix.cmake-args }} + LDFLAGS: ${{ matrix.ldflags }} diff --git a/.gitignore b/.gitignore index 6842f0e7..23f9fd15 100644 --- a/.gitignore +++ b/.gitignore @@ -79,6 +79,8 @@ a.out /win32/Debug /build/ /build[.-]*/ +/btmp[12]/ +/pkgtmp[12]/ /.idea /cmake-build-debug diff --git a/CMakeLists.txt b/CMakeLists.txt index fd5007b1..a31d3c7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -456,10 +456,10 @@ if(NOT HAVE_PTRDIFF_T) endif() endif() -# Macro to check if source compiles when cross-compiling -# or runs when compiling natively +# Macro to check if source compiles +# (and, when compiling very natively, also runs). macro(check_c_source_compile_or_run source flag) - if(CMAKE_CROSSCOMPILING) + if(CMAKE_CROSSCOMPILING OR NOT WITH_NATIVE_INSTRUCTIONS) check_c_source_compiles("${source}" ${flag}) else() check_c_source_runs("${source}" ${flag}) @@ -927,7 +927,7 @@ if(NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS) set_target_properties(zlib PROPERTIES SOVERSION 1) if(ZLIB_COMPAT) - set(ZLIB_FULL_VERSION ${ZLIB_HEADER_VERSION}) + set(ZLIB_FULL_VERSION ${ZLIB_HEADER_VERSION}.zlib-ng) else() set(ZLIB_FULL_VERSION ${ZLIBNG_HEADER_VERSION}) endif() diff --git a/Makefile.in b/Makefile.in index 21d4e9b5..3b476d09 100644 --- a/Makefile.in +++ b/Makefile.in @@ -413,6 +413,7 @@ clean: rm -f a.out a.exe rm -f *.pc rm -f *._h + rm -rf btmp1 btmp2 pkgtmp1 pkgtmp2 maintainer-clean: distclean distclean: clean diff --git a/test/pkgcheck.sh b/test/pkgcheck.sh index 9a560b54..fa25e40d 100644 --- a/test/pkgcheck.sh +++ b/test/pkgcheck.sh @@ -1,9 +1,92 @@ #!/bin/sh -# Verify that the various build systems produce identical results on a Unixlike system + +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 gcc-multilib +$ export CMAKE_ARGS="-DCMAKE_C_FLAGS=-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 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 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 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 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 -# If suffix not set to "", default to -ng -suffix=${suffix--ng} +# 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 @@ -26,7 +109,7 @@ rm -rf btmp2 pkgtmp2 mkdir btmp2 pkgtmp2 export DESTDIR=$(pwd)/pkgtmp2 cd btmp2 - cmake -G Ninja .. + cmake -G Ninja ${CMAKE_ARGS} .. ninja -v ninja install cd .. @@ -40,24 +123,44 @@ cd btmp1 Darwin) export LDFLAGS="-Wl,-headerpad_max_install_names" ;; - Linux) - if grep -i fedora /etc/os-release > /dev/null - then - # Note: Fedora patches cmake to use -O2 in release, which - # does not match the -O3 configure sets :-( - export CFLAGS="-O2 -DNDEBUG" - fi - ;; esac - ../configure + # Use same flags as cmake did. + CFLAGS="$(awk -F= '/CMAKE_C_FLAGS:/ {print $2}' < ../btmp2/CMakeCache.txt | tr '\012' ' ')" + export CFLAGS + ../configure $CONFIGURE_ARGS make make install cd .. -if diff --exclude '*.so*' --exclude '*.a' -Nur pkgtmp1 pkgtmp2 +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 +} + +# 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 --exclude '*.dylib*' --exclude '*.so*' -Nur pkgtmp1 pkgtmp2 then echo pkgcheck-cmake-bits-identical PASS else echo pkgcheck-cmake-bits-identical FAIL exit 1 fi + +rm -rf btmp1 btmp2 pkgtmp1 pkgtmp2 + +# any failure would have caused an early exit already +echo "pkgcheck: PASS"