134 lines
4.2 KiB
Bash
134 lines
4.2 KiB
Bash
|
#!/usr/bin/env bash
|
||
|
|
||
|
if [ "$(uname -s)" = "FreeBSD" ]; then
|
||
|
echo "Not testing for shared object dependencies on FreeBSD."
|
||
|
exit 0
|
||
|
fi
|
||
|
|
||
|
rootdir=$(readlink -f $(dirname $0)/../..)
|
||
|
source "$rootdir/test/common/autotest_common.sh"
|
||
|
|
||
|
libdir="$rootdir/build/lib"
|
||
|
libdeps_file="$rootdir/mk/spdk.lib_deps.mk"
|
||
|
|
||
|
# This function is needed to properly evaluate the Make variables into actual dependencies.
|
||
|
function replace_defined_variables() {
|
||
|
local arr=("$@")
|
||
|
local bad_values=()
|
||
|
local good_values=()
|
||
|
local new_values
|
||
|
for dep in "${arr[@]}"; do
|
||
|
if [[ $dep == *'$'* ]]; then
|
||
|
raw_dep=${dep/$\(/}
|
||
|
raw_dep=${raw_dep/\)/ }
|
||
|
bad_values+=("$raw_dep")
|
||
|
else
|
||
|
good_values+=("$dep")
|
||
|
fi
|
||
|
done
|
||
|
for dep in "${bad_values[@]}"; do
|
||
|
dep_def_arr=($(cat $libdeps_file | grep -v "#" | grep "${dep}" | cut -d "=" -f 2 | xargs))
|
||
|
new_values=($(replace_defined_variables "${dep_def_arr[@]}"))
|
||
|
good_values=( "${good_values[@]}" "${new_values[@]}" )
|
||
|
done
|
||
|
echo ${good_values[*]}
|
||
|
}
|
||
|
|
||
|
function confirm_deps() {
|
||
|
lib=$1
|
||
|
missing_syms=()
|
||
|
dep_names=()
|
||
|
found_symbol_lib=""
|
||
|
|
||
|
#keep the space here to differentiate bdev and bdev_*
|
||
|
lib_shortname=$(basename $lib | sed 's,libspdk_,,g' | sed 's,\.so, ,g')
|
||
|
lib_make_deps=($(cat $libdeps_file | grep "DEPDIRS-${lib_shortname}" | cut -d "=" -f 2 | xargs))
|
||
|
lib_make_deps=($(replace_defined_variables "${lib_make_deps[@]}"))
|
||
|
|
||
|
for dep in ${lib_make_deps[@]}; do
|
||
|
if [[ $dep == *'$'* ]]; then
|
||
|
dep_no_dollar=$(echo $dep | sed 's,$(,,g' | sed 's,),,g')
|
||
|
fi
|
||
|
done
|
||
|
|
||
|
symbols=$(readelf -s $lib | grep -E "NOTYPE.*GLOBAL.*UND" | awk '{print $8}' | sort | uniq)
|
||
|
for symbol in $symbols; do
|
||
|
for deplib in $DEP_LIBS; do
|
||
|
if [ "$deplib" == "$lib" ]; then
|
||
|
continue
|
||
|
fi
|
||
|
found_symbol=$(readelf -s $deplib | grep -E "DEFAULT\s+[0-9]+\s$symbol$") || true
|
||
|
if [ "$found_symbol" != "" ]; then
|
||
|
found_symbol_lib=$(basename $deplib | sed 's,libspdk_,,g' | sed 's,\.so,,g')
|
||
|
break
|
||
|
fi
|
||
|
done
|
||
|
if [ "$found_symbol" == "" ]; then
|
||
|
missing_syms+=("$symbol")
|
||
|
else
|
||
|
dep_names+=("$found_symbol_lib")
|
||
|
fi
|
||
|
done
|
||
|
IFS=$'\n'
|
||
|
# Ignore any event_* dependencies. Those are based on the subsystem configuration and not readelf.
|
||
|
lib_make_deps=( $(printf "%s\n" ${lib_make_deps[@]} | sort | grep -v "event_") )
|
||
|
# Ignore the env_dpdk readelf dependency. We don't want people explicitly linking against it.
|
||
|
dep_names=( $(printf "%s\n" ${dep_names[@]} | sort | uniq | grep -v "env_dpdk") )
|
||
|
unset IFS
|
||
|
diff=$(echo ${dep_names[@]} ${lib_make_deps[@]} | tr ' ' '\n' | sort | uniq -u)
|
||
|
if [ "$diff" != "" ]; then
|
||
|
touch $fail_file
|
||
|
echo "there was a dependency mismatch in the library $lib_shortname"
|
||
|
echo "The makefile lists: '${lib_make_deps[*]}'"
|
||
|
echo "readelf outputs : '${dep_names[*]}'"
|
||
|
echo "---------------------------------------------------------------------"
|
||
|
elif [ ${#missing_syms[@]} -ne 0 ]; then
|
||
|
echo "There are still undefined symbols in the library $lib_shortname"
|
||
|
printf "%s\n" ${missing_syms[@]}
|
||
|
echo "---------------------------------------------------------------------"
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
# By removing the spdk.lib_deps.mk file from spdk.lib.mk, we ensure that we won't
|
||
|
# create any link dependencies. Then we can be sure we get a valid accounting of the
|
||
|
# symbol dependencies we have.
|
||
|
sed -i -e 's,include $(SPDK_ROOT_DIR)/mk/spdk.lib_deps.mk,,g' "$rootdir/mk/spdk.lib.mk"
|
||
|
|
||
|
if [ "$SPDK_TEST_OCF" -eq 1 ]; then
|
||
|
config_params="$config_params --with-ocf=$rootdir/build/ocf.a"
|
||
|
fi
|
||
|
|
||
|
./configure $config_params --with-shared
|
||
|
$MAKE $MAKEFLAGS
|
||
|
|
||
|
xtrace_disable
|
||
|
|
||
|
echo "---------------------------------------------------------------------"
|
||
|
# Exclude libspdk_env_dpdk.so from the library list. We don't link against this one so that
|
||
|
# users can define their own environment abstraction. However we do want to still check it
|
||
|
# for dependencies to avoid printing out a bunch of confusing symbols under the missing
|
||
|
# symbols section.
|
||
|
SPDK_LIBS=$(ls -1 $libdir/libspdk_*.so | grep -v libspdk_env_dpdk.so)
|
||
|
DEP_LIBS=$(ls -1 $libdir/libspdk_*.so)
|
||
|
|
||
|
fail_file=$output_dir/check_so_deps_fail
|
||
|
|
||
|
rm -f $fail_file
|
||
|
|
||
|
for lib in $SPDK_LIBS; do
|
||
|
confirm_deps $lib&
|
||
|
done
|
||
|
|
||
|
wait
|
||
|
|
||
|
$MAKE $MAKEFLAGS clean
|
||
|
git checkout "$rootdir/mk/spdk.lib.mk"
|
||
|
|
||
|
if [ -f $fail_file ]; then
|
||
|
rm -f $fail_file
|
||
|
echo "shared object test failed"
|
||
|
exit 1
|
||
|
fi
|
||
|
|
||
|
xtrace_restore
|