]> git.ipfire.org Git - people/ms/ipfire-3.x.git/blob - pkgs/build-essentials/buildsystem-tools/functions-packager-find
Merge branch 'master' of ssh://git.ipfire.org/pub/git/ipfire-3.x
[people/ms/ipfire-3.x.git] / pkgs / build-essentials / buildsystem-tools / 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
42 # Get provides, because packages should not depend on features they provide
43 # by themselves.
44 local provides=$(find_provides ${dirs})
45
46 # Return a sorted and unique(!) list
47 local require
48 local requires
49 for require in $(listsort ${PKG_DEPS} ${interpreters} ${neededs} ${links} ${others}); do
50 [ "${require:0:3}" = "ld-" ] && continue
51 listmatch ${require} ${provides} || requires="${requires} ${require}"
52 done
53
54 echo ${requires}
55 }
56
57 function find_provides() {
58 local dirs=$@
59
60 local file
61 local sonames
62 for file in $(find_elf_files ${dirs}); do
63 sonames="${sonames} $(file_get_soname ${file})"
64 done
65 sonames=$(listsort ${sonames})
66
67 # Others
68 local others=$(find_python_provides ${dirs})
69 others="${others} $(find_weak_symbols_provides ${dirs})"
70 others="${others} $(find_perl_provides ${dirs})"
71
72 listsort ${PKG_PROVIDES} ${sonames} ${others}
73 }
74
75 function find_interpreters() {
76 local dirs=$@
77
78 log DEBUG "Searching for interpreters in ${dirs}"
79
80 local file
81 local interpreter
82 local interpreters
83 for file in $(find ${dirs} -type f 2>/dev/null); do
84 # Get interpreter information from file.
85 interpreter=$(file_get_interpreter ${file})
86
87 # Skip the file silently if the result was empty.
88 [ -z "${interpreter}" ] && continue
89
90 # Skip invalid interpreters that don't start with a slash.
91 if [ "${interpreter:0:1}" != "/" ]; then
92 log WARNING "Skipping invalid interpreter \"${interpreter}\" from \"${file}\"."
93 continue
94 fi
95
96 if ! listmatch ${interpreter} ${INTERPRETERS_TO_BE_SKIPPED}; then
97 interpreters="${interpreters} ${interpreter}"
98 fi
99 done
100
101 interpreters=$(listsort ${interpreters})
102
103 log DEBUG "find_interpreters ${dirs}: ${interpreters}"
104
105 echo "${interpreters}"
106 }
107
108 # Find the destinations of all symlinks and adds a dependency for that.
109 #
110 function find_symlink_destinations() {
111 local dir=$@
112
113 local link
114 local links
115 for link in $(find ${dir} -type l 2>/dev/null); do
116 link="$(readlink -m ${link})"
117 [ -e "${link}" ] && continue
118
119 link="${link#${dir}}"
120 links="${links} ${link}"
121 done
122
123 echo ${links}
124 }
125
126 function find_python_provides() {
127 local dir=${1}
128
129 local file
130 for file in $(find ${dir}/usr/bin/python* 2>/dev/null); do
131 file=$(basename ${file})
132 file=${file#python}
133
134 if [ -n "${file}" ]; then
135 echo "python-api=${file}"
136 fi
137 done
138 }
139
140 function find_python_requires() {
141 local dir=${1}
142
143 local file
144 for file in $(find ${dir}/usr/lib -maxdepth 1 2>/dev/null); do
145 file=$(basename ${file})
146
147 if [ "${file:0:6}" = "python" ]; then
148 file=${file#python}
149
150 if [ -n "${file}" ]; then
151 echo "python-api=${file}"
152 fi
153 fi
154 done
155 }
156
157 function find_perl_files() {
158 local extension
159 for extension in pm pl; do
160 find $@ -name "*.${extension}" 2>/dev/null
161 done
162 }
163
164 function find_perl_provides() {
165 [ -x "/usr/bin/perl" ] || return 0
166 ${BASEDIR}/perl.prov $(find_perl_files $@) | sort -u
167 }
168
169 function find_perl_requires() {
170 [ -x "/usr/bin/perl" ] || return 0
171 ${BASEDIR}/perl.req $(find_perl_files $@) | sort -u
172 }
173
174 function find_weak_symbols_provides() {
175 local dirs=$@
176
177 local file
178 local soname
179 local symbol
180 for file in $(find_elf_files ${dirs}); do
181 soname=$(file_get_soname ${file})
182 [ -z "${soname}" ] && continue
183
184 for symbol in $(objdump -p ${file} | grep -E "^[0-9]+" | awk '{ print $4 }'); do
185 [ "${symbol}" = "${soname}" ] && continue
186 [ "${symbol}" = "GLIBC_PRIVATE" ] && continue
187
188 echo "${soname}(${symbol})"
189 done
190 done | sort -u
191 }
192
193 function find_weak_symbols_requires() {
194 local dirs=$@
195
196 local file
197 for file in $(find_elf_files ${dirs}); do
198 objdump -p ${file} | awk 'BEGIN { START=0; LIBNAME=""; }
199 /^$/ { START=0; }
200 /^Dynamic Section:$/ { START=1; }
201 (START==1) && /NEEDED/ {
202 print $2;
203 }
204 (START==2) && /^[A-Za-z]/ { START=3; }
205 /^Version References:$/ { START=2; }
206 (START==2) && /required from/ {
207 sub(/:/, "", $3);
208 LIBNAME=$3;
209 }
210 (START==2) && (LIBNAME!="") && ($4!="") && (($4~/^GLIBC_*/) || ($4~/^GCC_*/)) {
211 print LIBNAME "(" $4 ")";
212 }'
213 done | grep -v "GLIBC_PRIVATE" | sort -u
214 }