#!/bin/bash # # Common functions to copy binaries and their dependancies. # ############################################################ # # Usage: get_dynamic_dependencies [-l ] # * the list must be seperated by spaces # * the search for lib needed by a binary can be done locally, # using the -l option # # Ouput: # Will simply echo list of required libraries # List of libraries to exclude from BLACKLIST="ld-linux linux-gate linux-vdso libc.so" LOCALSEARCH=0 LOCALSEARCHDIR="" CURRENT_BLACKLIST=$(echo ${BLACKLIST} | sed 's/ /\\|/g') get_dynamic_dependencies() { if [ "x$1" == "x-l" ]; then LOCALSEARCH=1 shift [ ! -d $1 ] && perror "Directory given does not exist, exiting." LOCALSEARCHDIR=$1 shift fi while [ $# != 0 ]; do local BINARY=$1 shift local LDD_OUT="ldd_output" if ldd $BINARY > $LDD_OUT; then # Case 1: dynamic for LIB in $(cat $LDD_OUT | grep -v "${CURRENT_BLACKLIST}" | awk '{print $1 $2 $3}'); do # split the entry into an array, ex: # libm.so.6 => /lib/libm.so.6 would be split into: # liblink[0] liblink[1] local liblink=(${LIB//=>/ }) lib_search done else # Case 2: not a dynamic pdebug "\t\t\t(Not a dynamic.)" rm -f $LDD_OUT continue fi rm -f $LDD_OUT done } lib_search(){ # if activated, start by searching the lib locally if [ "x$LOCALSEARCH" == "x1" ]; then cd $LOCALSEARCHDIR local LOCAL_MATCHES=$(find . -name "${liblink[0]}") # | awk -F '.' '{print $1}')".so\*) cd - &>/dev/null if [ "x${LOCAL_MATCHES}" != "x" ]; then for llib in ${LOCAL_MATCHES}; do get_link_chain "${LOCALSEARCHDIR}"/"${llib}" "${LOCALSEARCHDIR}" get_dynamic_dependencies -l "${LOCALSEARCHDIR}" "${llib}" CURRENT_BLACKLIST+="\|${liblink[0]}" done # found the libs, we are done return fi # mark local search as done fi # search the lib on the system since it was not found earlier if [ ! -z ${liblink[1]} ] && [ "x${liblink[1]}" != "xnot" ]; then # get chain of symlink for that lib get_link_chain ${liblink[1]} CURRENT_BLACKLIST+="\|${liblink[1]}" else pwarning "\t\tLib '${liblink[0]}' from required dir '$ENTRY' neither found in build directory nor on this system." pwarning "\t\tIf this lib is not supplied by another module, this module will probably fail in your final system" fi } ############################################################ # # Usage: get_link_chain [prefix] # # must be in absolute form- # [prefix] is the prefix to strip from the ouput. # # Output: # Lists the symlink chain until a hardlink is found. get_link_chain() { # sanity checks if [[ "$1" == /* ]]; then [ -e $1 ] || perror "get_link_chain: no such file: $1" else perror "get_link_chain() requires absolute paths, given: $1" fi if [ $# == 2 ] ; then [ ! -d $2 ] && perror "get_link_chain: $2 is not a directory." # got a prefix local PREFIX=$(readlink -f $2) else # mark prefix as not set local PREFIX="notset" fi # canonalize local LINK=$(canonicalize $1) local CHAIN="$LINK" # write the first link in the chain if [ "x$PREFIX" != "x" -a "x$PREFIX" != "xnotset" ]; then if [ "x${LINK#$PREFIX}" == "x${LINK}" ]; then # prefix was not in the link echo "$LINK" else # prefix was in the link echo ./"${LINK#$PREFIX}" fi else # no prefix, copy like it is echo "$LINK" fi # now we check for symlinks local TRY=0 while [ -L $LINK ] && [ $TRY -lt 10 ]; do let TRY=TRY+1 # save the directory prefix CURRENTDIR=$(dirname ${LINK}) # first follow the link LINK=$(readlink $LINK) CHAIN+=" -> $LINK" # $LINK can be absolute or relative, check cases [[ "$LINK" == /* ]] || LINK=$(canonicalize "$CURRENTDIR"/"${LINK}") # write the first link in the chain if [ "x$PREFIX" != "x" -a "x$PREFIX" != "xnotset" ]; then if [ "x${LINK#$PREFIX}" == "x${LINK}" ]; then # prefix was not in the link echo "$LINK" else # prefix was in the link echo ./"${LINK#$PREFIX}" fi else # no prefix, copy like it is echo "$LINK" fi done pdebug "\t\t$CHAIN" } # Function to get libc and ld-linux list_basic_libs() { for i in $(ldd ${SHELL}) do [ $(echo $i | grep '^/' | grep -c ld) -eq 1 -o $(echo $i | grep '^/' | grep -c libc.so) -eq 1 ] && get_link_chain $i done }