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>
142 lines
4.4 KiB
Bash
Executable File
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
|