162306a36Sopenharmony_ci#!/bin/bash 262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 362306a36Sopenharmony_ci# kselftest_deps.sh 462306a36Sopenharmony_ci# 562306a36Sopenharmony_ci# Checks for kselftest build dependencies on the build system. 662306a36Sopenharmony_ci# Copyright (c) 2020 Shuah Khan <skhan@linuxfoundation.org> 762306a36Sopenharmony_ci# 862306a36Sopenharmony_ci# 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ciusage() 1162306a36Sopenharmony_ci{ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ciecho -e "Usage: $0 -[p] <compiler> [test_name]\n" 1462306a36Sopenharmony_ciecho -e "\tkselftest_deps.sh [-p] gcc" 1562306a36Sopenharmony_ciecho -e "\tkselftest_deps.sh [-p] gcc mm" 1662306a36Sopenharmony_ciecho -e "\tkselftest_deps.sh [-p] aarch64-linux-gnu-gcc" 1762306a36Sopenharmony_ciecho -e "\tkselftest_deps.sh [-p] aarch64-linux-gnu-gcc mm\n" 1862306a36Sopenharmony_ciecho "- Should be run in selftests directory in the kernel repo." 1962306a36Sopenharmony_ciecho "- Checks if Kselftests can be built/cross-built on a system." 2062306a36Sopenharmony_ciecho "- Parses all test/sub-test Makefile to find library dependencies." 2162306a36Sopenharmony_ciecho "- Runs compile test on a trivial C file with LDLIBS specified" 2262306a36Sopenharmony_ciecho " in the test Makefiles to identify missing library dependencies." 2362306a36Sopenharmony_ciecho "- Prints suggested target list for a system filtering out tests" 2462306a36Sopenharmony_ciecho " failed the build dependency check from the TARGETS in Selftests" 2562306a36Sopenharmony_ciecho " main Makefile when optional -p is specified." 2662306a36Sopenharmony_ciecho "- Prints pass/fail dependency check for each tests/sub-test." 2762306a36Sopenharmony_ciecho "- Prints pass/fail targets and libraries." 2862306a36Sopenharmony_ciecho "- Default: runs dependency checks on all tests." 2962306a36Sopenharmony_ciecho "- Optional: test name can be specified to check dependencies for it." 3062306a36Sopenharmony_ciexit 1 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci} 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci# Start main() 3562306a36Sopenharmony_cimain() 3662306a36Sopenharmony_ci{ 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_cibase_dir=`pwd` 3962306a36Sopenharmony_ci# Make sure we're in the selftests top-level directory. 4062306a36Sopenharmony_ciif [ $(basename "$base_dir") != "selftests" ]; then 4162306a36Sopenharmony_ci echo -e "\tPlease run $0 in" 4262306a36Sopenharmony_ci echo -e "\ttools/testing/selftests directory ..." 4362306a36Sopenharmony_ci exit 1 4462306a36Sopenharmony_cifi 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ciprint_targets=0 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ciwhile getopts "p" arg; do 4962306a36Sopenharmony_ci case $arg in 5062306a36Sopenharmony_ci p) 5162306a36Sopenharmony_ci print_targets=1 5262306a36Sopenharmony_ci shift;; 5362306a36Sopenharmony_ci esac 5462306a36Sopenharmony_cidone 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ciif [ $# -eq 0 ] 5762306a36Sopenharmony_cithen 5862306a36Sopenharmony_ci usage 5962306a36Sopenharmony_cifi 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci# Compiler 6262306a36Sopenharmony_ciCC=$1 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_citmp_file=$(mktemp).c 6562306a36Sopenharmony_citrap "rm -f $tmp_file.o $tmp_file $tmp_file.bin" EXIT 6662306a36Sopenharmony_ci#echo $tmp_file 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_cipass=$(mktemp).out 6962306a36Sopenharmony_citrap "rm -f $pass" EXIT 7062306a36Sopenharmony_ci#echo $pass 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_cifail=$(mktemp).out 7362306a36Sopenharmony_citrap "rm -f $fail" EXIT 7462306a36Sopenharmony_ci#echo $fail 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci# Generate tmp source fire for compile test 7762306a36Sopenharmony_cicat << "EOF" > $tmp_file 7862306a36Sopenharmony_ciint main() 7962306a36Sopenharmony_ci{ 8062306a36Sopenharmony_ci} 8162306a36Sopenharmony_ciEOF 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci# Save results 8462306a36Sopenharmony_citotal_cnt=0 8562306a36Sopenharmony_cifail_trgts=() 8662306a36Sopenharmony_cifail_libs=() 8762306a36Sopenharmony_cifail_cnt=0 8862306a36Sopenharmony_cipass_trgts=() 8962306a36Sopenharmony_cipass_libs=() 9062306a36Sopenharmony_cipass_cnt=0 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci# Get all TARGETS from selftests Makefile 9362306a36Sopenharmony_citargets=$(grep -E "^TARGETS +|^TARGETS =" Makefile | cut -d "=" -f2) 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci# Initially, in LDLIBS related lines, the dep checker needs 9662306a36Sopenharmony_ci# to ignore lines containing the following strings: 9762306a36Sopenharmony_cifilter="\$(VAR_LDLIBS)\|pkg-config\|PKG_CONFIG\|IOURING_EXTRA_LIBS" 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci# Single test case 10062306a36Sopenharmony_ciif [ $# -eq 2 ] 10162306a36Sopenharmony_cithen 10262306a36Sopenharmony_ci test=$2/Makefile 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci l1_test $test 10562306a36Sopenharmony_ci l2_test $test 10662306a36Sopenharmony_ci l3_test $test 10762306a36Sopenharmony_ci l4_test $test 10862306a36Sopenharmony_ci l5_test $test 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci print_results $1 $2 11162306a36Sopenharmony_ci exit $? 11262306a36Sopenharmony_cifi 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci# Level 1: LDLIBS set static. 11562306a36Sopenharmony_ci# 11662306a36Sopenharmony_ci# Find all LDLIBS set statically for all executables built by a Makefile 11762306a36Sopenharmony_ci# and filter out VAR_LDLIBS to discard the following: 11862306a36Sopenharmony_ci# gpio/Makefile:LDLIBS += $(VAR_LDLIBS) 11962306a36Sopenharmony_ci# Append space at the end of the list to append more tests. 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_cil1_tests=$(grep -r --include=Makefile "^LDLIBS" | \ 12262306a36Sopenharmony_ci grep -v "$filter" | awk -F: '{print $1}' | uniq) 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci# Level 2: LDLIBS set dynamically. 12562306a36Sopenharmony_ci# 12662306a36Sopenharmony_ci# Level 2 12762306a36Sopenharmony_ci# Some tests have multiple valid LDLIBS lines for individual sub-tests 12862306a36Sopenharmony_ci# that need dependency checks. Find them and append them to the tests 12962306a36Sopenharmony_ci# e.g: mm/Makefile:$(OUTPUT)/userfaultfd: LDLIBS += -lpthread 13062306a36Sopenharmony_ci# Filter out VAR_LDLIBS to discard the following: 13162306a36Sopenharmony_ci# memfd/Makefile:$(OUTPUT)/fuse_mnt: LDLIBS += $(VAR_LDLIBS) 13262306a36Sopenharmony_ci# Append space at the end of the list to append more tests. 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_cil2_tests=$(grep -r --include=Makefile ": LDLIBS" | \ 13562306a36Sopenharmony_ci grep -v "$filter" | awk -F: '{print $1}' | uniq) 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci# Level 3 13862306a36Sopenharmony_ci# memfd and others use pkg-config to find mount and fuse libs 13962306a36Sopenharmony_ci# respectively and save it in VAR_LDLIBS. If pkg-config doesn't find 14062306a36Sopenharmony_ci# any, VAR_LDLIBS set to default. 14162306a36Sopenharmony_ci# Use the default value and filter out pkg-config for dependency check. 14262306a36Sopenharmony_ci# e.g: 14362306a36Sopenharmony_ci# memfd/Makefile 14462306a36Sopenharmony_ci# VAR_LDLIBS := $(shell pkg-config fuse --libs 2>/dev/null) 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_cil3_tests=$(grep -r --include=Makefile "^VAR_LDLIBS" | \ 14762306a36Sopenharmony_ci grep -v "pkg-config\|PKG_CONFIG" | awk -F: '{print $1}' | uniq) 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci# Level 4 15062306a36Sopenharmony_ci# some tests may fall back to default using `|| echo -l<libname>` 15162306a36Sopenharmony_ci# if pkg-config doesn't find the libs, instead of using VAR_LDLIBS 15262306a36Sopenharmony_ci# as per level 3 checks. 15362306a36Sopenharmony_ci# e.g: 15462306a36Sopenharmony_ci# netfilter/Makefile 15562306a36Sopenharmony_ci# LDLIBS += $(shell $(HOSTPKG_CONFIG) --libs libmnl 2>/dev/null || echo -lmnl) 15662306a36Sopenharmony_cil4_tests=$(grep -r --include=Makefile "^LDLIBS" | \ 15762306a36Sopenharmony_ci grep "pkg-config\|PKG_CONFIG" | awk -F: '{print $1}' | uniq) 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci# Level 5 16062306a36Sopenharmony_ci# some tests may use IOURING_EXTRA_LIBS to add extra libs to LDLIBS, 16162306a36Sopenharmony_ci# which in turn may be defined in a sub-Makefile 16262306a36Sopenharmony_ci# e.g.: 16362306a36Sopenharmony_ci# mm/Makefile 16462306a36Sopenharmony_ci# $(OUTPUT)/gup_longterm: LDLIBS += $(IOURING_EXTRA_LIBS) 16562306a36Sopenharmony_cil5_tests=$(grep -r --include=Makefile "LDLIBS +=.*\$(IOURING_EXTRA_LIBS)" | \ 16662306a36Sopenharmony_ci awk -F: '{print $1}' | uniq) 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci#echo l1_tests $l1_tests 16962306a36Sopenharmony_ci#echo l2_tests $l2_tests 17062306a36Sopenharmony_ci#echo l3_tests $l3_tests 17162306a36Sopenharmony_ci#echo l4_tests $l4_tests 17262306a36Sopenharmony_ci#echo l5_tests $l5_tests 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ciall_tests 17562306a36Sopenharmony_ciprint_results $1 $2 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ciexit $? 17862306a36Sopenharmony_ci} 17962306a36Sopenharmony_ci# end main() 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ciall_tests() 18262306a36Sopenharmony_ci{ 18362306a36Sopenharmony_ci for test in $l1_tests; do 18462306a36Sopenharmony_ci l1_test $test 18562306a36Sopenharmony_ci done 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci for test in $l2_tests; do 18862306a36Sopenharmony_ci l2_test $test 18962306a36Sopenharmony_ci done 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci for test in $l3_tests; do 19262306a36Sopenharmony_ci l3_test $test 19362306a36Sopenharmony_ci done 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci for test in $l4_tests; do 19662306a36Sopenharmony_ci l4_test $test 19762306a36Sopenharmony_ci done 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci for test in $l5_tests; do 20062306a36Sopenharmony_ci l5_test $test 20162306a36Sopenharmony_ci done 20262306a36Sopenharmony_ci} 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci# Use same parsing used for l1_tests and pick libraries this time. 20562306a36Sopenharmony_cil1_test() 20662306a36Sopenharmony_ci{ 20762306a36Sopenharmony_ci test_libs=$(grep --include=Makefile "^LDLIBS" $test | \ 20862306a36Sopenharmony_ci grep -v "$filter" | \ 20962306a36Sopenharmony_ci sed -e 's/\:/ /' | \ 21062306a36Sopenharmony_ci sed -e 's/+/ /' | cut -d "=" -f 2) 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci check_libs $test $test_libs 21362306a36Sopenharmony_ci} 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci# Use same parsing used for l2_tests and pick libraries this time. 21662306a36Sopenharmony_cil2_test() 21762306a36Sopenharmony_ci{ 21862306a36Sopenharmony_ci test_libs=$(grep --include=Makefile ": LDLIBS" $test | \ 21962306a36Sopenharmony_ci grep -v "$filter" | \ 22062306a36Sopenharmony_ci sed -e 's/\:/ /' | sed -e 's/+/ /' | \ 22162306a36Sopenharmony_ci cut -d "=" -f 2) 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci check_libs $test $test_libs 22462306a36Sopenharmony_ci} 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_cil3_test() 22762306a36Sopenharmony_ci{ 22862306a36Sopenharmony_ci test_libs=$(grep --include=Makefile "^VAR_LDLIBS" $test | \ 22962306a36Sopenharmony_ci grep -v "pkg-config" | sed -e 's/\:/ /' | 23062306a36Sopenharmony_ci sed -e 's/+/ /' | cut -d "=" -f 2) 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci check_libs $test $test_libs 23362306a36Sopenharmony_ci} 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_cil4_test() 23662306a36Sopenharmony_ci{ 23762306a36Sopenharmony_ci test_libs=$(grep --include=Makefile "^VAR_LDLIBS\|^LDLIBS" $test | \ 23862306a36Sopenharmony_ci grep "\(pkg-config\|PKG_CONFIG\).*|| echo " | \ 23962306a36Sopenharmony_ci sed -e 's/.*|| echo //' | sed -e 's/)$//') 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci check_libs $test $test_libs 24262306a36Sopenharmony_ci} 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_cil5_test() 24562306a36Sopenharmony_ci{ 24662306a36Sopenharmony_ci tests=$(find $(dirname "$test") -type f -name "*.mk") 24762306a36Sopenharmony_ci test_libs=$(grep "^IOURING_EXTRA_LIBS +\?=" $tests | \ 24862306a36Sopenharmony_ci cut -d "=" -f 2) 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci check_libs $test $test_libs 25162306a36Sopenharmony_ci} 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_cicheck_libs() 25462306a36Sopenharmony_ci{ 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ciif [[ ! -z "${test_libs// }" ]] 25762306a36Sopenharmony_cithen 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci #echo $test_libs 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci for lib in $test_libs; do 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci let total_cnt+=1 26462306a36Sopenharmony_ci $CC -o $tmp_file.bin $lib $tmp_file > /dev/null 2>&1 26562306a36Sopenharmony_ci if [ $? -ne 0 ]; then 26662306a36Sopenharmony_ci echo "FAIL: $test dependency check: $lib" >> $fail 26762306a36Sopenharmony_ci let fail_cnt+=1 26862306a36Sopenharmony_ci fail_libs+="$lib " 26962306a36Sopenharmony_ci fail_target=$(echo "$test" | cut -d "/" -f1) 27062306a36Sopenharmony_ci fail_trgts+="$fail_target " 27162306a36Sopenharmony_ci targets=$(echo "$targets" | grep -v "$fail_target") 27262306a36Sopenharmony_ci else 27362306a36Sopenharmony_ci echo "PASS: $test dependency check passed $lib" >> $pass 27462306a36Sopenharmony_ci let pass_cnt+=1 27562306a36Sopenharmony_ci pass_libs+="$lib " 27662306a36Sopenharmony_ci pass_trgts+="$(echo "$test" | cut -d "/" -f1) " 27762306a36Sopenharmony_ci fi 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci done 28062306a36Sopenharmony_cifi 28162306a36Sopenharmony_ci} 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ciprint_results() 28462306a36Sopenharmony_ci{ 28562306a36Sopenharmony_ci echo -e "========================================================"; 28662306a36Sopenharmony_ci echo -e "Kselftest Dependency Check for [$0 $1 $2] results..." 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci if [ $print_targets -ne 0 ] 28962306a36Sopenharmony_ci then 29062306a36Sopenharmony_ci echo -e "Suggested Selftest Targets for your configuration:" 29162306a36Sopenharmony_ci echo -e "$targets"; 29262306a36Sopenharmony_ci fi 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci echo -e "========================================================"; 29562306a36Sopenharmony_ci echo -e "Checked tests defining LDLIBS dependencies" 29662306a36Sopenharmony_ci echo -e "--------------------------------------------------------"; 29762306a36Sopenharmony_ci echo -e "Total tests with Dependencies:" 29862306a36Sopenharmony_ci echo -e "$total_cnt Pass: $pass_cnt Fail: $fail_cnt"; 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci if [ $pass_cnt -ne 0 ]; then 30162306a36Sopenharmony_ci echo -e "--------------------------------------------------------"; 30262306a36Sopenharmony_ci cat $pass 30362306a36Sopenharmony_ci echo -e "--------------------------------------------------------"; 30462306a36Sopenharmony_ci echo -e "Targets passed build dependency check on system:" 30562306a36Sopenharmony_ci echo -e "$(echo "$pass_trgts" | xargs -n1 | sort -u | xargs)" 30662306a36Sopenharmony_ci fi 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci if [ $fail_cnt -ne 0 ]; then 30962306a36Sopenharmony_ci echo -e "--------------------------------------------------------"; 31062306a36Sopenharmony_ci cat $fail 31162306a36Sopenharmony_ci echo -e "--------------------------------------------------------"; 31262306a36Sopenharmony_ci echo -e "Targets failed build dependency check on system:" 31362306a36Sopenharmony_ci echo -e "$(echo "$fail_trgts" | xargs -n1 | sort -u | xargs)" 31462306a36Sopenharmony_ci echo -e "--------------------------------------------------------"; 31562306a36Sopenharmony_ci echo -e "Missing libraries system" 31662306a36Sopenharmony_ci echo -e "$(echo "$fail_libs" | xargs -n1 | sort -u | xargs)" 31762306a36Sopenharmony_ci fi 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci echo -e "--------------------------------------------------------"; 32062306a36Sopenharmony_ci echo -e "========================================================"; 32162306a36Sopenharmony_ci} 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_cimain "$@" 324