Saturday, May 09, 2026

Re: graphics/ffmpeg: update to 8.0.2 (-stable) and 8.1.1 (-current)

On Thu, 07 May 2026 08:02:15 +0200, Theo Buehler <tb@theobuehler.org> wrote: > > On Wed, May 06, 2026 at 05:29:17PM +0100, Stuart Henderson wrote: > > On 2026/05/06 18:18, Kirill A. Korinsky wrote: > > > On Wed, 06 May 2026 18:02:20 +0200, > > > Stuart Henderson <stu@spacehopper.org> wrote: > > > > > > > > $ diffsyms > > > > > > Now I wonder that it is :) > > > > local script, can't remember who it came from (at least some of it is > > not mine, I am too lazy to remember about print -u2 and would have used > > echo >&2 instead ;) > > You shared an adapted-to-ports version of a rather old guenther > check_sym with me a long time ago (still in ~tb/bin/check_sym). > > This got out of sync with base, missing features like the data object size > changes and also some fixes I wanted to have, such as cleaning the mess > it left behind in /tmp, so I extracted your changes into a wrapper script > of src/lib/check_sym and added the fake check and shared that back with > you. Then you polished that a bit more by the looks of it. > > If you want to slap an ISC license on it, my contributions seem to be > from 2022. > > I still hope someone will eventually come up with a bsd.port.mk target > of this :) > Like this? I've used /usr/src/lib/check_sym as base, get some ideas from ~tb/bin/check_sym with some polish as I thnk right and it ends with this diff. Index: /usr/src/share/man/man5/bsd.port.mk.5 =================================================================== RCS file: /home/cvs/src/share/man/man5/bsd.port.mk.5,v diff -u -p -r1.654 bsd.port.mk.5 --- /usr/src/share/man/man5/bsd.port.mk.5 4 Nov 2025 12:52:28 -0000 1.654 +++ /usr/src/share/man/man5/bsd.port.mk.5 7 May 2026 23:34:55 -0000 @@ -158,6 +158,17 @@ Essentially invoke env -i ${MAKE_ENV} ${MAKE_PROGRAM} ${MAKE_FLAGS} \e -f ${MAKE_FILE} ${ALL_TARGET} .Ed +.It Cm check-diffsyms +Compare dynamic symbols for shared libraries listed in the +.Ev PLIST +against the corresponding libraries from the installed package. +The target requires an installed package for every checked subpackage +and a completed +.Cm fake +stage; unchanged libraries produce no output, while changed libraries +show added or removed libraries, or added, removed, weakened, +strengthened, external reference, and PLT differences for matching +libraries. .It Cm check-register Introspection target. Verify from the ports tree, without building anything, that the current Index: /usr/ports/infrastructure/mk/bsd.port.mk =================================================================== RCS file: /home/cvs/ports/infrastructure/mk/bsd.port.mk,v diff -u -p -r1.1649 bsd.port.mk --- /usr/ports/infrastructure/mk/bsd.port.mk 1 Apr 2026 15:14:57 -0000 1.1649 +++ /usr/ports/infrastructure/mk/bsd.port.mk 7 May 2026 23:39:53 -0000 @@ -2026,6 +2026,7 @@ CHECK_LIB_DEPENDS_ARGS += -F pthread _CHECK_LIB_DEPENDS = PORTSDIR=${PORTSDIR} ${_PERLSCRIPT}/check-lib-depends _CHECK_LIB_DEPENDS += -d ${_PKG_REPO} -B ${WRKINST} ${CHECK_LIB_DEPENDS_ARGS} +_PORT_CHECK_SYM = ${_SHSCRIPT}/port-check-sym -B ${WRKINST} -P ${PREFIX} .for _s in ${MULTI_PACKAGES} . if ${STATIC_PLIST${_s}:L} == "no" @@ -2536,7 +2537,7 @@ _internal-all _internal-build _internal- _internal-subpackage _internal-subupdate _internal-uninstall \ _internal-update _internal-update-or-install _internal-generate-readmes \ _internal-update-or-install-all _internal-update-plist \ - lib-depends-check port-lib-depends-check update-patches: + lib-depends-check port-lib-depends-check check-diffsyms update-patches: . if !defined(IGNORE_SILENT) @${ECHO_MSG} "===> ${FULLPKGNAME${SUBPACKAGE}}${_MASTER} ${IGNORE${SUBPACKAGE}} ${_EXTRA_IGNORE}." . endif @@ -2560,6 +2561,22 @@ port-lib-depends-check: ${WRKINST}/.save ${_CHECK_LIB_DEPENDS} -i -s ${WRKINST}/.saved_libs; \ done +check-diffsyms: ${_FAKE_COOKIE} +.for _S in ${BUILD_PACKAGES} + @b=$$(cd ${.CURDIR} && SUBPACKAGE=${_S} ${MAKE} print-plist|sed -ne '/^@pkgpath /s,,-e ,p'); \ + a=$$(${PKG_INFO} -e ${FULLPKGPATH${_S}} $$b 2>/dev/null |sort -u); \ + case $$a in \ + '') echo 1>&2 "Fatal: no installed package for ${FULLPKGPATH${_S}}"; exit 1;; \ + *) d=$$(${_PBUILD} mktemp -d ${WRKDIR}/check-diffsyms.XXXXXXXXXX || exit 1); \ + trap "${_PBUILD} rm -rf $$d" 0 1 2 3 15; \ + ${PKG_INFO} -qf $$a | sed -n '/^@lib /{ s///; p; }' | \ + ${_PBUILD} tee $$d/oldlibs >/dev/null || exit 1; \ + cd ${.CURDIR} && SUBPACKAGE=${_S} ${MAKE} print-plist-libs | \ + ${_PBUILD} ${_PORT_CHECK_SYM} -T $$d -o $$d/oldlibs; \ + r=$$?; ${_PBUILD} rm -rf $$d; trap - 0 1 2 3 15; exit $$r;; \ + esac +.endfor + # Most standard port targets create a cookie to avoid being re-run. # # fetch is an exception, as it uses the files it fetches as `cookies', @@ -3857,7 +3874,7 @@ _all_phony = ${_recursive_depends_target delete-package distpatch do-build do-configure do-distpatch \ do-gen do-extract do-install do-test fetch-all \ install-all lib-depends lib-depends-list \ - peek-ftp port-lib-depends-check post-build post-configure \ + peek-ftp port-lib-depends-check check-diffsyms post-build post-configure \ post-distpatch post-extract post-install \ post-patch post-test pre-build pre-configure pre-extract pre-fake \ pre-install pre-patch pre-test prepare \ Index: /usr/ports/infrastructure/bin/port-check-sym =================================================================== RCS file: /usr/ports/infrastructure/bin/port-check-sym diff -N /usr/ports/infrastructure/bin/port-check-sym --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ /usr/ports/infrastructure/bin/port-check-sym 7 May 2026 23:46:34 -0000 @@ -0,0 +1,393 @@ +#!/bin/ksh +# $OpenBSD$ +# +# Copyright (c) 2026 Kirill A. Korinsky <kirill@korins.ky> +# Copyright (c) 2022 Theo Buehler <tb@openbsd.org> +# Copyright (c) 2016,2019,2022 Philip Guenther <guenther@openbsd.org> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# +# +# port-check-sym derives from /usr/src/lib/check_sym, but is +# specialised for ports: it compares installed package libraries with +# their WRKINST replacements, accepts PLIST library streams, and stays +# silent when no ABI differences are found. + +pick_highest() +{ + old= + omaj=-1 + omin=0 + for i + do + [[ -f $i ]] || continue + maj=${i%.*}; maj=${maj##*.} + min=${i##*.} + if [[ $maj -gt $omaj || ( $maj -eq $omaj && $min -gt $omin ) ]] + then + old=$i + omaj=$maj + omin=$min + fi + done + [[ $old != "" ]] +} + +fail() { echo "$*" >&2; exit 1; } + +usage() +{ + usage="usage: port-check-sym [-hv] -B wrkinst [-P prefix] [-T tmpdir] [-o oldlibs] [lib ...]" + [[ $# -eq 0 ]] || fail "port-check-sym: $* +$usage" + echo "$usage" + exit 0 +} + + +# +# Output helpers +# +output_if_not_empty() +{ + leader=$1 + shift + if "$@" | grep -q . + then + echo "$leader" + "$@" | sed 's:^: :' + echo + fi +} + + +# +# Dynamic library routines +# + +dynamic_collect() +{ + readelf -sW $old | filt_symtab > $odir/Ds1 + readelf -sW $new | filt_symtab > $odir/Ds2 + + readelf -rW $old > $odir/r1 + readelf -rW $new > $odir/r2 + + case $(readelf -h $new | grep '^ *Machine:') in + *MIPS*) cpu=mips64 + gotsym1=$(readelf -d $old | awk '$2 ~ /MIPS_GOTSYM/{print $3}') + gotsym2=$(readelf -d $new | awk '$2 ~ /MIPS_GOTSYM/{print $3}') + ;; + *HPPA*) cpu=hppa;; + *) cpu=dontcare;; + esac +} + +jump_slots() +{ + case $cpu in + hppa) awk '/IPLT/ && $5 != ""{print $5}' r$1 + ;; + mips64) # the $((gotsym$1)) converts hex to decimal + awk -v g=$((gotsym$1)) \ + '/^Symbol table ..symtab/{exit} + $6 == "PROTECTED" { next } + $1+0 >= g && $4 == "FUNC" {print $8}' Ds$1 + ;; + *) awk '/JU*MP_SL/ && $5 != ""{print $5}' r$1 + ;; + esac | sort -o j$1 +} + +dynamic_sym() +{ + awk -v s=$1 '/^Symbol table ..symtab/{exit} + ! /^ *[1-9]/ {next} + $5 == "LOCAL" {next} + $7 == "UND" {print $8 | ("sort -o DU" s); next } + $5 == "GLOBAL" {print $8 | ("sort -o DS" s) } + $5 == "WEAK" {print $8 | ("sort -o DW" s) } + {print $8 | ("sort -o D" s) + print $4, $5, $6, $8}' Ds$1 | sort -o d$1 +} + +dynamic_analysis() +{ + jump_slots $1 + dynamic_sym $1 + comm -23 j$1 DU$1 >J$1 + return 0 +} + +dynamic_output() +{ + if ! cmp -s d[12] + then + printf "Dynamic export changes:\n" + output_if_not_empty "added:" comm -13 D[12] + output_if_not_empty "removed:" comm -23 D[12] + output_if_not_empty "weakened:" comm -12 DS1 DW2 + output_if_not_empty "strengthened:" comm -12 DW1 DS2 + fi + if ! cmp -s DU[12] + then + printf "External reference changes:\n" + output_if_not_empty "added:" comm -13 DU[12] + output_if_not_empty "removed:" comm -23 DU[12] + fi + + if $verbose; then + printf "\nReloc counts:\nbefore:\n" + grep ^R r1 + printf "\nafter:\n" + grep ^R r2 + fi + + output_if_not_empty "PLT added:" comm -13 J[12] + output_if_not_empty "PLT removed:" comm -23 J[12] +} + +dynamic_changed() +{ + ! cmp -s d[12] || ! cmp -s DU[12] || ! cmp -s J[12] +} + +make_odir() +{ + if [[ -n $tmpdir ]] + then + mktemp -d "$tmpdir/port-check-sym.XXXXXXXXXX" + else + mktemp -dt port-check-sym.XXXXXXXXXX + fi +} + +compare_libs() +( + unset odir + trap 'ret=$?; rm -rf "$odir"; exit $ret' 0 1 2 15 ERR + odir=$(make_odir) + + set -C + for i in $odir/$file_list + do + rm -f $i + 3>$i + files="$files $i" + done + set +C + + + # + # Collect data + # + dynamic_collect + + # Now that we're done accessing $old and $new (which could be + # relative paths), chdir into our work directory, whatever it is + cd $odir + + # + # Do The Job + # + for i in 1 2 + do + dynamic_analysis $i + done + + if dynamic_changed || $verbose + then + echo "$old --> $new" + dynamic_output + fi +) + +port_check_lib() +{ + case $1 in + "") return 0;; + esac + + case ${1##*/} in + lib*.so.*) ;; + *) return 0;; + esac + + case $1 in + /*) oldpath=$1 + new=$wrkinst$1 + ;; + *) oldpath=$prefix/$1 + new=$wrkinst$prefix/$1 + ;; + esac + + lib=${oldpath##*/} + lib=${lib%%.so.*} + if [[ -f $oldpath ]] + then + old=$oldpath + else + if ! pick_highest ${oldpath%/*}/$lib.so.* + then + echo "$oldpath doesn't exist" >&2 + return 1 + fi + fi + [[ -f $new ]] || { + echo "$new doesn't exist" >&2 + return 1 + } + + compare_libs +} + +port_check_lib_pair() +{ + case $1 in + /*) old=$1;; + *) old=$prefix/$1;; + esac + case $2 in + /*) new=$wrkinst$2;; + *) new=$wrkinst$prefix/$2;; + esac + + [[ -f $old ]] || { + echo "$old doesn't exist" >&2 + return 1 + } + [[ -f $new ]] || { + echo "$new doesn't exist" >&2 + return 1 + } + + compare_libs +} + +port_lib_map() +{ + awk -v prefix="$prefix" '/(^|\/)lib[^\/]*\.so\./ { + k = $0 + if (prefix != "" && index(k, prefix "/") == 1) + k = substr(k, length(prefix) + 2) + sub(/\.so\..*$/, "", k) + print k, $0 + }' +} + +port_check_libs() +( + unset odir + trap 'ret=$?; rm -rf "$odir"; exit $ret' 0 1 2 15 ERR + odir=$(make_odir) + + if [[ $# -eq 0 ]] + then + cat > $odir/newlibs + else + for _lib + do + echo "$_lib" + done > $odir/newlibs + fi + + port_lib_map < $old_libs | sort -u > $odir/oldmap + port_lib_map < $odir/newlibs | sort -u > $odir/newmap + + join -v 2 $odir/oldmap $odir/newmap | + sed 's/^[^ ]* //' > $odir/added + join -v 1 $odir/oldmap $odir/newmap | + sed 's/^[^ ]* //' > $odir/removed + if [[ -s $odir/added || -s $odir/removed ]] + then + printf "Library changes:\n" + output_if_not_empty "added:" cat $odir/added + output_if_not_empty "removed:" cat $odir/removed + fi + + join $odir/oldmap $odir/newmap > $odir/common + failed=0 + while read _key _old _new + do + if ! port_check_lib_pair "$_old" "$_new" + then + failed=1 + fi + done < $odir/common + + exit $failed +) + + +unset odir +file_list={D{,S,s,W,U},J,d,j,r}{1,2} + +prefix=${PREFIX:-/usr/local} +wrkinst=${WRKINST:-} +verbose=false +failed=0 +old_libs= +tmpdir= + +while getopts :B:ho:P:T:v opt "$@" +do + case $opt in + B) wrkinst=$OPTARG;; + h) usage;; + o) old_libs=$OPTARG;; + P) prefix=$OPTARG;; + T) tmpdir=$OPTARG;; + v) verbose=true;; + \?) usage "unknown option -- $OPTARG";; + esac +done +shift $((OPTIND - 1)) + +[[ -n $wrkinst ]] || fail "WRKINST not set" +[[ -z $tmpdir || -d $tmpdir ]] || fail "$tmpdir doesn't exist" +prefix=${prefix%/} +wrkinst=${wrkinst%/} + +# Filter the output of readelf -s to be easier to parse by removing a +# field that only appears on some symbols: [<other>: 88] +# Not really arch-specific, but I've only seen it on alpha +filt_symtab() { sed 's/\[<other>: [0-9a-f]*\]//'; } + +if [[ -n $old_libs ]] +then + [[ -f $old_libs ]] || fail "$old_libs doesn't exist" + port_check_libs "$@" + exit $? +fi + +if [[ $# -eq 0 ]] +then + while IFS= read _lib + do + if ! port_check_lib "$_lib" + then + failed=1 + fi + done +else + for _lib + do + if ! port_check_lib "$_lib" + then + failed=1 + fi + done +fi + +exit $failed -- wbr, Kirill

No comments:

Post a Comment