Lines 2-7
Link Here
|
2 |
# Spit out a portage-compatible list of packages to build because of lib |
2 |
# Spit out a portage-compatible list of packages to build because of lib |
3 |
# breakages. |
3 |
# breakages. |
4 |
|
4 |
|
|
|
5 |
declare quiet # if defined, output less noise |
6 |
declare avoid_utils # whitespace-delimited list of utils not to use |
7 |
declare checks # array of what checks to run |
8 |
|
9 |
# Exit and optionally output to sterr |
10 |
die() { |
11 |
local status=$1 |
12 |
shift |
13 |
echo "$@" >&2 |
14 |
exit $status |
15 |
} |
16 |
# Print out the commandline options |
5 |
print_usage() { |
17 |
print_usage() { |
6 |
cat << EOF |
18 |
cat << EOF |
7 |
Usage: $0 [OPTIONS] |
19 |
Usage: $0 [OPTIONS] |
Lines 10-22
Link Here
|
10 |
|
22 |
|
11 |
-h, --help Print this usage |
23 |
-h, --help Print this usage |
12 |
-e, --exact Emerge based on exact package version |
24 |
-e, --exact Emerge based on exact package version |
13 |
-q, --quiet Be less verbose (also passed to emerge command) |
25 |
-q, --quiet Be less verbose |
14 |
-u, --no-util UTIL Do not use features provided by UTIL |
26 |
-u, --no-util UTIL Do not use features provided by UTIL |
15 |
--no-util=UTIL UTIL can be one of portage-utils, pkgcore, or equery |
27 |
--no-util=UTIL UTIL can be one of portage-utils, pkgcore, or equery |
16 |
or it can be a *quoted* space-delimited list. |
28 |
or it can be a *quoted* space-delimited list. |
17 |
-L, --library NAME Emerge existing packages that use the library with NAME |
|
|
18 |
--library=NAME NAME can be a full path to the library or a basic |
19 |
regular expression (man grep) |
20 |
-b, --check-linking Check dynamic linking for binaries |
29 |
-b, --check-linking Check dynamic linking for binaries |
21 |
-l, --check-libtool Check *.la files for missing dependencies |
30 |
-l, --check-libtool Check *.la files for missing dependencies |
22 |
|
31 |
|
Lines 24-30
Link Here
|
24 |
|
33 |
|
25 |
Report bugs to <http://bugs.gentoo.org> |
34 |
Report bugs to <http://bugs.gentoo.org> |
26 |
EOF |
35 |
EOF |
|
|
36 |
# TODO: |
37 |
# -L, --library NAME Emerge existing packages that use the library with NAME |
38 |
# --library=NAME NAME can be a full path to the library or a basic |
39 |
# regular expression (man grep) |
40 |
} |
41 |
# Print feedback to stderr |
42 |
# Use stderr so as not to interfere with package-manager-friendly output |
43 |
# This function is redefined based on $quiet -- see get_args |
44 |
chatter() { |
45 |
[[ $quiet ]] && chatter() { :; } || chatter() { echo "$@" >&2; } |
46 |
chatter "$@" |
27 |
} |
47 |
} |
|
|
48 |
# Get the NEEDED sonames from scanelf and print out the ones that don't exist |
49 |
# on the filesystem. |
28 |
get_missing_sonames() { |
50 |
get_missing_sonames() { |
29 |
local soname IFS=$'\n,' list=($(scanelf -BLpF%n#F)) |
51 |
local soname IFS=$'\n,' list=($(scanelf -BLpF%n#F)) |
30 |
list=($(sort -u <<< "${list[*]}")) |
52 |
list=($(sort -u <<< "${list[*]}")) |
Lines 32-37
Link Here
|
32 |
[[ -e $soname ]] || echo $soname |
54 |
[[ -e $soname ]] || echo $soname |
33 |
done | sort -u |
55 |
done | sort -u |
34 |
} |
56 |
} |
|
|
57 |
# Get the package names for packages with missing sonames |
35 |
check_bins() { |
58 |
check_bins() { |
36 |
local missing_sonames broken_pkgs bin libs pv p |
59 |
local missing_sonames broken_pkgs bin libs pv p |
37 |
missing_sonames=$(get_missing_sonames) |
60 |
missing_sonames=$(get_missing_sonames) |
Lines 41-54
Link Here
|
41 |
while read bin libs; do |
64 |
while read bin libs; do |
42 |
feedback=$(grep -oF "$missing_sonames" <<< "$libs") |
65 |
feedback=$(grep -oF "$missing_sonames" <<< "$libs") |
43 |
feedback="${feedback##[[:space:]]}"; feedback="${feedback%%[[:space:]]}" |
66 |
feedback="${feedback##[[:space:]]}"; feedback="${feedback%%[[:space:]]}" |
44 |
echo "$bin is missing ${feedback//[[:space:]]/ and }" >&2 |
67 |
chatter "$bin is missing ${feedback//[[:space:]]/ and }" |
45 |
echo "$bin" |
68 |
echo "$bin" |
46 |
done <<< "$broken_pkgs" |
69 |
done <<< "$broken_pkgs" |
47 |
) | sort -u | slot |
70 |
) | sort -u | slot |
48 |
else |
71 |
else |
49 |
echo "Dynamic linking is consistent" >&2 |
72 |
chatter "Dynamic linking is consistent" |
50 |
fi |
73 |
fi |
51 |
} |
74 |
} |
|
|
75 |
# Get all the *.la files in likely places |
52 |
get_all_las() { |
76 |
get_all_las() { |
53 |
local IFS paths |
77 |
local IFS paths |
54 |
paths=( |
78 |
paths=( |
Lines 61-66
Link Here
|
61 |
paths=($(sort -u <<< "${paths[*]%/}")) |
85 |
paths=($(sort -u <<< "${paths[*]%/}")) |
62 |
find -L ${paths[@]} -type f -name '*.la' 2> /dev/null | sort -u |
86 |
find -L ${paths[@]} -type f -name '*.la' 2> /dev/null | sort -u |
63 |
} |
87 |
} |
|
|
88 |
# grep (heh) the dependency libs from the given .la file or files |
64 |
get_dependency_libs() { |
89 |
get_dependency_libs() { |
65 |
awk -F"[=']" '/^dependency_libs/{ |
90 |
awk -F"[=']" '/^dependency_libs/{ |
66 |
gsub("^-[^[:space:]]*", "", $NF); |
91 |
gsub("^-[^[:space:]]*", "", $NF); |
Lines 68-73
Link Here
|
68 |
print $NF |
93 |
print $NF |
69 |
}' "$@" |
94 |
}' "$@" |
70 |
} |
95 |
} |
|
|
96 |
# Get package names for packages owning las with missing dependencies |
71 |
check_las() { |
97 |
check_las() { |
72 |
local oIFS="$IFS" |
98 |
local oIFS="$IFS" |
73 |
local IFS |
99 |
local IFS |
Lines 80-86
Link Here
|
80 |
IFS="$oIFS" |
106 |
IFS="$oIFS" |
81 |
for dep in ${deps[@]}; do |
107 |
for dep in ${deps[@]}; do |
82 |
[[ $dep = /* && ! -e $dep ]] || continue |
108 |
[[ $dep = /* && ! -e $dep ]] || continue |
83 |
echo "$la is missing $dep" >&2 |
109 |
chatter "$la is missing $dep" |
84 |
echo "$la" |
110 |
echo "$la" |
85 |
done |
111 |
done |
86 |
done < <(get_all_las) | sort -u |
112 |
done < <(get_all_las) | sort -u |
Lines 89-97
Link Here
|
89 |
if (( ${#broken_las[@]} > 0)); then |
115 |
if (( ${#broken_las[@]} > 0)); then |
90 |
get_packages <<< "${broken_las[*]}" | sort -u | slot |
116 |
get_packages <<< "${broken_las[*]}" | sort -u | slot |
91 |
else |
117 |
else |
92 |
echo "No dependencies missing from .la files" >&2 |
118 |
chatter "No dependencies missing from .la files" |
93 |
fi |
119 |
fi |
94 |
} |
120 |
} |
|
|
121 |
# Convert category/package-version into category/package:slot |
122 |
# This function may be changed by commandline options: see get_args() |
95 |
slot() { |
123 |
slot() { |
96 |
while read pv; do |
124 |
while read pv; do |
97 |
p="${pv%%-r[[:digit:]]*}" |
125 |
p="${pv%%-r[[:digit:]]*}" |
Lines 99-125
Link Here
|
99 |
echo "$p:$(</var/db/pkg/$pv/SLOT)" |
127 |
echo "$p:$(</var/db/pkg/$pv/SLOT)" |
100 |
done |
128 |
done |
101 |
} |
129 |
} |
|
|
130 |
# Parse single-letter commandline options |
102 |
get_opts(){ |
131 |
get_opts(){ |
103 |
local x |
132 |
local x |
104 |
while getopts "behlqL:u:" opt; do |
133 |
while getopts ":behlqL:u:" opt; do |
105 |
case "$opt" in |
134 |
case "$opt" in |
106 |
L) SONAME="$OPTARG"; unset SEARCH_BROKEN;; |
135 |
# L) SONAME="$OPTARG"; unset SEARCH_BROKEN;; |
107 |
b) checks+=(linking);; |
136 |
b) checks+=(linking);; |
108 |
e) unset PACKAGE_NAMES;; |
137 |
e) unset PACKAGE_NAMES;; |
109 |
h) print_usage; exit 0;; |
138 |
h) print_usage; exit 0;; |
110 |
l) checks+=(libtool);; |
139 |
l) checks+=(libtool);; |
111 |
q) quiet=1; EMERGE_OPTIONS+=" $opt";; |
140 |
q) quiet=1;; |
112 |
u) avoid_utils+=" $opt ";; # TODO: Check validity |
141 |
u) avoid_utils+=" $opt ";; |
|
|
142 |
:) validate_arg "$OPTARG";; |
113 |
esac |
143 |
esac |
114 |
x=$OPTIND |
144 |
x=$OPTIND |
115 |
done |
145 |
done |
116 |
shift $((x-1)) |
146 |
shift $((x-1)) |
117 |
} |
147 |
} |
|
|
148 |
# Make sure needed arguments exist |
118 |
validate_arg() { |
149 |
validate_arg() { |
119 |
[[ $1 && $1 != -* ]] || die 1 "Missing expected argument to $1" |
150 |
[[ $2 && $2 != -* ]] && return |
120 |
} |
151 |
print_usage |
|
|
152 |
(( ${#1} == 1 )) && die 1 "Missing expected argument to -$1" |
153 |
die 1 "Missing expected argument to $1" |
154 |
} |
155 |
# Get the name of a package owning a file on the filesystem using one of several |
156 |
# utilities: This is a placeholder. The function is defined in get_args() |
157 |
get_packages() { :; } |
158 |
# Parse commandline arguments |
121 |
get_args() { |
159 |
get_args() { |
122 |
declare avoid_utils checks |
|
|
123 |
if [[ ! $1 ]]; then print_usage; exit 0; fi |
160 |
if [[ ! $1 ]]; then print_usage; exit 0; fi |
124 |
while [[ $1 ]]; do |
161 |
while [[ $1 ]]; do |
125 |
case $1 in |
162 |
case $1 in |
Lines 127-143
Link Here
|
127 |
--help) print_usage; exit 0;; |
164 |
--help) print_usage; exit 0;; |
128 |
--exact) slot() { while read pv; do echo "=$pv"; done };; |
165 |
--exact) slot() { while read pv; do echo "=$pv"; done };; |
129 |
--quiet) quiet=1;; |
166 |
--quiet) quiet=1;; |
130 |
--library=*) search_lib="${1#*=}";; |
167 |
# --library=*) search_lib="${1#*=}";; |
131 |
--library) validate_arg "$1"; shift; search_lib="$1";; |
168 |
# --library) validate_arg "$1 $2"; shift; search_lib="$1";; |
132 |
--no-util=*) avoid_utils+=" ${1#*=} ";; # TODO: Check validity |
169 |
--no-util=*) avoid_utils+=" ${1#*=} ";; # TODO: Check validity |
133 |
--no-util) validate_arg "$1"; shift; avoid_utils+=" $1 ";; |
170 |
--no-util) validate_arg "$1 $2"; shift; avoid_utils+=" $1 ";; |
134 |
--check-linking) checks+=(linking);; |
171 |
--check-linking) checks+=(linking);; |
135 |
--check-libtool) checks+=(libtool);; |
172 |
--check-libtool) checks+=(libtool);; |
136 |
--) break;; |
173 |
--) break;; |
137 |
*) echo "Invalid parameter $1:" >&2; print_usage; exit 1;; |
174 |
*) print_usage; die 1 "Invalid parameter $1";; |
138 |
esac |
175 |
esac |
139 |
shift |
176 |
shift |
140 |
done |
177 |
done |
|
|
178 |
# Rewrite get_packages based on what's available and possibly the commandline |
179 |
# arg --no-util |
141 |
if [[ avoid_utils != *portage-utils* ]] && hash qfile 2> /dev/null; then |
180 |
if [[ avoid_utils != *portage-utils* ]] && hash qfile 2> /dev/null; then |
142 |
get_packages() { qfile -qvC "$@"; } |
181 |
get_packages() { qfile -qvC "$@"; } |
143 |
elif [[ avoid_utils != *pkgcore* ]] && hash pquery 2> /dev/null; then |
182 |
elif [[ avoid_utils != *pkgcore* ]] && hash pquery 2> /dev/null; then |
Lines 152-157
Link Here
|
152 |
sed 's:/var/db/pkg/\(.*\)/CONTENTS:=\1:' |
191 |
sed 's:/var/db/pkg/\(.*\)/CONTENTS:=\1:' |
153 |
} |
192 |
} |
154 |
fi |
193 |
fi |
|
|
194 |
# Run the program, checking items requested at the commandline |
155 |
for check in ${checks[@]}; do |
195 |
for check in ${checks[@]}; do |
156 |
case $check in |
196 |
case $check in |
157 |
linking) check_bins;; |
197 |
linking) check_bins;; |