Spdk/test/make/check_so_deps.sh
Seth Howell 2f476a638f autobuild.sh: simplify and unify test suite.
We have added a lot of flags to this script over time to try and shorten
parts of it that take a long time or modify the way we make and
whatnot.

In the test framework today we really have two settings, we either want
to run the entire autobuild package with all the bells and whistles, or
we just want to make the code and get on with the rest of the tests. I
believe this change can save between 1 and 3 minutes on each of the
functional test suites.

Change-Id: I7519e8320aa16b57f09f633f866dc36cb494aa80
Signed-off-by: Seth Howell <seth.howell@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/478483
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Paul Luse <paul.e.luse@intel.com>
Community-CI: SPDK CI Jenkins <sys_sgci@intel.com>
2020-01-14 07:49:08 +00:00

142 lines
4.4 KiB
Bash
Executable File

#!/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 ign_dep in "${IGNORED_LIBS[@]}"; do
for i in "${!lib_make_deps[@]}"; do
if [[ ${lib_make_deps[i]} == "$ign_dep" ]]; then
unset 'lib_make_deps[i]'
fi
done
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
$MAKE $MAKEFLAGS clean
./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)
IGNORED_LIBS=()
if grep -q 'CONFIG_VHOST_INTERNAL_LIB?=n' $rootdir/mk/config.mk; then
IGNORED_LIBS+=("rte_vhost")
fi
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