Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/bash
0002 # SPDX-License-Identifier: GPL-2.0
0003 # kselftest_deps.sh
0004 #
0005 # Checks for kselftest build dependencies on the build system.
0006 # Copyright (c) 2020 Shuah Khan <skhan@linuxfoundation.org>
0007 #
0008 #
0009 
0010 usage()
0011 {
0012 
0013 echo -e "Usage: $0 -[p] <compiler> [test_name]\n"
0014 echo -e "\tkselftest_deps.sh [-p] gcc"
0015 echo -e "\tkselftest_deps.sh [-p] gcc vm"
0016 echo -e "\tkselftest_deps.sh [-p] aarch64-linux-gnu-gcc"
0017 echo -e "\tkselftest_deps.sh [-p] aarch64-linux-gnu-gcc vm\n"
0018 echo "- Should be run in selftests directory in the kernel repo."
0019 echo "- Checks if Kselftests can be built/cross-built on a system."
0020 echo "- Parses all test/sub-test Makefile to find library dependencies."
0021 echo "- Runs compile test on a trivial C file with LDLIBS specified"
0022 echo "  in the test Makefiles to identify missing library dependencies."
0023 echo "- Prints suggested target list for a system filtering out tests"
0024 echo "  failed the build dependency check from the TARGETS in Selftests"
0025 echo "  main Makefile when optional -p is specified."
0026 echo "- Prints pass/fail dependency check for each tests/sub-test."
0027 echo "- Prints pass/fail targets and libraries."
0028 echo "- Default: runs dependency checks on all tests."
0029 echo "- Optional: test name can be specified to check dependencies for it."
0030 exit 1
0031 
0032 }
0033 
0034 # Start main()
0035 main()
0036 {
0037 
0038 base_dir=`pwd`
0039 # Make sure we're in the selftests top-level directory.
0040 if [ $(basename "$base_dir") !=  "selftests" ]; then
0041         echo -e "\tPlease run $0 in"
0042         echo -e "\ttools/testing/selftests directory ..."
0043         exit 1
0044 fi
0045 
0046 print_targets=0
0047 
0048 while getopts "p" arg; do
0049     case $arg in
0050         p)
0051                 print_targets=1
0052         shift;;
0053     esac
0054 done
0055 
0056 if [ $# -eq 0 ]
0057 then
0058         usage
0059 fi
0060 
0061 # Compiler
0062 CC=$1
0063 
0064 tmp_file=$(mktemp).c
0065 trap "rm -f $tmp_file.o $tmp_file $tmp_file.bin" EXIT
0066 #echo $tmp_file
0067 
0068 pass=$(mktemp).out
0069 trap "rm -f $pass" EXIT
0070 #echo $pass
0071 
0072 fail=$(mktemp).out
0073 trap "rm -f $fail" EXIT
0074 #echo $fail
0075 
0076 # Generate tmp source fire for compile test
0077 cat << "EOF" > $tmp_file
0078 int main()
0079 {
0080 }
0081 EOF
0082 
0083 # Save results
0084 total_cnt=0
0085 fail_trgts=()
0086 fail_libs=()
0087 fail_cnt=0
0088 pass_trgts=()
0089 pass_libs=()
0090 pass_cnt=0
0091 
0092 # Get all TARGETS from selftests Makefile
0093 targets=$(egrep "^TARGETS +|^TARGETS =" Makefile | cut -d "=" -f2)
0094 
0095 # Single test case
0096 if [ $# -eq 2 ]
0097 then
0098         test=$2/Makefile
0099 
0100         l1_test $test
0101         l2_test $test
0102         l3_test $test
0103 
0104         print_results $1 $2
0105         exit $?
0106 fi
0107 
0108 # Level 1: LDLIBS set static.
0109 #
0110 # Find all LDLIBS set statically for all executables built by a Makefile
0111 # and filter out VAR_LDLIBS to discard the following:
0112 #       gpio/Makefile:LDLIBS += $(VAR_LDLIBS)
0113 # Append space at the end of the list to append more tests.
0114 
0115 l1_tests=$(grep -r --include=Makefile "^LDLIBS" | \
0116                 grep -v "VAR_LDLIBS" | awk -F: '{print $1}')
0117 
0118 # Level 2: LDLIBS set dynamically.
0119 #
0120 # Level 2
0121 # Some tests have multiple valid LDLIBS lines for individual sub-tests
0122 # that need dependency checks. Find them and append them to the tests
0123 # e.g: vm/Makefile:$(OUTPUT)/userfaultfd: LDLIBS += -lpthread
0124 # Filter out VAR_LDLIBS to discard the following:
0125 #       memfd/Makefile:$(OUTPUT)/fuse_mnt: LDLIBS += $(VAR_LDLIBS)
0126 # Append space at the end of the list to append more tests.
0127 
0128 l2_tests=$(grep -r --include=Makefile ": LDLIBS" | \
0129                 grep -v "VAR_LDLIBS" | awk -F: '{print $1}')
0130 
0131 # Level 3
0132 # memfd and others use pkg-config to find mount and fuse libs
0133 # respectively and save it in VAR_LDLIBS. If pkg-config doesn't find
0134 # any, VAR_LDLIBS set to default.
0135 # Use the default value and filter out pkg-config for dependency check.
0136 # e.g:
0137 # memfd/Makefile
0138 #       VAR_LDLIBS := $(shell pkg-config fuse --libs 2>/dev/null)
0139 
0140 l3_tests=$(grep -r --include=Makefile "^VAR_LDLIBS" | \
0141                 grep -v "pkg-config" | awk -F: '{print $1}')
0142 
0143 #echo $l1_tests
0144 #echo $l2_1_tests
0145 #echo $l3_tests
0146 
0147 all_tests
0148 print_results $1 $2
0149 
0150 exit $?
0151 }
0152 # end main()
0153 
0154 all_tests()
0155 {
0156         for test in $l1_tests; do
0157                 l1_test $test
0158         done
0159 
0160         for test in $l2_tests; do
0161                 l2_test $test
0162         done
0163 
0164         for test in $l3_tests; do
0165                 l3_test $test
0166         done
0167 }
0168 
0169 # Use same parsing used for l1_tests and pick libraries this time.
0170 l1_test()
0171 {
0172         test_libs=$(grep --include=Makefile "^LDLIBS" $test | \
0173                         grep -v "VAR_LDLIBS" | \
0174                         sed -e 's/\:/ /' | \
0175                         sed -e 's/+/ /' | cut -d "=" -f 2)
0176 
0177         check_libs $test $test_libs
0178 }
0179 
0180 # Use same parsing used for l2__tests and pick libraries this time.
0181 l2_test()
0182 {
0183         test_libs=$(grep --include=Makefile ": LDLIBS" $test | \
0184                         grep -v "VAR_LDLIBS" | \
0185                         sed -e 's/\:/ /' | sed -e 's/+/ /' | \
0186                         cut -d "=" -f 2)
0187 
0188         check_libs $test $test_libs
0189 }
0190 
0191 l3_test()
0192 {
0193         test_libs=$(grep --include=Makefile "^VAR_LDLIBS" $test | \
0194                         grep -v "pkg-config" | sed -e 's/\:/ /' |
0195                         sed -e 's/+/ /' | cut -d "=" -f 2)
0196 
0197         check_libs $test $test_libs
0198 }
0199 
0200 check_libs()
0201 {
0202 
0203 if [[ ! -z "${test_libs// }" ]]
0204 then
0205 
0206         #echo $test_libs
0207 
0208         for lib in $test_libs; do
0209 
0210         let total_cnt+=1
0211         $CC -o $tmp_file.bin $lib $tmp_file > /dev/null 2>&1
0212         if [ $? -ne 0 ]; then
0213                 echo "FAIL: $test dependency check: $lib" >> $fail
0214                 let fail_cnt+=1
0215                 fail_libs+="$lib "
0216                 fail_target=$(echo "$test" | cut -d "/" -f1)
0217                 fail_trgts+="$fail_target "
0218                 targets=$(echo "$targets" | grep -v "$fail_target")
0219         else
0220                 echo "PASS: $test dependency check passed $lib" >> $pass
0221                 let pass_cnt+=1
0222                 pass_libs+="$lib "
0223                 pass_trgts+="$(echo "$test" | cut -d "/" -f1) "
0224         fi
0225 
0226         done
0227 fi
0228 }
0229 
0230 print_results()
0231 {
0232         echo -e "========================================================";
0233         echo -e "Kselftest Dependency Check for [$0 $1 $2] results..."
0234 
0235         if [ $print_targets -ne 0 ]
0236         then
0237         echo -e "Suggested Selftest Targets for your configuration:"
0238         echo -e "$targets";
0239         fi
0240 
0241         echo -e "========================================================";
0242         echo -e "Checked tests defining LDLIBS dependencies"
0243         echo -e "--------------------------------------------------------";
0244         echo -e "Total tests with Dependencies:"
0245         echo -e "$total_cnt Pass: $pass_cnt Fail: $fail_cnt";
0246 
0247         if [ $pass_cnt -ne 0 ]; then
0248         echo -e "--------------------------------------------------------";
0249         cat $pass
0250         echo -e "--------------------------------------------------------";
0251         echo -e "Targets passed build dependency check on system:"
0252         echo -e "$(echo "$pass_trgts" | xargs -n1 | sort -u | xargs)"
0253         fi
0254 
0255         if [ $fail_cnt -ne 0 ]; then
0256         echo -e "--------------------------------------------------------";
0257         cat $fail
0258         echo -e "--------------------------------------------------------";
0259         echo -e "Targets failed build dependency check on system:"
0260         echo -e "$(echo "$fail_trgts" | xargs -n1 | sort -u | xargs)"
0261         echo -e "--------------------------------------------------------";
0262         echo -e "Missing libraries system"
0263         echo -e "$(echo "$fail_libs" | xargs -n1 | sort -u | xargs)"
0264         fi
0265 
0266         echo -e "--------------------------------------------------------";
0267         echo -e "========================================================";
0268 }
0269 
0270 main "$@"