Team Ai
Modelpublic

Felipe97/llama-cpp-compiled

sourceHugging Faceupdated 21d agoView on Hugging Face
0likes1.2kdownloads
check-apiabi-compat.sh291 linesDownload Raw Back to scripts
1#!/bin/sh2# Check for backwards-incompatible API and ABI changes between two builds3#4# Backwards-incompatible API changes, such as removing a value from an enum,5# are checked by abi-compliance-checker. Such changes can break compilation of6# existing programs.7#8# Backwards-incompatible ABI changes, such as the removal of a public function,9# are checked by libigail-tools. Such changes could break run-time dynamic10# linking of existing binaries. (We don't use a-c-c for ABI checks because it11# needs a debug build, whereas abigail does not.)12#13# Commands:14#   --generate <build-dir>: Creates API/ABI dumps in <build-dir>15#                           <build-dir> is expected to be a CMake build result16#   --check <dir1> <dir2>:  Compares dumps in <dir1> and <dir2>17#                           Comparison exit codes18#                              0: all good19#                              1: backwards-incompatible changes found20#21# Options:22#   --include-path <dir>:   a-c-c calls gcc on headers; use this option to add23#                           directories to gcc's search path24#25#26# This script would typically be used before cutting a release:27#28#   1. Generate API/ABI dump for the old version29#30#      $ check-apiabi-compat.sh --generate <build-dir-old> libfoo [ libbar ...]31#32#   2. <update source>33#34#   3. Generate API/ABI dump for the new version35#36#      $ check-apiabi-compat.sh --generate <build-dir-new> libfoo [ libbar ...]37#38#   4. Compare the two dumps39#40#      $ check-apiabi-compat.sh --check <old-build-dir> <new-build-dir>41#42#      If the check exits 0, all is fine. Otherwise, backwards-incompatible43#      changes were found, and the librar(ies) need a SOVER bump.44set -eu45 46# Preconditions47if ! command -v abi-compliance-checker >/dev/null 2>&1; then48    echo "abi-compliance-checker is not installed." >&249    exit 150elif ! command -v abidw >/dev/null 2>&1; then51    echo "abigail-tools are not installed." >&252    exit 153fi54 55# Some generic functions56usage() {57    echo "Usage: $0 [ --include-path <dir> ] --generate <build-dir> libXXX [ libYYY ... ]" >&258    echo "       $0 [ --strict ] --check <old-build-dir> <new-build-dir>" >&259    echo "" >&260    echo "  --strict: fail on any API/ABI change, including backwards-compatible additions" >&261}62 63get_cmake_project_name() {64    sed -nr 's/^project\("(.*)".*$/\1/p' CMakeLists.txt65}66 67get_cmake_version() {68    major="$(sed -nr 's/^set\([A-Z]+_VERSION_MAJOR ([0-9]+)\)$/\1/p' CMakeLists.txt)"69    minor="$(sed -nr 's/^set\([A-Z]+_VERSION_MINOR ([0-9]+)\)$/\1/p' CMakeLists.txt)"70    patch="$(sed -nr 's/^set\([A-Z]+_VERSION_PATCH ([0-9]+)\)$/\1/p' CMakeLists.txt)"71    echo "$major.$minor.$patch"72}73 74# Option parsing and validation75DO_GEN=076DO_CHECK=077STRICT=078BUILD_DIR=79BUILD_DIR_NEW=80INCLUDE_PATHS=81while [ "$#" -gt 0 ]; do82    case "$1" in83    --generate=*)84        DO_GEN=185        BUILD_DIR="${1#*=}"86        shift87        ;;88    --generate)89        DO_GEN=190        if [ -z "${2:-}" ]; then91            usage92            exit 193        fi94        BUILD_DIR="$2"95        shift 296        ;;97    --check)98        DO_CHECK=199        if [ -z "${2:-}" ] || [ -z "${3:-}" ]; then100            usage101            exit 1102        elif ! [ -d "$2" ]; then103            echo "$2 is not a directory." >&2104            exit 1105        elif ! [ -d "$3" ]; then106            echo "$3 is not a directory." >&2107            exit 1108        fi109        BUILD_DIR="$2"110        BUILD_DIR_NEW="$3"111        shift 3112        ;;113    --include-path=*)114        INCLUDE_PATHS="$INCLUDE_PATHS ${1#*=}"115        shift116        ;;117    --include-path)118        if [ -z "${2:-}" ]; then119            usage120            exit 1121        fi122        INCLUDE_PATHS="$INCLUDE_PATHS $2"123        shift 2124        ;;125    --strict)126        STRICT=1127        shift128        ;;129    -h | --help)130        usage131        exit 1132        ;;133    -?*)134        usage135        exit 1136        ;;137    *)138        break139        ;;140    esac141done142if [ $((DO_GEN + DO_CHECK)) -gt 1 ]; then143    echo "Can only use one --command." >&2144    exit145fi146PROJECT_NAME="$(get_cmake_project_name)"147PROJECT_VERSION="$(get_cmake_version)"148LIB_NAMES=""149while [ "$#" -gt 0 ]; do150    if [ "${1#lib}" = "$1" ]; then151        echo "Library to check must start with libXXX." >&2152        exit 1153    fi154    LIB_NAMES="$LIB_NAMES $1"155    shift156done157 158dump_current_api() {159    echo "Dumping API..."160 161    DESCRIPTOR="$BUILD_DIR/apiabi/acc-descriptor.xml"162    mkdir -p "$BUILD_DIR/apiabi"163    cat >"$DESCRIPTOR" <<EOF164<version>$PROJECT_VERSION</version>165<headers>include</headers>166<add_include_paths>$INCLUDE_PATHS</add_include_paths>167EOF168 169    # This addresses a bug between a-c-c and universal-ctags, manifested when170    # a name is use both for a tag and a function name171    mkdir -p "$BUILD_DIR/apiabi/.ctags.d"172    echo "--fields=-t" >"$BUILD_DIR/apiabi/.ctags.d/acc.ctags"173 174    # Change HOME so that .ctags.d gets picked up by universal-ctags, if used175    HOME="$BUILD_DIR/apiabi" abi-compliance-checker \176        -headers-only \177        -lib "$PROJECT_NAME" \178        -dump "$DESCRIPTOR" \179        -log-path "$BUILD_DIR/apiabi/acc.log" \180        -dump-path "$BUILD_DIR/apiabi/api.dump"181    # acc generates this file with an ancient timestamp, which confuses gzip182    touch "$BUILD_DIR/apiabi/api.dump"183}184 185dump_current_abi() {186    echo "Dumping ABIs ..."187    mkdir -p "$BUILD_DIR/apiabi"188    # The suppressions are needed to avoid including all the internal C++189    # symbols, and system types190    cat >"$BUILD_DIR/apiabi/abidw.suppress" <<EOF191[suppress_function]192 193label = suppress internal C++ mangled functions194symbol_name_regexp = ^_Z195drop = yes196 197[suppress_variable]198label = suppress internal C++ mangled variables199symbol_name_regexp = ^_Z200drop = yes201 202[suppress_type]203label = Suppress types outside of our own source204source_location_not_regexp = ^include/205drop = yes206EOF207 208    # In abidw 2.5, handling of undefined stuff was changed a bit209    abidw_version="$(abidw --version | sed -r 's/^abidw: ([0-9]+\.[0-9]+).*$/\1/')"210    abidw_major="${abidw_version%.*}"211    abidw_minor="${abidw_version#*.}"212    if [ "$abidw_major" -gt 2 ] || [ "$abidw_minor" -gt 4 ]; then213        abidw_undefined_syms_options="--no-load-undefined-interfaces"214    else215        abidw_undefined_syms_options="--drop-undefined-syms"216    fi217 218    for lib_name in $LIB_NAMES; do219        # Depending on where add_library resides, the libraries can end up in220        # build/src or build/bin221        lib_path="$BUILD_DIR/src/$lib_name.so"222        if ! [ -f "$lib_path" ]; then223            lib_path="$BUILD_DIR/bin/$lib_name.so"224            if ! [ -f "$lib_path" ]; then225                echo "Cannot find library $lib_name.so" >&2226                exit 1227            fi228        fi229        abidw \230            --headers-dir include \231            "$abidw_undefined_syms_options" \232            --suppressions "$BUILD_DIR/apiabi/abidw.suppress" \233            --out-file "${BUILD_DIR}/apiabi/$lib_name.abi.xml" \234            "$lib_path"235    done236}237 238# Run the actual commands239if [ "$DO_GEN" -eq 1 ]; then240    dump_current_api241    dump_current_abi242    exit 0243elif [ "$DO_CHECK" -eq 1 ]; then244    # From here on, we don't want to exit on first error245    set +e246 247    abi-compliance-checker \248        -strict \249        -source \250        -library "$PROJECT_NAME" \251        -old "$BUILD_DIR/apiabi/api.dump" \252        -new "$BUILD_DIR_NEW/apiabi/api.dump" \253        -src-report-path "$BUILD_DIR_NEW/apiabi/api_compat_report.html"254    API_RESULT=$?255 256    ABI_RESULT=0257    for xml_file in "$BUILD_DIR/apiabi/"lib*.abi.xml; do258        xml_file_new="$BUILD_DIR_NEW/apiabi/$(basename "$xml_file")"259 260        if ! [ -f "$xml_file_new" ]; then261            echo "Cannot compare, missing file: $xml_file_new" >&2262            exit 1263        fi264 265        abidiff "$xml_file" "$xml_file_new"266        res=$?267        [ "$((res & 8))" -ne 0 ] && ABI_RESULT=1268        # check bit 2 for compatible ABI changes (like new symbols) and if269        # STRICT is set then handle this as an error.270        [ "$STRICT" -eq 1 ] && [ "$((res & 4))" -ne 0 ] && ABI_RESULT=1271    done272 273    if [ "$API_RESULT" -gt 0 ]; then274        if [ "$STRICT" -eq 1 ]; then275            echo "ERROR: API changed — a minor version bump is required." >&2276        else277            echo "ERROR: API changed with backwards-incompatible problems — a major version bump is required." >&2278        fi279    fi280    if [ "$ABI_RESULT" -gt 0 ]; then281        if [ "$STRICT" -eq 1 ]; then282            echo "ERROR: ABI changed — a minor version bump is required." >&2283        else284            echo "ERROR: ABI changed with backwards-incompatible problems — a major version bump is required." >&2285        fi286    fi287    if [ "$((API_RESULT + ABI_RESULT))" -gt 0 ]; then288        exit 1289    fi290fi291