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
|
# Check for pkg-config file issues
pkgconfig_check() {
local files=()
# Make a list of .pc files and bail out if there aren't any
mapfile -d '' files < <(
find "${ED}"/usr/{lib*,share}/pkgconfig -maxdepth 1 -type f -name '*.pc' -print0 2>/dev/null
)
[[ -z "${files[@]}" ]] && return
local f
# Look for leaking LDFLAGS into pkg-config files
f=$(grep -E -zsH '^Libs.*-Wl,(-O[012]|--hash-style)' "${files[@]}")
if [[ -n ${f} ]] ; then
eqawarn "QA Notice: pkg-config files with wrong LDFLAGS detected:"
eqatag -v pkgconfig.bad-ldlags "${f//${D}}"
fi
# Bail out now so we can rely on pkgconfig in subsequent checks if we want.
if ! type -P pkg-config >/dev/null ; then
return
fi
# Validate using pkgconfig
# Some less common implementations may not support this?
# seems like f.d.o, OpenBSD, and of course pkgconf do though.
# Need --maximum-traverse-depth=1 to avoid checking deps and giving
# unrelated warnings/errors.
if ! pkg-config --maximum-traverse-depth=1 --with-path="${ED}"/usr/{lib*,share}/pkgconfig --validate "${files[@]}" ; then
eqawarn "QA Notice: pkg-config files which fail validation found!"
eqawarn "Run 'pkg-config --validate ...' for more information"
fi
# Check for unexpected paths
# e.g. https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=c90ab38e3577aae61fac2341b34ad593948de1cd
if [[ -n ${EPREFIX} ]] ; then
for f in "${files[@]}" ; do
local key
for key in prefix exec_prefix libdir includedir ; do
# Check if the variable is even in there (bug #860825)
grep -E -q "^${key}" "${f}" || continue
local value=$(pkg-config --variable="${key}" "${f}")
if [[ ${value} != "${EPREFIX}"* ]] ; then
eqawarn "QA Notice: pkg-config files not respecting EPREFIX found"
eqawarn "key=${key} does not respect EPREFIX:"
eqawarn "${key}=${value}"
eqatag -v pkgconfig.bad-paths ${key}="${value}" "${f//${D}}"
# Don't bother repeating for every variable in the same file
break
fi
done
done
fi
# TODO: Generalise for non-lib64 libdir? Not that this is very common now
# that riscv chose a more standard layout.
#
# If we're installing to ${ED}/usr/lib/pkgconfig, let's make sure
# we're not referencing lib64.
#
# e.g. https://bugs.gentoo.org/729642
local bad_libdir=()
for f in "${files[@]}" ; do
if [[ ${f} == *lib/pkgconfig* ]] ; then
if [[ -d "${ED}"/usr/lib && -L "${ED}"/usr/lib ]] ; then
# (Don't bother if /usr/lib is a symlink to /usr/lib64)
continue
fi
# In ${ED}/usr/lib, we shouldn't reference lib64
if grep -E -q "=(/usr)?/lib64" ${f} ; then
bad_libdir+=( "${f//${D}}" )
fi
elif [[ ${f} == *lib64/pkgconfig* ]] ; then
# We want to match /lib/, /lib/foo/, but not e.g. /lib64 or /lib64/, or libfoo
if grep -qP '=(/usr)?/lib\b' ${f} ; then
bad_libdir+=( "${f//${D}}" )
fi
fi
done
if [[ -n "${bad_libdir[@]}" ]] ; then
eqawarn "QA Notice: pkg-config files not respecting libdir found"
eqawarn "(contains reference to either lib or lib64 in wrong directory)"
eqatag -v pkgconfig.bad-libdir "${bad_libdir[@]}"
fi
# Check for mismatched Version field vs ${PV}
# To be safe, let's make sure _all_ installed .pcs have a bad Version
# before warning, as this should catch the general cases we're worried
# about, while avoiding any pathological cases e.g. multiple libraries
# with different versioning within one package.
# Example bugs: bug #833895, bug #833887.
# Default to PV if QA_PKGCONFIG_VERSION is unset.
if [[ -z ${QA_PKGCONFIG_VERSION+set} ]]; then
local QA_PKGCONFIG_VERSION=${PV}
fi
# Skip the check if QA_PKGCONFIG_VERSION is set to empty string.
if [[ -n ${QA_PKGCONFIG_VERSION} ]]; then
local pms_ver_re="^([0-9]+(\.[0-9]+)*)([a-z]?)((_(alpha|beta|pre|rc|p)[0-9]*)*)(-r[0-9]+)?$"
local -A bad_files
local is_pms_ver=false
if [[ ${QA_PKGCONFIG_VERSION} =~ ${pms_ver_re} ]] ; then
# Ensure that ver_test is available.
[[ $(type -t ver_test) == function ]] || inherit eapi7-ver
is_pms_ver=true
fi
for f in "${files[@]}" ; do
local file_version=$(pkg-config --modversion "${f}")
if [[ -n ${file_version} ]] ; then
if ${is_pms_ver} && [[ ${file_version} =~ ${pms_ver_re} ]]; then
# If both versions comply to PMS, then we can use ver_test to compare them.
ver_test ${QA_PKGCONFIG_VERSION} -eq ${file_version} && continue
else
# Otherwise, we resort to string comparision.
[[ ${QA_PKGCONFIG_VERSION} == ${file_version} ]] && continue
fi
else
# Record a special value if the .pc file has no version set at all.
file_version="<no-set>"
fi
bad_files["${f//${D}}"]="${file_version}"
done
# Skip result reporting if *_p* because for both _pN and _preN, we
# don't generally expect the versions to be exactly accurate, and
# we want to avoid false positives.
if [[ ${#bad_files[@]} -gt 0 && ${PV} != *_p* ]] && ! has live ${PROPERTIES} ; then
eqawarn "QA Notice: pkg-config files with mismatched Version found!"
eqawarn "The Version field of the following files does not match ${PV}"
local bad_file
for bad_file in "${!bad_files[@]}"; do
local bad_file_version="${bad_files[${bad_file}]}"
eqawarn "- ${bad_file}: ${bad_file_version}"
done
eqawarn "Please check all .pc files installed by this package."
eqawarn "You can use QA_PKGCONFIG_VERSION to set the expected version,"
eqawarn "or set to the empty string to disable this QA check."
eqatag pkgconfig.unexpected-version ${!bad_files[@]}
fi
fi
}
pkgconfig_check
: # guarantee successful exit
# vim:ft=sh
|