diff --git a/.gitignore b/.gitignore index 1f36a17..fe7ac00 100644 --- a/.gitignore +++ b/.gitignore @@ -45,6 +45,7 @@ # Generated folders /build +/build.abi-check /Debug /Release /*/Debug diff --git a/abi-check.sh b/abi-check.sh index c3a88d0..a2a24a0 100755 --- a/abi-check.sh +++ b/abi-check.sh @@ -1,28 +1,164 @@ -#!/bin/sh +#!/bin/bash -set -e +set -e -o pipefail +RUNDIR=$(dirname "$0") +RUNDIR=$(realpath "${RUNDIR}") + +. "${RUNDIR}/reltools/reltools.subr" # The 0.17 release is broken -prev=0.18 -release=0.19 +#prev=0.18 +#release=0.19 -# ... clone json-c, abi-compliance-checker, abi-dumper +prev=$(get_most_recent_relver) +prevtag=$(get_most_recent_reltag "${prev}") +release=$(get_ver_descr) -if [ "$1" != "--skip-build" ] ; then - mkdir build - cd build - CFLAGS=-Og cmake -DCMAKE_INSTALL_PREFIX=~/json-c-installs/json-c-${release} .. - make && make test && make install +ACCDIR=${RUNDIR}/../abi-compliance-checker +ACC=${ACCDIR}/abi-compliance-checker.pl +REPORTDIR=${ACCDIR} +INSTBASE=${HOME}/json-c-installs + +usage() +{ + local exitval="$1" ; shift + local errmsg="$1" + if [ $exitval -ne 0 ] ; then + exec 1>&2 + fi + if [ -n "$errmsg" ] ; then + echo "ERROR: $errmsg" 1>&2 + fi + cat <] + [-R ] [-I ] + Build two versions of json-c and compare them with abi-compliance-checker + + --rebuild-old - Re-build the previous version + --rebuild-new - Re-build the current version + --regen - Always re-generate the ABI dumps + --buildold - Build the previous version if not yet done + By default, an old build must already exist. + --prev - Specify an alternate old tag to compare against + --clean - Rebuild and regen everything + -R - Where to place output reports (${REPORTDIR}) + -I - Where to install json-c builds to (${INSTBASE}) + + Previous release: ${prev} (${prevtag}) + Current version: ${release} +EOF + exit "$exitval" +} + +REBUILD_NEW=0 +REBUILD_OLD=0 +BUILD_OLD=0 +REGEN_ABI_DUMPS=0 + +while [ $# -gt 0 ] ; do + case "$1" in + --clean) + BUILD_OLD=1 + REGEN_ABI_DUMPS=1 + REBUILD_NEW=1 + REBUILD_OLD=1 + ;; + --rebuild-new) + REBUILD_NEW=1 + ;; + --rebuild-old) + REBUILD_OLD=1 + ;; + --regen) + REGEN_ABI_DUMPS=1 + ;; + --buildold) + BUILD_OLD=1 + ;; + --prev) + prev="$2" + prevtag=$(get_most_recent_reltag "${prev}") + shift + ;; + -R) + REPORTDIR="$2" + shift + ;; + -I) + INSTBASE="$2" + shift + ;; + -h|--help) + usage 0 + ;; + *) + usage 1 "Unknown args: $*" + ;; + esac + shift +done + +if [ ! -d "${ACCDIR}" ]; then + echo "Cloning abi-compliance-checker into ${ACCDIR}" + git clone https://github.com/lvc/abi-compliance-checker "${ACCDIR}" fi -# Assume the old version has already been built +if ! type -P perl > /dev/null ; then + echo "perl install needed: apt-get install perl, yum install perl, etc..." 1>&2 + exit 1 +fi + +# =============================== + +build_new() +{ + local BUILD_DEST=${INSTBASE}/json-c-${release} + if [ ! -d "${BUILD_DEST}" ] || [ "${REBUILD_NEW}" -eq 1 ] ; then + echo "Building $(pwd) (${release}) into ${BUILD_DEST}" + rm -rf build.abi-check + mkdir -p build.abi-check/${release} + ( + cd build.abi-check/${release} + CFLAGS=-Og cmake -DCMAKE_INSTALL_PREFIX="${BUILD_DEST}" ../.. + make && make test + rm -rf "${BUILD_DEST}" + make install + ) + fi +} + +build_old() +{ + local BUILD_DEST=${INSTBASE}/json-c-${prev} + if [ ! -d "${BUILD_DEST}" ] && [ "${BUILD_OLD}" -eq 0 ] ; then + echo "ERROR: ${INSTBASE}/json-c-${prev} does not exist, pass --buildold to build it." 1>&2 + exit 1 + fi + if [ ! -d "${BUILD_DEST}" ] || [ "${REBUILD_OLD}" -eq 1 ] ; then + rm -rf "build.abi-check/${prev}" + git clone "${RUNDIR}" "build.abi-check/${prev}" + ( + cd "build.abi-check/${prev}" + git -c advice.detachedHead=false checkout "${prevtag}" + echo "Building $(pwd) (${prevtag}) into ${BUILD_DEST}" + mkdir build.abi-check + cd build.abi-check + CFLAGS=-Og cmake -DCMAKE_INSTALL_PREFIX="${BUILD_DEST}" .. + make && make test + rm -rf "${BUILD_DEST}" + make install + ) + fi +} -cd ~/abi-compliance-checker mkxml() { + local INSTREL + INSTREL=$(realpath --relative-to="${REPORTDIR}" "${INSTBASE}") ver="$1" - if [ ! -e ../json-c-installs/json-c-${ver}/lib64 ] ; then - ln -s lib ../json-c-installs/json-c-${ver}/lib64 + if [ ! -e "${INSTBASE}/json-c-${ver}/lib64" ] ; then + ln -s lib "${INSTBASE}/json-c-${ver}/lib64" fi cat < json-c-${ver}.xml @@ -31,20 +167,48 @@ cat < json-c-${ver}.xml -../json-c-installs/json-c-${ver}/include/json-c +${INSTREL}/json-c-${ver}/include/json-c -../json-c-installs/json-c-${ver}/lib64/libjson-c.so +${INSTREL}/json-c-${ver}/lib64/libjson-c.so EOF } + +abidump() +{ + local libver="$1" ; shift + + local dumppath="./ABI-${libver}.dump" + if [ "${REGEN_ABI_DUMPS}" -eq 1 ] ; then + rm -f "${dumppath}" + fi + if [ ! -e "${dumppath}" ] ; then + perl "${ACC}" -lib json-c -dump json-c-${libver}.xml -dump-path "${dumppath}" + else + echo "ABI dump already exists at ${dumppath}" + fi +} + +# =============================== + +mkdir -p "${REPORTDIR}" + +build_old +build_new + +cd "${REPORTDIR}" mkxml ${release} mkxml ${prev} -perl abi-compliance-checker.pl -lib json-c -dump json-c-${prev}.xml -dump-path ./ABI-${prev}.dump -perl abi-compliance-checker.pl -lib json-c -dump json-c-${release}.xml -dump-path ./ABI-${release}.dump -perl abi-compliance-checker.pl -l json-c -old ABI-${prev}.dump -new ABI-${release}.dump +echo "=== Generating ABI dumps ===" +abidump ${prev} +abidump ${release} -echo "look in compat_reports/json-c/..." +echo "=== Comparing ABIs ===" +perl "${ACC}" -l json-c -old ABI-${prev}.dump -new ABI-${release}.dump + +echo +echo "Look in $(pwd)/compat_reports/json-c/${prev}_to_${release}" diff --git a/reltools/reltools.subr b/reltools/reltools.subr index 51b7432..f78684f 100644 --- a/reltools/reltools.subr +++ b/reltools/reltools.subr @@ -5,8 +5,9 @@ JSON_C_TOP=${rt_RUNDIR}/.. get_most_recent_reltag() { + local PATTERN="json-c-${1}*" local RELTAG - RELTAG=$(git tag | tail -1) + RELTAG=$(git tag --list "${PATTERN}" | tail -1) echo "${RELTAG}" } get_most_recent_relver()