]> git.ipfire.org Git - pakfire.git/blob - scripts/functions-packager-find
1b488d9f7b9144d04a515ea7068abbed55d0008e
[pakfire.git] / scripts / functions-packager-find
1 #!/bin/bash
2
3 # A function that finds needed libraries and interpreters.
4 #
5 function find_requires() {
6 local dir
7 local dirs=$@
8
9 # Find interpreters of all files in the dirs and skip those we provide
10 # ourself.
11 local interpreter
12 local interpreters
13 for interpreter in $(find_interpreters ${dirs}); do
14 local found=0
15 for dir in ${dirs}; do
16 if [ -e "${dir}/${interpreter}" ]; then
17 found=1
18 break
19 fi
20 done
21
22 [ "${found}" = "0" ] && interpreters="${interpreters} ${interpreter}"
23 done
24
25 # Find NEEDED libs and add them to a list if they are not provided by any
26 # other file in dirs.
27 local neededs
28 for file in $(find_elf_files ${dirs}); do
29 for needed in $(file_get_needed ${file}); do
30 neededs="${neededs} ${needed}"
31 done
32 done
33
34 # Find all symlink destinations
35 local links=$(find_symlink_destinations ${dirs})
36
37 # Others
38 local others=$(find_python_requires ${dirs})
39 others="${others} $(find_weak_symbols_requires ${dirs})"
40 others="${others} $(find_perl_requires ${dirs})"
41 others="${others} $(find_pkgconfig_requires ${dirs})"
42
43 # Return a sorted and unique(!) list
44 local require
45 local requires
46 for require in $(listsort ${PKG_DEPS} ${interpreters} ${neededs} ${links} ${others}); do
47 [ "${require:0:3}" = "ld-" ] && continue
48
49 if [ -n "${PKG_REQUIRES_FILTER}" ]; then
50 grep -qE "${PKG_REQUIRES_FILTER}" <<< "${require}" && continue
51 fi
52
53 requires="${requires} ${require}"
54 done
55
56 echo ${requires}
57 }
58
59 function find_provides() {
60 local dirs=$@
61
62 local file
63 local sonames
64 for file in $(find_elf_files ${dirs}); do
65 sonames="${sonames} $(file_get_soname ${file})"
66 done
67 sonames=$(listsort ${sonames})
68
69 # Others
70 local others=$(find_python_provides ${dirs})
71 others="${others} $(find_weak_symbols_provides ${dirs})"
72 others="${others} $(find_perl_provides ${dirs})"
73 others="${others} $(find_pkgconfig_provides ${dirs})"
74
75 local provide
76 local provides
77 for provide in $(listsort ${PKG_PROVIDES} ${sonames} ${others}); do
78 if [ -n "${PKG_PROVIDES_FILTER}" ]; then
79 grep -qE "${PKG_PROVIDES_FILTER}" <<< "${provide}" && continue
80 fi
81
82 provides="${provides} ${provide}"
83 done
84
85 echo ${provides}
86 }
87
88 function find_interpreters() {
89 local dirs=$@
90
91 log DEBUG "Searching for interpreters in ${dirs}"
92
93 local file
94 local interpreter
95 local interpreters
96 for file in $(find ${dirs} -type f 2>/dev/null); do
97 # Get interpreter information from file.
98 interpreter=$(file_get_interpreter ${file})
99
100 # Skip the file silently if the result was empty.
101 [ -z "${interpreter}" ] && continue
102
103 # Skip invalid interpreters that don't start with a slash.
104 if [ "${interpreter:0:1}" != "/" ]; then
105 log WARNING "Skipping invalid interpreter \"${interpreter}\" from \"${file}\"."
106 continue
107 fi
108
109 if ! listmatch ${interpreter} ${INTERPRETERS_TO_BE_SKIPPED}; then
110 interpreters="${interpreters} ${interpreter}"
111 fi
112 done
113
114 interpreters=$(listsort ${interpreters})
115
116 log DEBUG "find_interpreters ${dirs}: ${interpreters}"
117
118 echo "${interpreters}"
119 }
120
121 # Find the destinations of all symlinks and adds a dependency for that.
122 #
123 function find_symlink_destinations() {
124 local dir=$@
125
126 local link
127 local links
128 for link in $(find ${dir} -type l 2>/dev/null); do
129 link="$(readlink -m ${link})"
130 [ -e "${link}" ] && continue
131
132 link="${link#${dir}}"
133 links="${links} ${link}"
134 done
135
136 echo ${links}
137 }
138
139 function find_python_provides() {
140 local dir=${1}
141
142 local file
143 for file in $(find ${dir}/usr/bin/python* 2>/dev/null); do
144 file=$(basename ${file})
145 file=${file#python}
146
147 if [ -n "${file}" ]; then
148 echo "python-api=${file}"
149 fi
150 done
151 }
152
153 function find_python_requires() {
154 local dir=${1}
155
156 local file
157 for file in $(find ${dir}/usr/lib -maxdepth 1 2>/dev/null); do
158 file=$(basename ${file})
159
160 if [ "${file:0:6}" = "python" ]; then
161 file=${file#python}
162
163 if [ -n "${file}" ]; then
164 echo "python-api=${file}"
165 fi
166 fi
167 done
168 }
169
170 function find_perl_files() {
171 local extension
172 for extension in pm pl; do
173 find $@ -name "*.${extension}" 2>/dev/null
174 done
175 }
176
177 function find_perl_provides() {
178 [ -x "/usr/bin/perl" ] || return 0
179 perl ${BASEDIR}/perl.prov $(find_perl_files $@) | sort -u
180 }
181
182 function find_perl_requires() {
183 [ -x "/usr/bin/perl" ] || return 0
184 perl ${BASEDIR}/perl.req $(find_perl_files $@) | sort -u
185 }
186
187 function find_pkgconfig_provides() {
188 [ -x "/usr/bin/pkg-config" ] || return 0
189 find $@ | ${BASEDIR}/pkg-config.prov
190 }
191
192 function find_pkgconfig_requires() {
193 [ -x "/usr/bin/pkg-config" ] || return 0
194 find $@ | ${BASEDIR}/pkg-config.req
195 }
196
197 function find_weak_symbols_provides() {
198 local dirs=$@
199
200 local file
201 local soname
202 local symbol
203 for file in $(find_elf_files ${dirs}); do
204 soname=$(file_get_soname ${file})
205 [ -z "${soname}" ] && continue
206
207 for symbol in $(objdump -p ${file} | grep -E "^[0-9]+" | awk '{ print $4 }'); do
208 [ "${symbol}" = "${soname}" ] && continue
209 [ "${symbol}" = "GLIBC_PRIVATE" ] && continue
210
211 echo "${soname}(${symbol})"
212 done
213 done | sort -u
214 }
215
216 function find_weak_symbols_requires() {
217 local dirs=$@
218
219 local file
220 for file in $(find_elf_files ${dirs}); do
221 objdump -p ${file} | awk 'BEGIN { START=0; LIBNAME=""; }
222 /^$/ { START=0; }
223 /^Dynamic Section:$/ { START=1; }
224 (START==1) && /NEEDED/ {
225 print $2;
226 }
227 (START==2) && /^[A-Za-z]/ { START=3; }
228 /^Version References:$/ { START=2; }
229 (START==2) && /required from/ {
230 sub(/:/, "", $3);
231 LIBNAME=$3;
232 }
233 (START==2) && (LIBNAME!="") && ($4!="") && (($4~/^GLIBC_*/) || ($4~/^GCC_*/)) {
234 print LIBNAME "(" $4 ")";
235 }'
236 done | grep -v "GLIBC_PRIVATE" | sort -u
237 }