Magellan Linux

Annotation of /trunk/depend-tools/linking_libs.sh

Parent Directory Parent Directory | Revision Log Revision Log


Revision 331 - (hide annotations) (download) (as text)
Mon Feb 20 00:14:24 2006 UTC (18 years, 2 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