diff -r 11cc7a5102fa -r 758d5137fe87 scripts/populate.in --- a/scripts/populate.in Sun Mar 28 23:01:19 2010 +0200 +++ b/scripts/populate.in Mon Mar 29 00:15:32 2010 +0200 @@ -185,6 +185,12 @@ local mode for dir in lib usr/lib; do + if [ -e "${dir}/${libname}" ]; then + ${CT_PRINTF} " already present\n" + return 0 + fi + done + for dir in lib usr/lib; do ${CT_PRINTF} " trying in '%s'" "${dir}" libfile="${CT_SYSROOT_DIR}/${dir}/${libname}" ${CT_PRINTF} ": '%s'\n" "${libfile}" @@ -200,12 +206,36 @@ esac ${CT_PRINTF} " installing as '%s/%s', mode='%s'\n" "${dir}" "${true_libname}" "${mode}" "${install}" -m "${mode}" "${libfile}" "${dir}/${true_libname}" + do_resolve_deps "${dir}/${true_libname}" return 0 fi done return 1 } +# A function to resolve all NEEDED entries for the given file, relative +# to the working directory (eg. dst_dir) +# Usage: do_resolve_deps some/where/some/file +# Returns: 0, meaning all dependencies were found +# If not all dependencies could be found, exists with error code 1 +# (unless forced) +do_resolve_deps() { + local file="${1}" + local libname + + for libname in $("${CT_READELF}" -d "${file}" \ + |"${grep}" -E '\(NEEDED\)[[:space:]]+Shared library:' \ + |"${sed}" -r -e 's,.+\[(.+)\] *$,\1,;' \ + ); do + [ -n "${libname}" ] || continue + ${CT_PRINTF} "Searching for '%s' needed by '%s'\n" "${libname}" "${file}" + if ! do_add_lib "${libname}"; then + printf "$myname: library '${libname}' not found!\n" + [ "${CT_FORCE}" = "y" ] || exit 1 + fi + done +} + # We'll work in the copied rootfs cd "${CT_ROOT_DST_DIR}" @@ -223,12 +253,11 @@ |"${sed}" -r -e 's/^:+//; s/:+$//; s/:+/ /g;' \ ) if [ -n "${CT_LIB_LIST}" ]; then - ${CT_PRINTF} "Installing forced libraries...\n" for name in ${CT_LIB_LIST}; do [ -z "${name}" ] && continue found=0 for libname in "lib${name}.so" "${name}.so" "${name}"; do - ${CT_PRINTF} " searching for '%s'\n" "${libname}" + ${CT_PRINTF} "Searching for forced library '%s'\n" "${libname}" if do_add_lib "${libname}"; then found=1 break @@ -241,35 +270,28 @@ done fi -# Parse the working copy for executables and libraries -still_needed=1 -while [ ${still_needed} -eq 1 ]; do - ${CT_PRINTF} "Looping...\n" - still_needed=0 - for f in $(find . -type f -exec file {} \; \ - |"${grep}" -E ': ELF [[:digit:]]+-bit (L|M)SB (executable|shared object),' \ - |cut -d ":" -f 1 \ - ); do - ${CT_PRINTF} "Scanning '%s'\n" "${f}" - for libname in $("${CT_READELF}" -d "${f}" \ - |"${grep}" -E '\(NEEDED\)[[:space:]]+Shared library:' \ - |"${sed}" -r -e 's,.+\[(.+)\] *$,\1,;' \ - ); do - ${CT_PRINTF} " searching for '%s'\n" "${libname}" - if [ -e "lib/${libname}" \ - -o -e "usr/lib/${libname}" ]; then - ${CT_PRINTF} " already present\n" - continue - fi - if do_add_lib "${libname}"; then - still_needed=1 - else - printf "$myname: library '${libname}' not found!\n" - [ "${CT_FORCE}" = "y" ] || exit 1 - fi - done - done -done +# Create a temporary place where to store... temp files. +rand="$( dd if=/dev/urandom bs=1024 count=1 2>/dev/null \ + |md5sum \ + |awk '{ print $1; }' + )" +CT_TMP_DIR="${TMPDIR:-/tmp}/populate-${rand}-${$}" +( umask 0077; mkdir "${CT_TMP_DIR}" ) || { printf "Could not create temporary directory\n"; exit 1; } +trap "rm -rf ${CT_TMP_DIR}" EXIT + +# List all ELF (executables|shared objects)... +find . -type f -exec file {} \; \ +|"${grep}" -E ': ELF [[:digit:]]+-bit (L|M)SB (executable|shared object),' \ +|cut -d ":" -f 1 \ +>"${CT_TMP_DIR}/files.list" + +# ... and use that list to find missing dependencies +while read file; do + do_resolve_deps "${file}" +done <"${CT_TMP_DIR}/files.list" + +rm -rf "${CT_TMP_DIR}" +trap - EXIT # OK, we're done. Back off. cd - >/dev/null