Message ID | 20230704142435.3490823-3-kieran.bingham@ideasonboard.com |
---|---|
State | Accepted |
Headers | show |
Series |
|
Related | show |
Hi Kieran, Thank you for the patch. On Tue, Jul 04, 2023 at 03:24:34PM +0100, Kieran Bingham via libcamera-devel wrote: > Provide support to compare ABI compatibility between any two git commits > or by a commit and the most recent ancestral tag of that commit. > > Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> > > --- > v3 > - use '--force' for git worktree add to prevent issues on cancelled > builds > > - define 'libdir' and 'prefix' explicitly to prevent reliance on > system defaults. > > - many fixups thanks to Laurents review. > > - abi-compat now fails correctly in case of error. (This means it can > only run on trees that have the patch 1/3 of this series applied). > > > utils/abi-compat.sh | 212 ++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 212 insertions(+) > create mode 100755 utils/abi-compat.sh > > diff --git a/utils/abi-compat.sh b/utils/abi-compat.sh > new file mode 100755 > index 000000000000..785d081d6e1c > --- /dev/null > +++ b/utils/abi-compat.sh > @@ -0,0 +1,212 @@ > +#!/bin/bash > + > +# SPDX-License-Identifier: GPL-2.0-or-later > +# Generate and compare the ABI compatibilty of two libcamera versions > + > +name=$(basename "$0") > + > +usage() { > + cat << EOF > +$name: Determine the ABI/API compatibility of two build versions > + > + $name [--help] [--abi-dir=<PATH>] [--tmp-dir=<PATH>] ARGS > + > +The positional arguments (ARGS) determine the versions that will be compared and > +take three variants: > + > + - No positional arguments: > + $name [optional arguments] > + > + It is assumed to compare the current git HEAD against the most recent TAG > + > + - One positional argument: > + $name [optional aguments] COMMITISH > + > + The given COMMITISH is compared against it's most recent TAG > + > + - Two positional arguments: > + $name [optional aguments] BASE COMMITISH > + > + The given COMMITISH is compared against the given BASE. > + > +Optional Arguments: > + --abi-dir <path> Use <path> for storing (or retrieving existing) ABI data > + files > + > + --tmp-dir <path> Specify temporary build location for building ABI data. > + This could be a tmpfs/RAM disk to save on disk writes. > +EOF > +} > + > +dbg () { > + echo "$@" >> /dev/stderr echo "$@" >&2 Same below. > +} > + > +die () { > + echo "$name: $*" >> /dev/stderr > + exit 128 The usual exit code in case of failure is 1. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > +} > + > +describe () { > + git describe --tags "$1" \ > + || die "Failed to describe $1" > +} > + > +prev_release () { > + git describe --tags --abbrev=0 "$1"^ \ > + || die "Failed to identify previous release tag from $1" > +} > + > +# Make sure we exit on errors during argument parsing. > +set -Eeuo pipefail > + > +positional=() > +while [[ $# -gt 0 ]] ; do > + option="$1" > + shift > + > + case $option in > + -h|--help) > + usage > + exit 0 > + ;; > + > + --abi-dir) > + abi_dir=$1 > + shift > + ;; > + > + --tmp-dir) > + tmp=$1 > + shift > + ;; > + > + -*) > + die "Unrecognised argument $option" > + ;; > + > + *) # Parse unidentified arguments based on position. > + positional+=("$option") > + ;; > + esac > +done > +set -- "${positional[@]}" # restore positional parameters. > + > +# Parse positional arguments. > +case $# in > + 0) # Check HEAD against previous 'release'. > + from=$(prev_release HEAD) > + to=$(describe HEAD) > + ;; > + > + 1) # Check COMMIT against previous release. > + from=$(prev_release "$1") > + to=$(describe "$1") > + ;; > + > + 2) # Check ABI between FROM and TO explicitly. > + from=$(describe "$1") > + to=$(describe "$2") > + ;; > + > + *) > + die "Invalid arguments" > + ;; > +esac > + > +if ! which abi-compliance-checker; then > + die "This tool requires 'abi-compliance-checker' to be installed." > +fi > + > + > +abi_dir=${abi_dir:-abi} > +tmp=${tmp:-"$abi_dir/tmp/"} > + > +echo "Validating ABI compatibility between $from and $to" > + > +mkdir -p "$abi_dir" > +mkdir -p "$tmp" > + > +# Generate an abi-compliance-checker xml description file. > +create_xml() { > + local output="$1" > + local version="$2" > + local root="$3" > + > + echo "<version>$version</version>" > "$output" > + echo "<headers>$root/usr/local/include/</headers>" >> "$output" > + echo "<libs>$root/usr/local/lib/</libs>" >> "$output" > +} > + > +# Check if an ABI dump file exists, and if not create one by building a minimal > +# configuration of libcamera at the specified version using a clean worktree. > +create_abi_dump() { > + local version="$1" > + local abi_file="$abi_dir/$version.abi.dump" > + local worktree="$tmp/$version" > + local build="$tmp/$version-build" > + > + # Use a fully qualified path when calling ninja -C. > + install=$(realpath "$tmp/$version-install") > + > + if [[ ! -e "$abi_file" ]] ; then > + dbg "Creating ABI dump for $version in $abi_dir" > + git worktree add --force "$worktree" "$version" > + > + # Generate a minimal libcamera build. "lib" and "prefix" are > + # defined explicitly to avoid system default ambiguities. > + meson setup "$build" "$worktree" \ > + -Dlibdir=lib \ > + -Dprefix=/usr/local/ \ > + -Ddocumentation=disabled \ > + -Dcam=disabled \ > + -Dqcam=disabled \ > + -Dgstreamer=disabled \ > + -Dlc-compliance=disabled \ > + -Dtracing=disabled \ > + -Dpipelines= > + > + ninja -C "$build" > + DESTDIR="$install" ninja -C "$build" install > + > + # Create an xml descriptor with parameters to generate the dump file. > + create_xml \ > + "$install/libcamera-abi-dump.xml" \ > + "$version" \ > + "$install" > + > + abi-compliance-checker \ > + -lib libcamera \ > + -v1 "$version" \ > + -dump "$install/libcamera-abi-dump.xml" \ > + -dump-path "$abi_file" > + > + dbg Created "$abi_file" > + > + dbg Removing Worktree "$worktree" > + git worktree remove -f "$worktree" > + > + dbg Removing "$build" > + rm -r "$build" > + > + dbg Removing "$install" > + rm -r "$install" > + fi > +} > + > +# Create the requested ABI dump files if they don't yet exist. > +create_abi_dump "$from" > +create_abi_dump "$to" > + > +# TODO: Future iterations and extensions here could add "-stdout -xml" and > +# parse the results automatically. > +abi-compliance-checker -l libcamera \ > + -old "$abi_dir/$from.abi.dump" \ > + -new "$abi_dir/$to.abi.dump" > + > +# On (far too many) occasions, the tools keep running leaving a cpu core @ 100% > +# CPU usage. Perhaps some subprocess gets launched but never rejoined. Stop > +# them all. > +# > +# TODO: Investigate this and report upstream. > +killall abi-compliance-checker 2>/dev/null
Hi Kieran, On 7/4/23 4:24 PM, Kieran Bingham via libcamera-devel wrote: > Provide support to compare ABI compatibility between any two git commits > or by a commit and the most recent ancestral tag of that commit. > > Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Tested-by: Umang Jain <umang.jain@ideasonboard.com> > > --- > v3 > - use '--force' for git worktree add to prevent issues on cancelled > builds > > - define 'libdir' and 'prefix' explicitly to prevent reliance on > system defaults. > > - many fixups thanks to Laurents review. > > - abi-compat now fails correctly in case of error. (This means it can > only run on trees that have the patch 1/3 of this series applied). > > > utils/abi-compat.sh | 212 ++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 212 insertions(+) > create mode 100755 utils/abi-compat.sh > > diff --git a/utils/abi-compat.sh b/utils/abi-compat.sh > new file mode 100755 > index 000000000000..785d081d6e1c > --- /dev/null > +++ b/utils/abi-compat.sh > @@ -0,0 +1,212 @@ > +#!/bin/bash > + > +# SPDX-License-Identifier: GPL-2.0-or-later > +# Generate and compare the ABI compatibilty of two libcamera versions > + > +name=$(basename "$0") > + > +usage() { > + cat << EOF > +$name: Determine the ABI/API compatibility of two build versions > + > + $name [--help] [--abi-dir=<PATH>] [--tmp-dir=<PATH>] ARGS > + > +The positional arguments (ARGS) determine the versions that will be compared and > +take three variants: > + > + - No positional arguments: > + $name [optional arguments] > + > + It is assumed to compare the current git HEAD against the most recent TAG > + > + - One positional argument: > + $name [optional aguments] COMMITISH > + > + The given COMMITISH is compared against it's most recent TAG > + > + - Two positional arguments: > + $name [optional aguments] BASE COMMITISH > + > + The given COMMITISH is compared against the given BASE. > + > +Optional Arguments: > + --abi-dir <path> Use <path> for storing (or retrieving existing) ABI data > + files > + > + --tmp-dir <path> Specify temporary build location for building ABI data. > + This could be a tmpfs/RAM disk to save on disk writes. > +EOF > +} > + > +dbg () { > + echo "$@" >> /dev/stderr > +} > + > +die () { > + echo "$name: $*" >> /dev/stderr > + exit 128 > +} > + > +describe () { > + git describe --tags "$1" \ > + || die "Failed to describe $1" > +} > + > +prev_release () { > + git describe --tags --abbrev=0 "$1"^ \ > + || die "Failed to identify previous release tag from $1" > +} > + > +# Make sure we exit on errors during argument parsing. > +set -Eeuo pipefail > + > +positional=() > +while [[ $# -gt 0 ]] ; do > + option="$1" > + shift > + > + case $option in > + -h|--help) > + usage > + exit 0 > + ;; > + > + --abi-dir) > + abi_dir=$1 > + shift > + ;; > + > + --tmp-dir) > + tmp=$1 > + shift > + ;; > + > + -*) > + die "Unrecognised argument $option" > + ;; > + > + *) # Parse unidentified arguments based on position. > + positional+=("$option") > + ;; > + esac > +done > +set -- "${positional[@]}" # restore positional parameters. > + > +# Parse positional arguments. > +case $# in > + 0) # Check HEAD against previous 'release'. > + from=$(prev_release HEAD) > + to=$(describe HEAD) > + ;; > + > + 1) # Check COMMIT against previous release. > + from=$(prev_release "$1") > + to=$(describe "$1") > + ;; > + > + 2) # Check ABI between FROM and TO explicitly. > + from=$(describe "$1") > + to=$(describe "$2") > + ;; > + > + *) > + die "Invalid arguments" > + ;; > +esac > + > +if ! which abi-compliance-checker; then > + die "This tool requires 'abi-compliance-checker' to be installed." > +fi > + > + > +abi_dir=${abi_dir:-abi} > +tmp=${tmp:-"$abi_dir/tmp/"} > + > +echo "Validating ABI compatibility between $from and $to" > + > +mkdir -p "$abi_dir" > +mkdir -p "$tmp" > + > +# Generate an abi-compliance-checker xml description file. > +create_xml() { > + local output="$1" > + local version="$2" > + local root="$3" > + > + echo "<version>$version</version>" > "$output" > + echo "<headers>$root/usr/local/include/</headers>" >> "$output" > + echo "<libs>$root/usr/local/lib/</libs>" >> "$output" > +} > + > +# Check if an ABI dump file exists, and if not create one by building a minimal > +# configuration of libcamera at the specified version using a clean worktree. > +create_abi_dump() { > + local version="$1" > + local abi_file="$abi_dir/$version.abi.dump" > + local worktree="$tmp/$version" > + local build="$tmp/$version-build" > + > + # Use a fully qualified path when calling ninja -C. > + install=$(realpath "$tmp/$version-install") > + > + if [[ ! -e "$abi_file" ]] ; then > + dbg "Creating ABI dump for $version in $abi_dir" > + git worktree add --force "$worktree" "$version" > + > + # Generate a minimal libcamera build. "lib" and "prefix" are > + # defined explicitly to avoid system default ambiguities. > + meson setup "$build" "$worktree" \ > + -Dlibdir=lib \ > + -Dprefix=/usr/local/ \ > + -Ddocumentation=disabled \ > + -Dcam=disabled \ > + -Dqcam=disabled \ > + -Dgstreamer=disabled \ > + -Dlc-compliance=disabled \ > + -Dtracing=disabled \ > + -Dpipelines= > + > + ninja -C "$build" > + DESTDIR="$install" ninja -C "$build" install > + > + # Create an xml descriptor with parameters to generate the dump file. > + create_xml \ > + "$install/libcamera-abi-dump.xml" \ > + "$version" \ > + "$install" > + > + abi-compliance-checker \ > + -lib libcamera \ > + -v1 "$version" \ > + -dump "$install/libcamera-abi-dump.xml" \ > + -dump-path "$abi_file" > + > + dbg Created "$abi_file" > + > + dbg Removing Worktree "$worktree" > + git worktree remove -f "$worktree" > + > + dbg Removing "$build" > + rm -r "$build" > + > + dbg Removing "$install" > + rm -r "$install" > + fi > +} > + > +# Create the requested ABI dump files if they don't yet exist. > +create_abi_dump "$from" > +create_abi_dump "$to" > + > +# TODO: Future iterations and extensions here could add "-stdout -xml" and > +# parse the results automatically. > +abi-compliance-checker -l libcamera \ > + -old "$abi_dir/$from.abi.dump" \ > + -new "$abi_dir/$to.abi.dump" > + > +# On (far too many) occasions, the tools keep running leaving a cpu core @ 100% > +# CPU usage. Perhaps some subprocess gets launched but never rejoined. Stop > +# them all. > +# > +# TODO: Investigate this and report upstream. > +killall abi-compliance-checker 2>/dev/null
diff --git a/utils/abi-compat.sh b/utils/abi-compat.sh new file mode 100755 index 000000000000..785d081d6e1c --- /dev/null +++ b/utils/abi-compat.sh @@ -0,0 +1,212 @@ +#!/bin/bash + +# SPDX-License-Identifier: GPL-2.0-or-later +# Generate and compare the ABI compatibilty of two libcamera versions + +name=$(basename "$0") + +usage() { + cat << EOF +$name: Determine the ABI/API compatibility of two build versions + + $name [--help] [--abi-dir=<PATH>] [--tmp-dir=<PATH>] ARGS + +The positional arguments (ARGS) determine the versions that will be compared and +take three variants: + + - No positional arguments: + $name [optional arguments] + + It is assumed to compare the current git HEAD against the most recent TAG + + - One positional argument: + $name [optional aguments] COMMITISH + + The given COMMITISH is compared against it's most recent TAG + + - Two positional arguments: + $name [optional aguments] BASE COMMITISH + + The given COMMITISH is compared against the given BASE. + +Optional Arguments: + --abi-dir <path> Use <path> for storing (or retrieving existing) ABI data + files + + --tmp-dir <path> Specify temporary build location for building ABI data. + This could be a tmpfs/RAM disk to save on disk writes. +EOF +} + +dbg () { + echo "$@" >> /dev/stderr +} + +die () { + echo "$name: $*" >> /dev/stderr + exit 128 +} + +describe () { + git describe --tags "$1" \ + || die "Failed to describe $1" +} + +prev_release () { + git describe --tags --abbrev=0 "$1"^ \ + || die "Failed to identify previous release tag from $1" +} + +# Make sure we exit on errors during argument parsing. +set -Eeuo pipefail + +positional=() +while [[ $# -gt 0 ]] ; do + option="$1" + shift + + case $option in + -h|--help) + usage + exit 0 + ;; + + --abi-dir) + abi_dir=$1 + shift + ;; + + --tmp-dir) + tmp=$1 + shift + ;; + + -*) + die "Unrecognised argument $option" + ;; + + *) # Parse unidentified arguments based on position. + positional+=("$option") + ;; + esac +done +set -- "${positional[@]}" # restore positional parameters. + +# Parse positional arguments. +case $# in + 0) # Check HEAD against previous 'release'. + from=$(prev_release HEAD) + to=$(describe HEAD) + ;; + + 1) # Check COMMIT against previous release. + from=$(prev_release "$1") + to=$(describe "$1") + ;; + + 2) # Check ABI between FROM and TO explicitly. + from=$(describe "$1") + to=$(describe "$2") + ;; + + *) + die "Invalid arguments" + ;; +esac + +if ! which abi-compliance-checker; then + die "This tool requires 'abi-compliance-checker' to be installed." +fi + + +abi_dir=${abi_dir:-abi} +tmp=${tmp:-"$abi_dir/tmp/"} + +echo "Validating ABI compatibility between $from and $to" + +mkdir -p "$abi_dir" +mkdir -p "$tmp" + +# Generate an abi-compliance-checker xml description file. +create_xml() { + local output="$1" + local version="$2" + local root="$3" + + echo "<version>$version</version>" > "$output" + echo "<headers>$root/usr/local/include/</headers>" >> "$output" + echo "<libs>$root/usr/local/lib/</libs>" >> "$output" +} + +# Check if an ABI dump file exists, and if not create one by building a minimal +# configuration of libcamera at the specified version using a clean worktree. +create_abi_dump() { + local version="$1" + local abi_file="$abi_dir/$version.abi.dump" + local worktree="$tmp/$version" + local build="$tmp/$version-build" + + # Use a fully qualified path when calling ninja -C. + install=$(realpath "$tmp/$version-install") + + if [[ ! -e "$abi_file" ]] ; then + dbg "Creating ABI dump for $version in $abi_dir" + git worktree add --force "$worktree" "$version" + + # Generate a minimal libcamera build. "lib" and "prefix" are + # defined explicitly to avoid system default ambiguities. + meson setup "$build" "$worktree" \ + -Dlibdir=lib \ + -Dprefix=/usr/local/ \ + -Ddocumentation=disabled \ + -Dcam=disabled \ + -Dqcam=disabled \ + -Dgstreamer=disabled \ + -Dlc-compliance=disabled \ + -Dtracing=disabled \ + -Dpipelines= + + ninja -C "$build" + DESTDIR="$install" ninja -C "$build" install + + # Create an xml descriptor with parameters to generate the dump file. + create_xml \ + "$install/libcamera-abi-dump.xml" \ + "$version" \ + "$install" + + abi-compliance-checker \ + -lib libcamera \ + -v1 "$version" \ + -dump "$install/libcamera-abi-dump.xml" \ + -dump-path "$abi_file" + + dbg Created "$abi_file" + + dbg Removing Worktree "$worktree" + git worktree remove -f "$worktree" + + dbg Removing "$build" + rm -r "$build" + + dbg Removing "$install" + rm -r "$install" + fi +} + +# Create the requested ABI dump files if they don't yet exist. +create_abi_dump "$from" +create_abi_dump "$to" + +# TODO: Future iterations and extensions here could add "-stdout -xml" and +# parse the results automatically. +abi-compliance-checker -l libcamera \ + -old "$abi_dir/$from.abi.dump" \ + -new "$abi_dir/$to.abi.dump" + +# On (far too many) occasions, the tools keep running leaving a cpu core @ 100% +# CPU usage. Perhaps some subprocess gets launched but never rejoined. Stop +# them all. +# +# TODO: Investigate this and report upstream. +killall abi-compliance-checker 2>/dev/null
Provide support to compare ABI compatibility between any two git commits or by a commit and the most recent ancestral tag of that commit. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> --- v3 - use '--force' for git worktree add to prevent issues on cancelled builds - define 'libdir' and 'prefix' explicitly to prevent reliance on system defaults. - many fixups thanks to Laurents review. - abi-compat now fails correctly in case of error. (This means it can only run on trees that have the patch 1/3 of this series applied). utils/abi-compat.sh | 212 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100755 utils/abi-compat.sh