#!/bin/bash
# Copyright (C) 2016 Franz Flasch <franz.flasch@gmx.at>
# This file is part of REM - Rake for EMbedded Systems and Microcontrollers.
# REM is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version.
# REM is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details.
# You should have received a copy of the GNU General Public License # along with REM. If not, see <www.gnu.org/licenses/>.
# This script will perform the following tests: # At first a recursive “compile test” build with the complete package dependency chain will be done. # In each round one specific dependency will be disabled and checked if the build is still successful. # If one build is successful, the disabled dependency comes to the list of “suspicious” packages. # # The second part is the link test. # As it cannot be guaranteed that every package on the “suspicous” compile test list is 100% a wrong dependency setting # an additional link test will be done. # # Consider the following scenario: # The compile test could expose that the dependency ATMEGA168 from the package heatingctrl is suspocious. # However this does not mean, that the dependency setup is wrong! If there are generic headers used with different implementations, # then this cannot be detected by the compile test alone! # In this case the script checks if more packages with the same dependency exists and are “suspicious” # If all packages with the suspicous dependency are in the “suspicious” list then they are considered for doing a link test. # The link test will start linking without the given packages which were chosen before for doing this test. If one link build succeeds # without the given dependency then the probability for a wrong dependency setup is plausible and they also come to the link dependency list. # If some packages are contained in both lists, then these packages can be considered as nearly 100% wrong configured! # # If one package (from the complete dependency chain) with the given suspicous dependency is not in the “suspicious” compiletest list, # then this would mean, that at least one compilation failed, and therefore the dependency setting for this one package is correct, # it also means that it is not necessary to do a link test then, as this will fail for sure
if [ -z “$PACKAGE_NAME” ]; then
echo "PACKAGE_NAME not set!" exit 1
fi
# Do a normal build at first to check if everything is OK rem package:$PACKAGE_NAME:link if [ “$?” != 0 ]; then
echo "Not able to do a normal build! Check if you can build normally before doing a dependency test!" exit 2
fi
# Helper functions function add_to_array_if_not_contained() {
array_ref=$1 text_to_append=$2 eval "array=\${$array_ref[*]}" if [[ "${array[@]}" =~ "${text_to_append}" ]]; then echo "ARRAY ALREADY CONTAINS $text_to_append!" return else array+=("$text_to_append") fi eval "$array_ref+=($text_to_append)"
}
# Get the complete dependency of the package, the last sed command removes the color from the output DEPENDENCY_CHAIN=`rem package:$PACKAGE_NAME:depends_chain_print | awk '/DEPENDENCY-CHAIN:/{y=1;next}y' | awk '{print $1}' | sed 's/x1b[*m//g'`
COMPILE_TEST_RESULT=() DEP_LIST_ARRAY=()
# Now build each package from the dependencylist while removing a single dependency in each iteration # If one of the build iterations is successful, then there's probably something wrong in the dependency settings for pkg in $DEPENDENCY_CHAIN do
echo "" echo "Checking package $pkg" deps_for_package=`rem package:$pkg:depends_chain_print | grep "$pkg -->"` if [ "$?" != 0 ]; then echo "No deps for package $pkg! Continuing..." continue fi deps_for_package=`echo $deps_for_package | awk '{$1=$2="";$0=$0;$1=$1}1' | sed 's/\x1b\[[0-9;]*m//g'` echo "$pkg has the following dependencies: $deps_for_package" DEP_LIST_ARRAY+=("$pkg : $deps_for_package") for dep in $deps_for_package do echo "Trying to build $pkg without $dep" rem package:$pkg:clean[compile] rem package:$pkg:check_deps[$dep,"compile",$PACKAGE_NAME] if [ "$?" != 0 ]; then echo "Error when building $pkg without $dep" else echo "Build without $dep possible! Please check deps for package $pkg!!" COMPILE_TEST_RESULT+=("$pkg : $dep") fi done
done
# COMPILE_TEST_RESULT=() # COMPILE_TEST_RESULT+=(“heatingctrl : ATMEGA168”) # COMPILE_TEST_RESULT+=(“heatingctrl : crc”) # COMPILE_TEST_RESULT+=(“msglib : crc”) # COMPILE_TEST_RESULT+=(“soft_spi : spi_common”) # COMPILE_TEST_RESULT+=(“ATMEGA168 : spi_common”)
LINK_REMOVE_ARRAY=() CANDIDATE_DEP_COUNT_ARRAY=() for each in “${COMPILE_TEST_RESULT}” do
canditate=`echo $each | awk '{print $3}'` canditate_count=0 for each in "${COMPILE_TEST_RESULT[@]}" do canditate_tmp=`echo $each | awk '{print $3}'` if [ "$canditate" == "$canditate_tmp" ]; then canditate_count=$(( $canditate_count + 1)) fi done #echo "$canditate occurences in result: $canditate_count" dep_count=0 for each in "${DEP_LIST_ARRAY[@]}" do dep=`echo $each | awk '{print $1}'` if [ "$canditate" == "$dep" ]; then # ignore this package as it is the one we are currently checking continue fi dep_count=$(( $dep_count +`echo "$each" | grep -o "$canditate" | wc -l` )) done #echo "Count $canditate : $dep_count" if [ $canditate_count -eq $dep_count ]; then echo "$canditate has same occurences in dep_list as in the result list! Candidate for link test!" add_to_array_if_not_contained "LINK_REMOVE_ARRAY" "$canditate" add_to_array_if_not_contained "CANDIDATE_DEP_COUNT_ARRAY" "$canditate\ -\ occurences\ deplist:\ $dep_count,\ occurences\ compile\ testresult:\ $canditate_count" fi
done
# Do final link test here: LINK_TEST_RESULT=() for each in “${LINK_REMOVE_ARRAY}” do
rem package:$PACKAGE_NAME:clean["link"] rem package:$PACKAGE_NAME:check_deps[$each,"link",$PACKAGE_NAME] if [ "$?" != 0 ]; then echo "Error when linking $PACKAGE_NAME without $each" else echo "Linking without $each possible! Please check if $each is really necessary in your deps!" LINK_TEST_RESULT+=("$each") fi
done
echo “” echo “” echo “===============================================” echo “Dependency analysis results:” echo “===============================================” echo “” echo “The result of this script contains testresults of compiling and linking packages without specific dependencies.” echo “ - If the result of the compile test is empty, then the probability of a correct dependency setup is ~100%” echo “ - If the result of the compile test not empty, but the result of the link test is empty then the probability of a correct dependency setup is high but not 100%” echo “ in this case the results of the compile test should be checked for correctness” echo “ - If the compile test is not empty and also the link test is not empty, then the packages which are on both lists are practically 100% wrong” echo “ - If the compile test is empty but the link test is not, then there is something seriously wrong. This should not happen.” echo “” echo “Compile test result:” echo “suspicious packages:” if [ -n “$COMPILE_TEST_RESULT” ]; then
for each in "${COMPILE_TEST_RESULT[@]}" do echo "$each" done
else
echo "NONE"
fi
echo “” echo “” echo “Candidates chosen for link test:” if [ -n “$CANDIDATE_DEP_COUNT_ARRAY” ]; then
for each in "${CANDIDATE_DEP_COUNT_ARRAY[@]}" do echo "$each" done
else
echo "NONE"
fi
echo “” echo “Link test result:” echo “suspicious packages:” if [ -n “$LINK_TEST_RESULT” ]; then
for each in "${LINK_TEST_RESULT[@]}" do echo "$each" done
else
echo "NONE"
fi