#!/bin/bash set -e clear cd "$(dirname "$0")" compiler="gcc" if [ -e compiler ]; then compiler=$(cat compiler) echo "compiling with $compiler" fi printHelpExit() { echo "$0 clean | remove build results" echo "$0 build | build everything" echo "$0 install | move build results into the install folder" echo "$0 test | run the tests" echo "$0 valgrind | run the tests with valgrind" echo "$0 coverage | generate code coverage" echo "$0 performance | run the performance tests" echo "$0 stats | run the performance tests with stats" echo "$0 macro | find macros without CORE" echo "$0 time | check build time" exit 0 } task=$1 if [ -z "$task" ]; then printHelpExit fi # task vars build_debug=false build_profile=false build_release=false test_debug=false test_release=false valgrind="" performance=false time=false install=false coverage=false stats=false export CMAKE_EXPORT_COMPILE_COMMANDS=true cleanFolders() { rm -rf build_debug build_profile build_release install } # parsing if [ "$task" = "clean" ]; then cleanFolders elif [ "$task" = "build" ]; then type=$2 if [ "$type" = "debug" ]; then build_debug=true elif [ "$type" = "release" ]; then build_release=true elif [ "$type" = "all" ]; then build_debug=true build_release=true else echo "Valid build types are: debug, release, all" printHelpExit fi elif [ "$task" = "install" ]; then build_release=true install=true elif [ "$task" = "coverage" ]; then build_debug=true test_debug=true coverage=true elif [ "$task" = "test" ]; then type=$2 if [ "$type" = "debug" ]; then build_debug=true test_debug=true elif [ "$type" = "release" ]; then build_release=true test_release=true elif [ "$type" = "all" ]; then build_debug=true test_debug=true build_release=true test_release=true else echo "Valid test types are: debug, release, all" printHelpExit fi elif [ "$task" = "valgrind" ]; then type=$2 if [ "$type" = "debug" ]; then build_debug=true test_debug=true elif [ "$type" = "release" ]; then build_release=true test_release=true elif [ "$type" = "all" ]; then build_debug=true test_debug=true build_release=true test_release=true else echo "Valid valgrind types are: debug, release, all" printHelpExit fi valgrind="valgrind --leak-check=full --show-leak-kinds=all" elif [ "$task" = "performance" ]; then build_profile=true performance=true elif [ "$task" = "stats" ]; then build_profile=true performance=true stats=true elif [ "$task" = "time" ]; then build_release=true time=true elif [ "$task" = "macro" ]; then grep -r "#define" src include | grep -v " CORE" || true exit 0 else echo "unknown task" printHelpExit fi # task execution buildProfile() { folder=$1 shift 1 if [ -e "$folder" ]; then if ! cat $folder/CMakeCache.txt | grep "CMAKE_C_COMPILER:" | grep $compiler > /dev/null; then cleanFolders fi fi if [ ! -e "$folder" ]; then cmake -B "$folder" -S . -G Ninja -DCMAKE_C_COMPILER="${compiler}" -DCMAKE_INSTALL_PREFIX=../install "$@" fi ninja -C "$folder" } if $build_debug; then buildProfile build_debug -DCMAKE_BUILD_TYPE=Debug fi if $build_profile; then buildProfile build_profile -DCMAKE_BUILD_TYPE=RelWithDebInfo fi if $build_release; then buildProfile build_release -DCMAKE_BUILD_TYPE=Release fi if $install; then ninja -C build_release install fi function runTests() { echo "--------------Invalid alloc exit----------------" LLVM_PROFILE_FILE="alloc.profraw" ./test alloc || true echo "--------------Invalid realloc exit--------------" LLVM_PROFILE_FILE="realloc.profraw" ./test realloc || true echo "--------------Pre canary detection--------------" LLVM_PROFILE_FILE="pre_canary.profraw" ./test pre_canary || true echo "--------------Post canary detection-------------" LLVM_PROFILE_FILE="post_canary.profraw" ./test post_canary || true # Test Fails LLVM_PROFILE_FILE="test.profraw" ./test test > /dev/null || true echo "--------------Default run-----------------------" LLVM_PROFILE_FILE="default.profraw" $valgrind ./test light $valgrind < ../readLineTest || true } if $test_debug; then cd build_debug runTests cd .. fi if $test_release; then cd build_release runTests cd .. fi if $performance; then cd build_profile if $stats; then user=$(whoami) sudo perf record ./performance sudo chown "$user:$user" perf.data sudo chown "$user:$user" default.profraw perf report else ./performance fi cd .. fi if $time; then lines=$(grep "^[0-9]" "build_release/.ninja_log") startMillis=0 endMillis=0 name="" i=0 output="" for arg in $lines; do if [ $i == 0 ]; then startMillis=$arg elif [ $i == 1 ]; then endMillis=$arg elif [ $i == 3 ]; then name=$arg diff=$((endMillis - startMillis)) output="${output}\n$diff $name" fi i=$(($((i + 1)) % 5)) done echo -e "$output" | sort -n fi generateCoverageFunctions() { #allowlist_fun:.* ignore=$(cat ./ignoredCoverageFunctions) list=$(nm ./build_debug/libcore.a -j | grep "^[a-zA-Z]") for file in $ignore; do list=$(echo "$list" | grep -v "$file") done echo "$list" | sed 's/^/allowlist_fun:/g' > build_debug/coverageFunctions } if $coverage; then if [ "$compiler" = "gcc" ]; then gcovr -r . build_debug -e test -e performance \ --exclude-lines-by-pattern ".*CoverageIgnore.*" else mapfile -t files < <(find build_debug -name "*.profraw") llvm-profdata-17 merge -sparse "${files[@]}" -o build_debug/default.profdata generateCoverageFunctions llvm-cov-17 show ./build_debug/test -instr-profile=build_debug/default.profdata --ignore-filename-regex="test/" -line-coverage-lt=100 --name-allowlist=build_debug/coverageFunctions fi fi