Annotation of /trunk/depend-tools/linking_libs.sh
Parent Directory | Revision Log
Revision 331 -
(hide annotations)
(download)
(as text)
Mon Feb 20 00:14:24 2006 UTC (18 years, 8 months ago) by niro
File MIME type: application/x-sh
File size: 4307 byte(s)
Mon Feb 20 00:14:24 2006 UTC (18 years, 8 months ago) by niro
File MIME type: application/x-sh
File size: 4307 byte(s)
new files
1 | niro | 331 | #!/bin/bash |
2 | |||
3 | # CHANGES | ||
4 | # | ||
5 | # 20051211: Move most of the logic to check for bad links into get_libnames() | ||
6 | # seds, so we don't wrongly sed out whole link lines. Seems to catch more | ||
7 | # problems, such as ' or ` or -- in a link. | ||
8 | # 20051210: Prefer qfile from portage-utils over equery if it's available. | ||
9 | # Check for ... in "link" lines because configure checks are not links. | ||
10 | # Change get_link_generic() to handle whole lines at a time instead of single | ||
11 | # words, so get_linklines() works. | ||
12 | # 20051210: Rework get_libnames() to use a new style of grep, because the old | ||
13 | # way was broken on some packages from the \b. Also optimize the "Looking for | ||
14 | # libraries" section to only grep the log file once for links and cache it; | ||
15 | # also only grep the link lines ones for a given library, then parse the | ||
16 | # output for static or shared. Should speed things up considerably for large | ||
17 | # packages. I get 5 seconds in Analyzing log and 15 in Looking for libs on an | ||
18 | # xorg-x11-6.8.99.15 log on second run. | ||
19 | # Create get_link_generic() that both sections call with different options. | ||
20 | |||
21 | log=${1} | ||
22 | |||
23 | usage() { | ||
24 | echo "${0##*/} compilation_log" | ||
25 | echo " Checks for -lfoo link commands and finds the library owners." | ||
26 | exit 1 | ||
27 | } | ||
28 | |||
29 | if [[ $# -ne 1 ]]; then | ||
30 | usage | ||
31 | fi | ||
32 | |||
33 | |||
34 | # Finds all lines in a file that involve linking | ||
35 | # get_link_generic(char *grep_opts, char *filename) | ||
36 | get_link_generic() { | ||
37 | egrep ${1} '\-l\w[^[:space:]]*' ${2} \ | ||
38 | | while read linker; do | ||
39 | # -linker is passed through to ld and doesn't mean the inker lib. | ||
40 | # The new -w in grep makes sure they're separate "words", but its | ||
41 | # "word" characters only include alnum and underscore, so -- gets | ||
42 | # through. | ||
43 | # Some configure lines with ... match, so we drop them | ||
44 | # Some of the configure options match, so we get rid of = for that. | ||
45 | if \ | ||
46 | [[ "${linker}" != *...* ]] \ | ||
47 | && [[ "${linker}" != -lib ]] \ | ||
48 | && [[ "${linker}" != -libs ]]; then | ||
49 | echo ${linker} | ||
50 | fi | ||
51 | done | ||
52 | } | ||
53 | |||
54 | # Note the lack of -o, as compared to get_libnames() egrep | ||
55 | get_linklines() { | ||
56 | get_link_generic "-w" ${1} | sort | uniq | ||
57 | } | ||
58 | |||
59 | get_libnames() { | ||
60 | get_link_generic "-o -w" ${1} \ | ||
61 | | sed \ | ||
62 | -e "/^-link/d" \ | ||
63 | -e "/^-lib/d" \ | ||
64 | -e "s:^-l::g" \ | ||
65 | -e "/=/d" \ | ||
66 | -e "/'/d" \ | ||
67 | -e "/^-/d" \ | ||
68 | -e "s:\.*$::g" \ | ||
69 | -e "s:|::g" \ | ||
70 | -e "s:\"::g" \ | ||
71 | -e "/^-link/d" \ | ||
72 | -e "/^-lib/d" \ | ||
73 | | sort \ | ||
74 | | uniq | ||
75 | } | ||
76 | |||
77 | get_libdirs() { | ||
78 | cat /etc/ld.so.conf | sed -e "/^#/d" | ||
79 | } | ||
80 | |||
81 | # *64 needs to be first, as *lib is a symlink to it so equery screws up | ||
82 | libdirs="/lib64 /usr/lib64 /lib /usr/lib $(get_libdirs)" | ||
83 | |||
84 | echo "Analyzing log ..." | ||
85 | libnames="$(get_libnames ${1})" | ||
86 | |||
87 | #echo libnames=$libnames | ||
88 | |||
89 | echo "Looking for libraries ..." | ||
90 | linker_lines=$(get_linklines ${1}) | ||
91 | |||
92 | #echo linker_lines=$linker_lines | ||
93 | |||
94 | for libname in ${libnames}; do | ||
95 | static=0 | ||
96 | shared=0 | ||
97 | line=$(echo ${linker_lines} | grep "\b-l${libname}\b") | ||
98 | if echo ${line} | grep -q '\b-static\b'; then | ||
99 | static=1 | ||
100 | fi | ||
101 | if ! echo ${line} | grep -q '\b-static\b'; then | ||
102 | shared=1 | ||
103 | fi | ||
104 | staticlibname="lib${libname}.a" | ||
105 | sharedlibname="lib${libname}.so" | ||
106 | if [[ ${static} -eq 1 ]]; then | ||
107 | echo -n " Looking for ${staticlibname} ... " | ||
108 | for libdir in ${libdirs}; do | ||
109 | found=0 | ||
110 | if [[ -e ${libdir}/${staticlibname} ]]; then | ||
111 | libpaths="${libpaths} ${libdir}/${staticlibname}" | ||
112 | found=1 | ||
113 | echo "OK" | ||
114 | break | ||
115 | fi | ||
116 | done | ||
117 | if [[ ${found} -ne 1 ]]; then | ||
118 | echo "Not found!" | ||
119 | fi | ||
120 | fi | ||
121 | if [[ ${shared} -eq 1 ]]; then | ||
122 | echo -n " Looking for ${sharedlibname} ... " | ||
123 | for libdir in ${libdirs}; do | ||
124 | found=0 | ||
125 | if [[ -e ${libdir}/${sharedlibname} ]]; then | ||
126 | libpaths="${libpaths} ${libdir}/${sharedlibname}" | ||
127 | found=1 | ||
128 | echo "OK" | ||
129 | break | ||
130 | fi | ||
131 | done | ||
132 | if [[ ${found} -ne 1 ]]; then | ||
133 | echo "Not found!" | ||
134 | fi | ||
135 | fi | ||
136 | done | ||
137 | |||
138 | # Add backslashes in front of any + symbols | ||
139 | libpaths=${libpaths//+/\\+} | ||
140 | |||
141 | echo "Tracing libraries back to packages ..." | ||
142 | echo | ||
143 | if [[ -x $(which qfile 2> /dev/null) ]]; then | ||
144 | qfile ${libpaths} | cut -d'(' -f1 | sort | uniq | ||
145 | elif [[ -x $(which equery 2> /dev/null) ]]; then | ||
146 | equery -q belongs ${libpaths} | cut -d'(' -f1 | ||
147 | elif [[ -x /sbin/magequery ]]; then | ||
148 | for i in ${libpaths}; do | ||
149 | /sbin/magequery -f ${i} | ||
150 | done | sort -u | ||
151 | elif [[ -x $(which rpm 2> /dev/null) ]]; then | ||
152 | rpm -qf ${libpaths} | ||
153 | else | ||
154 | echo "Couldn't find package query tool! Printing libpaths instead." | ||
155 | echo | ||
156 | for libpath in ${libpaths}; do | ||
157 | echo ${libpath} | ||
158 | done | ||
159 | fi |