Index: revdep-rebuild =================================================================== --- revdep-rebuild (revision 474) +++ revdep-rebuild (working copy) @@ -29,6 +29,7 @@ declare RM_OLD_TEMPFILES # ...remove tempfiles from prior runs declare SEARCH_BROKEN # ...search for broken libraries and binaries declare VERBOSE # ...give verbose output +declare EMERGE_OWNER # ...emerge the owner of a soname # Globals that impact portage directly: declare EMERGE_DEFAULT_OPTS # String of options portage assumes to be set @@ -62,6 +63,8 @@ declare SONAME_SEARCH # Value of SONAME modified to match ldd's output declare WORKING_TEXT # Feedback about the search declare ENV_FILE # A file containing environment variables +declare -a LIB_OWNERS # The packages owning the libraries specified + # as arguments to --library rm() { local i @@ -126,6 +129,8 @@ -l, --no-ld-path Do not set LD_LIBRARY_PATH -o, --no-order Do not check the build order (Saves time, but may cause breakage.) + -O, --merge-owner Remerge the owner of the library being searched + (Ignored if -L is not used.) -p, --pretend Do a trial run without actually emerging anything (also passed to emerge command) -P, --no-progress Turn off the progress meter @@ -158,6 +163,19 @@ progress() { :; } fi } +## +# has item list +# returns 0 if item is in list, 1 otherwise +has() { + local IFS=$'\a' + [[ $@ != *${IFS}* ]] || + die 1 "function has() fails miserably if any argument contains a BEL." + local item="$1" + shift + local -a list=( "$@" ) + # has() will reflect the exit code of the following: + [[ "${IFS}${list[*]}${IFS}" = *"${IFS}${item}${IFS}"* ]] +} # Usage: countdown n # n: number of seconds to count countdown() { @@ -297,6 +315,7 @@ SONAME="$1" unset SEARCH_BROKEN;; --no-ld-path) unset FULL_LD_PATH;; + --emerge-owner) EMERGE_OWNER=1;; --no-order) unset ORDER_PKGS;; --no-progress) progress() { :; };; --pretend) EMERGE_OPTIONS+=("--pretend");; @@ -328,7 +347,7 @@ # Get single-letter commandline options preceded by a single dash. get_shortopts() { local OPT OPTSTRING OPTARG OPTIND - while getopts ":CdehikL:loPpqu:vX" OPT; do + while getopts ":CdehikL:lOoPpqu:vX" OPT; do case "$OPT" in C) # TODO: Match syntax with the rest of gentoolkit export NOCOLOR="yes";; @@ -342,6 +361,7 @@ SONAME="${OPTARG#*=}" unset SEARCH_BROKEN;; l) unset FULL_LD_PATH;; + O) EMERGE_OWNER=1;; o) unset ORDER_PKGS;; P) progress() { :; };; p) EMERGE_OPTIONS+=("--pretend");; @@ -516,6 +536,7 @@ fi local uuid="${SONAME##*/}" uuid="${uuid//[[:space:]]}" + uuid="${uuid//\*}" LIST+="_$uuid" HEAD_TEXT="using $SONAME" OK_TEXT="There are no dynamic links to $SONAME" @@ -668,15 +689,25 @@ else # FIXME: I hate duplicating code # Only rebuild for direct dependencies - MISSING_LIBS=$( - expr="/$SONAME_SEARCH/s/^[[:space:]]*\([^[:space:]]*\).*$/\1/p" - sort -u <<< "$ldd_output" | sed -n "$expr" - ) + # FIXME: If the grep matches more than one line it'll screw up the + # LIB_OWNERS array. + local soname_matchline=( $( + sort -u <<< "$ldd_output" | grep "$SONAME_SEARCH" + ) ) + if [[ ! ${SEARCH_BROKEN}${EMERGE_OWNER} ]]; then + # The third item in soname_matchline should be the full path to the + # soname that we're searching for + if [[ ${#soname_matchline[@]} -eq 4 && ${soname_matchline[2]} ]] + then + local owner=$(get_file_owner "${soname_matchline[2]}") + has "$owner" "${LIB_OWNERS[@]}" || LIB_OWNERS+=("$owner") + fi + fi REQUIRED_LIBS=$( expr='s/^[[:space:]]*NEEDED[[:space:]]*\([^[:space:]]*\).*/\1/p'; objdump -x "$target_file" | grep NEEDED | sed "$expr" | sort -u ) - MISSING_LIBS=$(grep -F "$REQUIRED_LIBS" <<< "$MISSING_LIBS") + MISSING_LIBS=$(grep -F "$REQUIRED_LIBS" <<< "${soname_matchline[0]}") if [[ $MISSING_LIBS ]]; then echo "obj $target_file" >> "$LIST.3_rebuild" if [[ $SEARCH_BROKEN ]]; then @@ -740,6 +771,12 @@ while read obj target_file; do EXACT_PKG=$(get_file_owner $target_file) if [[ $EXACT_PKG ]]; then + # Skip packages owned by the SONAME searched. + # http://bugs.gentoo.org/30095 + if [[ $LIB_OWNERS ]] && has "$EXACT_PKG" "${LIB_OWNERS[@]}"; then + [[ $VERBOSE ]] && einfo " $target_file -> $EXACT_PKG (skipped)" + continue + fi # Strip version information PKG="${EXACT_PKG%%-r[[:digit:]]*}" PKG="${PKG%-*}"