1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
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
|