3 # A function that finds needed libraries and interpreters.
5 function find_requires
() {
9 # Find interpreters of all files in the dirs and skip those we provide
13 for interpreter
in $
(find_interpreters
${dirs}); do
15 for dir
in ${dirs}; do
16 if [ -e "${dir}/${interpreter}" ]; then
22 [ "${found}" = "0" ] && interpreters="${interpreters} ${interpreter}"
25 # Find NEEDED libs and add them to a list if they are not provided by any
28 for file in $
(find_elf_files
${dirs}); do
29 for needed
in $
(file_get_needed
${file}); do
30 neededs
="${neededs} ${needed}"
34 # Find all symlink destinations
35 local links
=$
(find_symlink_destinations
${dirs})
38 local others
=$
(find_python_requires
${dirs})
39 others
="${others} $(find_weak_symbols_requires ${dirs})"
40 others
="${others} $(find_perl_requires ${dirs})"
42 # Get provides, because packages should not depend on features they provide
44 local provides
=$
(find_provides
${dirs})
46 # Return a sorted and unique(!) list
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}"
57 function find_provides() {
62 for file in $(find_elf_files ${dirs}); do
63 sonames="${sonames} $
(file_get_soname
${file})"
65 sonames=$(listsort ${sonames})
68 local others=$(find_python_provides ${dirs})
69 others="${others} $
(find_weak_symbols_provides
${dirs})"
70 others="${others} $
(find_perl_provides
${dirs})"
72 listsort ${PKG_PROVIDES} ${sonames} ${others}
75 function find_interpreters() {
78 log DEBUG "Searching
for interpreters
in ${dirs}"
83 for file in $(find ${dirs} -type f 2>/dev/null); do
84 # Get interpreter information from file.
85 interpreter=$(file_get_interpreter ${file})
87 # Skip the file silently if the result was empty.
88 [ -z "${interpreter}" ] && continue
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}\".
"
96 if ! listmatch ${interpreter} ${INTERPRETERS_TO_BE_SKIPPED}; then
97 interpreters="${interpreters} ${interpreter}"
101 interpreters=$(listsort ${interpreters})
103 log DEBUG "find_interpreters
${dirs}: ${interpreters}"
105 echo "${interpreters}"
108 # Find the destinations of all symlinks and adds a dependency for that.
110 function find_symlink_destinations() {
115 for link in $(find ${dir} -type l 2>/dev/null); do
116 link="$
(readlink
-m ${link})"
117 [ -e "${link}" ] && continue
119 link="${link#${dir}}"
120 links="${links} ${link}"
126 function find_python_provides() {
130 for file in $(find ${dir}/usr/bin/python* 2>/dev/null); do
131 file=$(basename ${file})
134 if [ -n "${file}" ]; then
135 echo "python-api
=${file}"
140 function find_python_requires() {
144 for file in $(find ${dir}/usr/lib -maxdepth 1 2>/dev/null); do
145 file=$(basename ${file})
147 if [ "${file:0:6}" = "python
" ]; then
150 if [ -n "${file}" ]; then
151 echo "python-api
=${file}"
157 function find_perl_files() {
159 for extension in pm pl; do
160 find $@ -name "*.
${extension}" 2>/dev/null
164 function find_perl_provides() {
165 [ -x "/usr
/bin
/perl
" ] || return 0
166 ${BASEDIR}/perl.prov $(find_perl_files $@) | sort -u
169 function find_perl_requires() {
170 [ -x "/usr
/bin
/perl
" ] || return 0
171 ${BASEDIR}/perl.req $(find_perl_files $@) | sort -u
174 function find_weak_symbols_provides() {
180 for file in $(find_elf_files ${dirs}); do
181 soname=$(file_get_soname ${file})
182 [ -z "${soname}" ] && continue
184 for symbol in $(objdump -p ${file} | grep -E "^
[0-9]+" | awk '{ print $4 }'); do
185 [ "${symbol}" = "${soname}" ] && continue
186 [ "${symbol}" = "GLIBC_PRIVATE
" ] && continue
188 echo "${soname}(${symbol})"
193 function find_weak_symbols_requires() {
197 for file in $(find_elf_files ${dirs}); do
198 objdump -p ${file} | awk 'BEGIN { START=0; LIBNAME=""; }
200 /^Dynamic Section:$/ { START=1; }
201 (START==1) && /NEEDED/ {
204 (START==2) && /^[A-Za-z]/ { START=3; }
205 /^Version References:$/ { START=2; }
206 (START==2) && /required from/ {
210 (START==2) && (LIBNAME!="") && ($4!="") && (($4~/^GLIBC_*/) || ($4~/^GCC_*/)) {
211 print LIBNAME "(" $4 ")";
213 done | grep -v "GLIBC_PRIVATE
" | sort -u