So. I wanted to install
gnupg from FreeBSD ports on an older box. Somehow it depended on something that depended on the LDAP libraries. Which broke authentication on the box. And in fixing that, lots of other dependencies needed to be updated. It turned into a horrible mess and some ports wouldn’t reinstall cleanly and no amount of
portmaster shenanigans would fix it without removing swathes of stuff first.
In trying to find out which shared libraries were now broken, I wrote a very crude script to find out which binaries broke.
# simple hack to find local binaries with broken library dependencies
[ -z "$dirs" ] && dirs="/usr/local/bin /usr/local/sbin /usr/local/libexec /usr/local/lib"
for dir in $dirs; do
for file in "$dir"/*; do
if [ -x "$file" ]; then
l=$(ldd "$file" 2>&1 | grep "=> not found" | sed -e 's/=> not found.*//')
if [ "$l" != "" ]; then
pkg=$(find /var/db/pkg -type f -name '+CONTENTS' -print0 | \
xargs -0 grep "/$p\$" | cut -d: -f1 | sort -u | \
sed -e 's/^.var.db.pkg.//' -e 's/.+CONTENTS$//')
echo $p: $pkg: $l
In short, it finds executable files that
ldd reports as having missing runtime dependencies and attempts to find those in the package directory (so you have a clue which packages it came from).
libfam to something else, just to test the script, and this was the output:
# sh /home/chrisy/bin/find-broken-libs
imapd: courier-imap-4.8.1,2 imap-uw-2007e,1: libfam.so.0
maildiracl: courier-imap-4.8.1,2: libfam.so.0
maildirkw: courier-imap-4.8.1,2: libfam.so.0
maildrop: maildrop-2.5.2: libfam.so.0
First field is the file that is broken. Second field are FreeBSD ports (packages) that contain files with that name. Last field shows the missing libraries.
If no package uses a broken binary then that field in the output stays blank, wit:
# sh ~chrisy/bin/find-broken-libs
libgnutls-extra.so.15: : libintl.so.8 libintl.so.8
libgnutls-openssl.so.15: : libintl.so.8 libintl.so.8
libgnutls.so.15: : libintl.so.8
libgnutlsxx.so.15: : libintl.so.8
I’m posting this in case someone else finds it useful…