brintos

brintos / linux-shallow public Read only

0
0
Text · 8.0 KiB · 487e49f Raw
325 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.03# kselftest_deps.sh4#5# Checks for kselftest build dependencies on the build system.6# Copyright (c) 2020 Shuah Khan <skhan@linuxfoundation.org>7#8#9 10usage()11{12 13echo -e "Usage: $0 -[p] <compiler> [test_name]\n"14echo -e "\tkselftest_deps.sh [-p] gcc"15echo -e "\tkselftest_deps.sh [-p] gcc mm"16echo -e "\tkselftest_deps.sh [-p] aarch64-linux-gnu-gcc"17echo -e "\tkselftest_deps.sh [-p] aarch64-linux-gnu-gcc mm\n"18echo "- Should be run in selftests directory in the kernel repo."19echo "- Checks if Kselftests can be built/cross-built on a system."20echo "- Parses all test/sub-test Makefile to find library dependencies."21echo "- Runs compile test on a trivial C file with LDLIBS specified"22echo "  in the test Makefiles to identify missing library dependencies."23echo "- Prints suggested target list for a system filtering out tests"24echo "  failed the build dependency check from the TARGETS in Selftests"25echo "  main Makefile when optional -p is specified."26echo "- Prints pass/fail dependency check for each tests/sub-test."27echo "- Prints pass/fail targets and libraries."28echo "- Default: runs dependency checks on all tests."29echo "- Optional: test name can be specified to check dependencies for it."30exit 131 32}33 34# Start main()35main()36{37 38base_dir=`pwd`39# Make sure we're in the selftests top-level directory.40if [ $(basename "$base_dir") !=  "selftests" ]; then41	echo -e "\tPlease run $0 in"42	echo -e "\ttools/testing/selftests directory ..."43	exit 144fi45 46print_targets=047 48while getopts "p" arg; do49	case $arg in50		p)51		print_targets=152	shift;;53	esac54done55 56if [ $# -eq 0 ]57then58	usage59fi60 61# Compiler62CC=$163 64tmp_file=$(mktemp).c65trap "rm -f $tmp_file.o $tmp_file $tmp_file.bin" EXIT66#echo $tmp_file67 68pass=$(mktemp).out69trap "rm -f $pass" EXIT70#echo $pass71 72fail=$(mktemp).out73trap "rm -f $fail" EXIT74#echo $fail75 76# Generate tmp source fire for compile test77cat << "EOF" > $tmp_file78int main()79{80}81EOF82 83# Save results84total_cnt=085fail_trgts=()86fail_libs=()87fail_cnt=088pass_trgts=()89pass_libs=()90pass_cnt=091 92# Get all TARGETS from selftests Makefile93targets=$(grep -E "^TARGETS +|^TARGETS =" Makefile | cut -d "=" -f2)94 95# Initially, in LDLIBS related lines, the dep checker needs96# to ignore lines containing the following strings:97filter="\$(VAR_LDLIBS)\|pkg-config\|PKG_CONFIG\|IOURING_EXTRA_LIBS"98 99# Single test case100if [ $# -eq 2 ]101then102	test=$2/Makefile103 104	l1_test $test105	l2_test $test106	l3_test $test107	l4_test $test108	l5_test $test109 110	print_results $1 $2111	exit $?112fi113 114# Level 1: LDLIBS set static.115#116# Find all LDLIBS set statically for all executables built by a Makefile117# and filter out VAR_LDLIBS to discard the following:118# 	gpio/Makefile:LDLIBS += $(VAR_LDLIBS)119# Append space at the end of the list to append more tests.120 121l1_tests=$(grep -r --include=Makefile "^LDLIBS" | \122		grep -v "$filter" | awk -F: '{print $1}' | uniq)123 124# Level 2: LDLIBS set dynamically.125#126# Level 2127# Some tests have multiple valid LDLIBS lines for individual sub-tests128# that need dependency checks. Find them and append them to the tests129# e.g: mm/Makefile:$(OUTPUT)/userfaultfd: LDLIBS += -lpthread130# Filter out VAR_LDLIBS to discard the following:131# 	memfd/Makefile:$(OUTPUT)/fuse_mnt: LDLIBS += $(VAR_LDLIBS)132# Append space at the end of the list to append more tests.133 134l2_tests=$(grep -r --include=Makefile ": LDLIBS" | \135		grep -v "$filter" | awk -F: '{print $1}' | uniq)136 137# Level 3138# memfd and others use pkg-config to find mount and fuse libs139# respectively and save it in VAR_LDLIBS. If pkg-config doesn't find140# any, VAR_LDLIBS set to default.141# Use the default value and filter out pkg-config for dependency check.142# e.g:143# memfd/Makefile144#	VAR_LDLIBS := $(shell pkg-config fuse --libs 2>/dev/null)145 146l3_tests=$(grep -r --include=Makefile "^VAR_LDLIBS" | \147		grep -v "pkg-config\|PKG_CONFIG" | awk -F: '{print $1}' | uniq)148 149# Level 4150# some tests may fall back to default using `|| echo -l<libname>`151# if pkg-config doesn't find the libs, instead of using VAR_LDLIBS152# as per level 3 checks.153# e.g:154# netfilter/Makefile155#	LDLIBS += $(shell $(HOSTPKG_CONFIG) --libs libmnl 2>/dev/null || echo -lmnl)156l4_tests=$(grep -r --include=Makefile "^LDLIBS" | \157		grep "pkg-config\|PKG_CONFIG" | awk -F: '{print $1}' | uniq)158 159# Level 5160# some tests may use IOURING_EXTRA_LIBS to add extra libs to LDLIBS,161# which in turn may be defined in a sub-Makefile162# e.g.:163# mm/Makefile164#	$(OUTPUT)/gup_longterm: LDLIBS += $(IOURING_EXTRA_LIBS)165l5_tests=$(grep -r --include=Makefile "LDLIBS +=.*\$(IOURING_EXTRA_LIBS)" | \166	awk -F: '{print $1}' | uniq)167 168#echo l1_tests $l1_tests169#echo l2_tests $l2_tests170#echo l3_tests $l3_tests171#echo l4_tests $l4_tests172#echo l5_tests $l5_tests173 174all_tests175print_results $1 $2176 177exit $?178}179# end main()180 181all_tests()182{183	for test in $l1_tests; do184		l1_test $test185	done186 187	for test in $l2_tests; do188		l2_test $test189	done190 191	for test in $l3_tests; do192		l3_test $test193	done194 195	for test in $l4_tests; do196		l4_test $test197	done198 199	for test in $l5_tests; do200		l5_test $test201	done202}203 204# Use same parsing used for l1_tests and pick libraries this time.205l1_test()206{207	test_libs=$(grep --include=Makefile "^LDLIBS" $test | \208			grep -v "$filter" | \209			sed -e 's/\:/ /' | \210			sed -e 's/+/ /' | cut -d "=" -f 2)211 212	check_libs $test $test_libs213}214 215# Use same parsing used for l2_tests and pick libraries this time.216l2_test()217{218	test_libs=$(grep --include=Makefile ": LDLIBS" $test | \219			grep -v "$filter" | \220			sed -e 's/\:/ /' | sed -e 's/+/ /' | \221			cut -d "=" -f 2)222 223	check_libs $test $test_libs224}225 226l3_test()227{228	test_libs=$(grep --include=Makefile "^VAR_LDLIBS" $test | \229			grep -v "pkg-config" | sed -e 's/\:/ /' |230			sed -e 's/+/ /' | cut -d "=" -f 2)231 232	check_libs $test $test_libs233}234 235l4_test()236{237	test_libs=$(grep --include=Makefile "^VAR_LDLIBS\|^LDLIBS" $test | \238			grep "\(pkg-config\|PKG_CONFIG\).*|| echo " | \239			sed -e 's/.*|| echo //' | sed -e 's/)$//')240 241	check_libs $test $test_libs242}243 244l5_test()245{246	tests=$(find $(dirname "$test") -type f -name "*.mk")247	[[ -z "${tests// }" ]] && return248	test_libs=$(grep "^IOURING_EXTRA_LIBS +\?=" $tests | \249			cut -d "=" -f 2)250 251	check_libs $test $test_libs252}253 254check_libs()255{256 257if [[ ! -z "${test_libs// }" ]]258then259 260	#echo $test_libs261 262	for lib in $test_libs; do263 264	let total_cnt+=1265	$CC -o $tmp_file.bin $lib $tmp_file > /dev/null 2>&1266	if [ $? -ne 0 ]; then267		echo "FAIL: $test dependency check: $lib" >> $fail268		let fail_cnt+=1269		fail_libs+="$lib "270		fail_target=$(echo "$test" | cut -d "/" -f1)271		fail_trgts+="$fail_target "272		targets=$(echo "$targets" | grep -v "$fail_target")273	else274		echo "PASS: $test dependency check passed $lib" >> $pass275		let pass_cnt+=1276		pass_libs+="$lib "277		pass_trgts+="$(echo "$test" | cut -d "/" -f1) "278	fi279 280	done281fi282}283 284print_results()285{286	echo -e "========================================================";287	echo -e "Kselftest Dependency Check for [$0 $1 $2] results..."288 289	if [ $print_targets -ne 0 ]290	then291	echo -e "Suggested Selftest Targets for your configuration:"292	echo -e "$targets";293	fi294 295	echo -e "========================================================";296	echo -e "Checked tests defining LDLIBS dependencies"297	echo -e "--------------------------------------------------------";298	echo -e "Total tests with Dependencies:"299	echo -e "$total_cnt Pass: $pass_cnt Fail: $fail_cnt";300 301	if [ $pass_cnt -ne 0 ]; then302	echo -e "--------------------------------------------------------";303	cat $pass304	echo -e "--------------------------------------------------------";305	echo -e "Targets passed build dependency check on system:"306	echo -e "$(echo "$pass_trgts" | xargs -n1 | sort -u | xargs)"307	fi308 309	if [ $fail_cnt -ne 0 ]; then310	echo -e "--------------------------------------------------------";311	cat $fail312	echo -e "--------------------------------------------------------";313	echo -e "Targets failed build dependency check on system:"314	echo -e "$(echo "$fail_trgts" | xargs -n1 | sort -u | xargs)"315	echo -e "--------------------------------------------------------";316	echo -e "Missing libraries system"317	echo -e "$(echo "$fail_libs" | xargs -n1 | sort -u | xargs)"318	fi319 320	echo -e "--------------------------------------------------------";321	echo -e "========================================================";322}323 324main "$@"325