1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
#!/bin/bash
# This script allows to automatically build and test AspectC++ with multiple clang versions. It produces a compact
# report about AspectC++'s status in terms of supported clang versions.
### Optional arguments ###
# $1 clang_version_array (see below)
# $2 clang_dir_path_prefix (see below)
# $3 build target, i.e., make's TARGET argument
if [ $# -gt 3 ]
then
echo "Error: Max. 3 arguments allowed."
exit 1
fi
### Config ###
# Array of version strings. For each string, the corresponding clang version is used for testing AspectC++. Pre-built
# binaries/libraries can be downloaded from http://releases.llvm.org/download.html.
clang_version_array=${1:-"9.0.0 6.0.1 5.0.2 4.0.1 3.9.1 3.8.1 3.7.1 3.6.2 3.5.2"}
# Path to directory containing clang binary/library directories plus the prefix of all clang binary/library directory
# names.
# When concatenated with a version from the version array, it must result in a path to the root of a clang
# binary/library directory. From that path, "./bin/llvm-config" should point to llvm-config binary.
# For example, extract all downloaded pre-built binary/library files to your home and rename each extracted root
# directory to llvm-<version>. In this case, clang_dir_path_prefix should be "$HOME/llvm-"
# Note: Please provide absolute paths. Tilde (~) is not supported.
clang_dir_path_prefix=${2:-"$HOME/llvm-"}
# Number of cpus to use for building:
cpu_count_to_use=$(grep -c ^processor /proc/cpuinfo)
# AspectC++ build command without LLVMCONF argument:
build_target=${3:-"linux-debug"}
acpp_base_build_command="make SHARED=1 TARGET=$build_target -j$cpu_count_to_use FRONTEND=Clang"
### End of config ######################################################################################################
########################################################################################################################
run_command() {
# $1 = command description
# $2 = command to run
# $3 = whether to continue on non-zero exit code (1) or not (0)
echo -e "\n------------------------------\n$1 ($2) ..."
# Run command:
# Since we run two piped commands below, force bash to set the exit status $? to a non-zero exit code if any of the
# commands fail:
set -o pipefail
# Direct command output to stdout/stderr while additionally storing stdout in the variable:
exec 9>&1 # Duplicates &1 to 9 (9 is a mostly arbitrary chosen number)
output=$($2 | tee >(cat - >&9))
# Store the last exit code:
exit_code=$?
if [ $exit_code -ne 0 ]
then
echo "Error: $1 failed with exit code $exit_code."
if [ -n "$3" ] && [ "$3" -eq 1 ] # if $3 is not empty ("-n" ^= "! -z") and equals 1
then
echo "... but continuing anyway."
else
exit $exit_code
fi
else
echo "Done."
fi
}
# If PUMA_CONFIG is not set and a default config from aspectc++ package is available, set PUMA_CONFIG to the default:
if [ -z "$PUMA_CONFIG" ] && [ -f "/etc/puma.config" ]
then
export PUMA_CONFIG="/etc/puma.config"
echo "Set PUMA_CONFIG to default config $PUMA_CONFIG."
fi
# Show a warning if tests are likely to fail:
if [ -z "$PUMA_CONFIG" ]
then
echo "----------------------------------------------------------------"
echo "WARNING: Neither /etc/puma.config exists nor PUMA_CONFIG is set."
echo " This may lead to failing tests due to failing includes."
echo " See README for more information."
echo "----------------------------------------------------------------"
sleep 2
fi
echo -e "Testing AspectC++ with clang versions $clang_version_array ..."
for clang_version in $clang_version_array
do
echo -e "\n------------------------------\n| AspectC++ with Clang $clang_version |\n------------------------------"
# In each loop, try to build and test with the current clang version. In all cases, clang_version_result_string
# contains either the test results or a message explaining why the build failed.
# Construct llvm-config path:
llvm_conf_path="${clang_dir_path_prefix}$clang_version/bin/llvm-config"
if [ ! -f "$llvm_conf_path" ]
then
echo "Error: Could not find Clang $clang_version llvm-config binary in $llvm_conf_path. Please check your clang directory paths and the config on top of this file. Skipping tests ..."
clang_version_result_string="Unable to build AspectC++: $llvm_conf_path does not exist."
else
# clang/llvm binaries/libraries are available. Construct build, clean and test commands:
acpp_build_command="$acpp_base_build_command LLVMCONF=$llvm_conf_path"
acpp_clean_command="$acpp_build_command clean"
acpp_testall_command="$acpp_build_command testall"
# Try building AspectC++:
run_command "Cleaning with Clang $clang_version" "$acpp_clean_command"
run_command "Building with Clang $clang_version" "$acpp_build_command" "1" # do not exit script on non-zero exit code
if [ $exit_code -ne 0 ]
then
clang_version_result_string="Unable to build AspectC++: Build command exited with non-zero exit code $exit_code."
else
# Build was successful: Run the tests:
run_command "Running tests with Clang $clang_version" "$acpp_testall_command" "1"
# Extract the test result summary line:
clang_version_result_string=$(echo "$output" | sed -n 2p) # second line of test output only
fi
fi
# Construct a string holding all clang versions' test result summaries:
overall_test_results="$overall_test_results\n$clang_version: $clang_version_result_string"
echo -e "\nTest results so far:$overall_test_results"
done
echo -e "\nOverall test results:$overall_test_results"
|