diff options
author | B. Watson <urchlay@slackware.uk> | 2024-11-04 21:02:07 -0500 |
---|---|---|
committer | B. Watson <urchlay@slackware.uk> | 2024-11-04 21:02:07 -0500 |
commit | 5e9481388d3d3cf810d0d8d7a9535466424c54b6 (patch) | |
tree | 371872d8bc4f380ef4a7f4d904a035d3121a51ce | |
parent | 05ded05770fab09df662efc73a9c92c2338e42d6 (diff) | |
download | sbo-maintainer-tools-master.tar.gz |
-rw-r--r-- | NEWS | 8 | ||||
-rw-r--r-- | sbopkglint.d/95-pkgconfig.t.sh | 159 |
2 files changed, 167 insertions, 0 deletions
@@ -1,6 +1,14 @@ The real ChangeLog is the git log. This is just a summary of the user-visible changes between releases. +New in 0.9.4: +============= + +sbopkglint: +- check .pc files for validity, ownerships/perms, correct lib dir (lib + vs. lib64) and make sure any -I or -L dirs from pkg-config actually exist + in the package. + New in 0.9.3: ============= diff --git a/sbopkglint.d/95-pkgconfig.t.sh b/sbopkglint.d/95-pkgconfig.t.sh new file mode 100644 index 0000000..64156bb --- /dev/null +++ b/sbopkglint.d/95-pkgconfig.t.sh @@ -0,0 +1,159 @@ +#!/bin/sh + +# sbopkglint test, must be sourced by sbopkglint (not run standalone). + +# PKG, PRGNAM, VERSION, ARCH are set by sbopkglint. also the current +# directory is the root of the installed package tree. + +####################################################################### +# Test .pc (pkgconfig) files. +# - pkgconfig dir must match ARCH (lib vs. lib64). +# - pkg-config must be able to read and parse each file. +# - paths mentioned in the file must exist in the package. +# - for a 32-bit package, libdir must not be /usr/lib64. +# - for a 64-bit package, libdir must not be /usr/lib. +# - .pc files must be either ASCII or Unicode/UTF-8. + +# note: quite a few .pc files don't use the standard variables like +# libdir. it's not required, so we can't just check for that. have to +# actually run pkg-config --cflags and --libs... but we have to +# rip any 'Requires:' line out first, because otherwise, pkg-config +# would pull in the flags/libs from any package mentioned there (if +# installed), or else complain that it doesn't exist. + +check_libinc_dir() { + local type=$1 + local flag=$2 + local file=$3 + local dir + + #echo "===> $flag" + + dir="$( printf "%s" $flag | tail -c+3 )" + [ -d $PKG/$dir ] || warn "$file references $type dir $dir, but it's missing from the package" +} + +check_pc_file() { + local file="$1" + local tmpfile="./$1.tmp.pc" + local mime + local s + + ## echo "===> checking $file" + + if [ ! -f "$file" ]; then + warn "$file is not a regular file:" + ls -ld "$file" + return + fi + + s="$( stat -L -c '%a %U %G' "$file" )" + case "$s" in + "444 root root"|"644 root root") ;; # OK + *) + warn "$file has bad ownership/permissions (should be 0644, root/root)" + ls -ld $file + ;; + esac + + if [ "$s" = "444 root root" ]; then + : # we could warn here someday + elif [ "$s" != "644 root root" ]; then + BADPERMS+="$f " + fi + + + mime="$(file -bL --mime $file)" + + case "$mime" in + text/plain*) + case "$mime" in + *charset=us-ascii|*charset=utf-8) ;; # OK + *) warn "$file has bad character encoding '$( echo "$mime" | sed 's,.*charset=,,' )' (should be us-ascii or utf-8)" + ;; + esac + ;; + *) warn "$file is '$mime', not plain text (are you sure it's a .pc file?)" + ;; + esac + + case "$file" in + *.pc) ;; # OK + *) warn "$file is not a .pc file" ; return ;; + esac + + if ! pkg-config --validate $file; then + warn "$file is not a valid .pc file" + return + fi + + grep -v '^Requires:' $file > $tmpfile + + # the environment stuff keeps pkg-config from stripping out + # -L/usr/lib or -L/usr/lib64 on the grounds that it's a system dir. + for flag in xxx \ + $( env PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 \ + PKG_CONFIG_SYSTEM_LIBRARY_PATH=1 \ + pkg-config --short-errors --libs --cflags $tmpfile ) + do + ## echo "===> $flag" + case $flag in + xxx) ;; # skip (it's just there in case there are no flags at all) + -L/usr/$bad) + warn "$file has /usr/$bad for libdir, should be /usr/$good" + ;; + -L*) check_libinc_dir library "$flag" "$file" + ;; + -I*) check_libinc_dir include "$flag" "$file" + ;; + *) ;; # skip any other flags (-lwhatever, -Dwhatever, etc) + esac + done + + rm -f $tmpfile +} + +check_pc_dir() { + local file + local dir=$1 + + if [ ! -d $dir ]; then + warn "$dir exists but is not a directory!" + return + fi + + # cumbersome way to check if a dir is empty + if [ "$( find $dir -maxdepth 0 -empty )" != "" ]; then + return + fi + + for file in $dir/*; do + check_pc_file $file + done +} + +check_pkgconfig() { + local good bad bits dir + + if [ "$ARCH" = "x86_64" -o "$ARCH" = "aarch64" ]; then + good=lib64; bad=lib; bits=64 + else + good=lib; bad=lib64; bits=32 + fi + + gooddir=usr/$good/pkgconfig + baddir=usr/$bad/pkgconfig + if [ -d $baddir ]; then + if [ -d $gooddir ]; then + warn "$bits-bit package has both $baddir (wrong) and $gooddir (OK)" + else + warn "$bits-bit package has $baddir, should be $gooddir" + fi + fi + + for dir in $baddir $gooddir usr/share/pkgconfig; do + [ -d $dir ] && check_pc_dir $dir + done +} + +check_pkgconfig |