#!/bin/sh BUILD_TYPE= USE_COMPILER= DESTINATION= EXTRA_OPTIONS= EXTRA_LINK_OPTIONS= SKIP_TESTS=0 while [ $# -gt 0 ]; do case $1 in -H|--help) echo "Build script for C projects" echo "" echo "Usage: ./build_and_test.sh [OPTIONS]" echo "" echo " -H --help - Print this info" echo " -t --type - Set build type: debug, release" echo " -c --compiler - Set compiler to use: gcc, clang, msvc, emcc" echo " -d --destination - Set destination path" echo " -o --options - Set additional options for the compiler" echo " -l --link - Set additional options for the linker" echo " -S --skip-tests - Skip tests" echo "" exit 0 ;; -t|--type) BUILD_TYPE=$2 shift shift ;; -c|--compiler) USE_COMPILER="$2" shift shift ;; -d|--destination) DESTINATION="$2" shift shift ;; -o|--options) EXTRA_OPTIONS="$2" shift shift ;; -l|--link) EXTRA_LINK_OPTIONS="$2" shift shift ;; -S|--skip-tests) SKIP_TESTS=1 shift ;; *) echo "Unknown option $1" shift ;; esac done FOLDER=out_gcc OS=Linux COMPILE=gcc COMPILEPP=g++ OBJ_POSTFIX=.o EXE_POSTFIX= FLAGS= FLAG_OBJ="-c -o " FLAG_EXE="-o " LINK_FLAGS= if [ "$USE_COMPILER" = "gcc" ]; then FOLDER=out_gcc COMPILE=gcc COMPILEPP=g++ elif [ "$USE_COMPILER" = "clang" ]; then FOLDER=out_clang COMPILE=clang COMPILEPP=clang++ elif [ "$USE_COMPILER" = "msvc" ]; then FOLDER=out_msvc COMPILE=cl.exe COMPILEPP=cl.exe OBJ_POSTFIX=.obj FLAG_OBJ="-c -Fo" FLAG_EXE="-Fe" elif [ "$USE_COMPILER" = "emcc" ]; then FOLDER=out_emcc COMPILE=emcc COMPILEPP=em++ EXE_POSTFIX=.js LINK_FLAGS="-sFULL_ES3=1" elif [ "$USE_COMPILER" != "" ]; then echo "Unknown C compiler" exit 1 fi if [ "$DESTINATION" != "" ]; then FOLDER="$DESTINATION" fi if [ "$USE_COMPILER" != "" ]; then if command -v $COMPILE >/dev/null 2>&1; then echo "C compiler found" else echo "C compiler not found" exit 1 fi fi if [ "$COMPILE" != "emcc" ]; then case $(uname | tr '[:upper:]' '[:lower:]') in *darwin*) OS=macOS if [ "$USE_COMPILER" = "" ]; then if command -v clang >/dev/null 2>&1; then echo "C compiler found - Clang" COMPILE=clang COMPILEPP=clang++ elif command -v gcc >/dev/null 2>&1; then echo "C compiler found - GCC" else echo "C compiler not found" exit 1 fi fi ;; *msys*|*cygwin*|*mingw*|*nt*|*win*) OS=Windows EXE_POSTFIX=.exe if [ "$USE_COMPILER" = "" ]; then if command -v cl.exe >/dev/null 2>&1; then echo "C compiler found - MSVC" COMPILE=cl.exe COMPILEPP=cl.exe OBJ_POSTFIX=.obj FLAG_OBJ="-c -Fo" FLAG_EXE="-Fe" elif command -v gcc >/dev/null 2>&1; then echo "C compiler found - GCC" elif command -v clang >/dev/null 2>&1; then echo "C compiler found - Clang" COMPILE=clang COMPILEPP=clang++ else echo "C compiler not found" exit 1 fi fi if [ "$COMPILE" = "cl.exe" ]; then LINK_FLAGS="Shlwapi.lib Advapi32.lib" else LINK_FLAGS="-lShlwapi -lAdvapi32" fi ;; *) if [ "$USE_COMPILER" = "" ]; then if command -v gcc >/dev/null 2>&1; then echo "C compiler found - GCC" elif command -v clang >/dev/null 2>&1; then echo "C compiler found - Clang" COMPILE=clang COMPILEPP=clang++ else echo "C compiler not found" exit 1 fi fi ;; esac fi if [ "$COMPILE" = "gcc" ] || [ "$COMPILE" = "emcc" ]; then if [ "$BUILD_TYPE" = "release" ]; then FLAGS="-O3 -DNDEBUG" elif [ "$COMPILE" = "gcc" ] && [ "$OS" != "Windows" ]; then FLAGS="-O0 -fsanitize=undefined,address,leak" elif [ "$OS" != "Windows" ] && [ "$COMPILE" != "emcc" ]; then FLAGS="-O0 -fsanitize=undefined,address" else FLAGS="-O0" fi elif [ "$COMPILE" = "clang" ]; then if [ "$BUILD_TYPE" = "release" ]; then FLAGS="-O3 -DNDEBUG" else FLAGS="-O0" fi else if [ "$BUILD_TYPE" = "release" ]; then FLAGS="-O2 -DNDEBUG" else FLAGS="-Od" fi fi if [ "$COMPILE" = "clang" ] || [ "$OS" = "macOS" ]; then FLAGS="-fblocks $FLAGS" LINK_FLAGS="-lBlocksRuntime $LINK_FLAGS" fi if [ "$EXTRA_OPTIONS" != "" ]; then FLAGS="$EXTRA_OPTIONS $FLAGS" fi if [ "$EXTRA_LINK_OPTIONS" != "" ]; then LINK_FLAGS="$EXTRA_LINK_OPTIONS $LINK_FLAGS" fi if [ ! -d "$FOLDER" ]; then mkdir "$FOLDER" fi echo "" echo "Compiler options: $FLAGS" echo "Link options: $LINK_FLAGS" echo "" echo "Build kit" $COMPILE $FLAGS \ ${FLAG_OBJ}"$FOLDER/kit$OBJ_POSTFIX" \ "source/kit/_lib.c" if [ $? -ne 0 ]; then exit 1 fi echo "Build test suite" $COMPILE $FLAGS \ $FLAG_EXE"$FOLDER/test_suite$EXE_POSTFIX" \ "$FOLDER/kit$OBJ_POSTFIX" \ "source/tests/_exe.c" \ $LINK_FLAGS if [ $? -ne 0 ]; then exit 1 fi $COMPILE $FLAGS \ $FLAG_EXE"$FOLDER/test_too_many_assertions$EXE_POSTFIX" \ "$FOLDER/kit$OBJ_POSTFIX" \ "source/tests/test_too_many_assertions.c" \ $LINK_FLAGS if [ $? -ne 0 ]; then exit 1 fi $COMPILE $FLAGS \ $FLAG_EXE"$FOLDER/test_too_many_tests$EXE_POSTFIX" \ "$FOLDER/kit$OBJ_POSTFIX" \ "source/tests/test_too_many_tests.c" \ $LINK_FLAGS if [ $? -ne 0 ]; then exit 1 fi $COMPILEPP $FLAGS \ $FLAG_EXE"$FOLDER/test_cpp$EXE_POSTFIX" \ "$FOLDER/kit$OBJ_POSTFIX" \ "source/tests/test_cpp.cpp" \ $LINK_FLAGS if [ $? -ne 0 ]; then exit 1 fi $COMPILEPP $FLAGS \ $FLAG_EXE"$FOLDER/test_signals$EXE_POSTFIX" \ "$FOLDER/kit$OBJ_POSTFIX" \ "source/tests/test_signals.cpp" \ $LINK_FLAGS if [ $? -ne 0 ]; then exit 1 fi $COMPILE $FLAGS \ $FLAG_EXE"$FOLDER/test_interprocess$EXE_POSTFIX" \ "$FOLDER/kit$OBJ_POSTFIX" \ "source/tests/test_interprocess.c" \ $LINK_FLAGS if [ $? -ne 0 ]; then exit 1 fi if [ $SKIP_TESTS -ne 0 ] || [ "$COMPILE" = "emcc" ]; then exit 0 fi echo "Run tests" echo "" STATUS=0 $FOLDER/test_suite if [ $? -ne 0 ]; then STATUS=1 fi $FOLDER/test_too_many_assertions --quiet if [ $? -eq 0 ]; then echo "too many assertions - OK" else echo "too many assertions - FAILED (code $?)" STATUS=1 fi $FOLDER/test_too_many_tests --quiet if [ $? -eq 0 ]; then echo "too many tests - OK" else echo "too many tests - FAILED (code $?)" STATUS=1 fi $FOLDER/test_cpp --quiet if [ $? -eq 0 ]; then echo "cpp - OK" else echo "cpp - FAILED (code $?)" STATUS=1 fi $FOLDER/test_signals --quiet if [ $? -eq 0 ]; then echo "signals - OK" else echo "signals - FAILED (code $?)" STATUS=1 fi $FOLDER/test_interprocess clean $FOLDER/test_interprocess reader & $FOLDER/test_interprocess writer if [ $? -eq 0 ]; then echo "interprocess - OK" else echo "interprocess - FAILED (code $?)" STATUS=1 fi exit $STATUS