diff --git a/check_linking.sh b/check_linking.sh new file mode 100755 index 0000000..cd3263e --- /dev/null +++ b/check_linking.sh @@ -0,0 +1,105 @@ +#!/bin/bash +# +# Library dependency check script inspired by revdep-rebuild of Gentoo Linux +# +# Christoph Niethammer (C) 2011 +# + +declare -r APP_NAME="${0##*/}" +declare -r VERSION="0.1" +declare -r FILES_FILE=1_files.rr +declare -r BROKEN_FILE=2_broken.rr +declare findMask +declare MODULE_NAMES +declare SEARCH_DIRS + + +# extract path information from module file +find_paths() { + local pathspec=$1 + local PATHS=$( module display $MODULE_NAME |& awk "/.*path[[:space:]]+$pathspec[[:space:]]+/{ sub(/.*path[[:space:]]+$pathspec[[:space:]]+/,\"\"); print }" ) + for path in $PATHS; do + SEARCH_DIRS+="$path " + done +} + + + +function print_usage { + +binary=`basename $0` +cat < + +Usage: $APP_NAME MODULE + +-h, --help Print this usage + +Checks linking consistency of given modules. + +EOF +} + + + +############################################################################## +# MAIN +############################################################################## + +if [ $# -lt 1 ]; then + print_usage + exit 0 +fi + +for arg in $@; do + case $arg in + --help|-h) + print_usage + exit 0 + ;; + *) + MODULE_NAMES+="${IFS}${arg}" + ;; + esac +done + + + +for MODULE_NAME in $MODULE_NAMES; do + find_paths PATH + find_paths LD_LIBRARY_PATH +done + +echo "SEARCH_DIRS=$SEARCH_DIRS" + +find ${SEARCH_DIRS[@]} $findMask -type f \( -perm -u+x -o -perm -g+x -o -perm -o+x -o \ + -name '*.so' -o -name '*.so.*' -o -name '*.la' \) -print 2> /dev/null | + sort -u > "$FILES_FILE" + +files=($(<"$FILES_FILE")) + +for target_file in "${files[@]}"; do + if ! file $target_file | grep ELF > /dev/null ; then + continue + fi + if [[ $target_file != *.la ]]; then + ldd_output=$(ldd "$target_file" 2> /dev/null) + MISSING_LIBS=$( + expr='s/[[:space:]]*\([^[:space:]]*\) => not found/\1/p' + sed -n "$expr" <<< "$ldd_output" + ) + 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") + + if [[ $MISSING_LIBS ]]; then + echo "obj $target_file" >> "$BROKEN_FILE" + echo " broken $target_file (requires $MISSING_LIBS)" + fi + fi +done +