name: CI on: [push, pull_request] jobs: ci: name: ${{ matrix.name }} runs-on: ${{ matrix.os }} env: CMAKE_GENERATOR: Ninja ASAN_OPTIONS: strict_string_checks=true:detect_odr_violation=2:detect_stack_use_after_return=true:check_initialization_order=true:strict_init_order=true TSAN_OPTIONS: force_seq_cst_atomics=1 CTEST_OUTPUT_ON_FAILURE: ON CTEST_PARALLEL_LEVEL: 2 ACTIONS_ALLOW_UNSECURE_COMMANDS: true # because of the set-env calls strategy: fail-fast: false matrix: # Github Actions requires a single row to be added to the build matrix. # See https://help.github.com/en/articles/workflow-syntax-for-github-actions. name: [ ubuntu-18.04-gcc-4.8, ubuntu-18.04-gcc-4.9, ubuntu-18.04-gcc-5, ubuntu-18.04-gcc-6, ubuntu-18.04-gcc-7, ubuntu-18.04-gcc-8, ubuntu-18.04-gcc-9, ubuntu-latest-gcc-10, ubuntu-18.04-clang-3.5, ubuntu-18.04-clang-3.6, ubuntu-18.04-clang-3.7, ubuntu-18.04-clang-3.8, ubuntu-18.04-clang-3.9, ubuntu-18.04-clang-4.0, ubuntu-18.04-clang-5.0, ubuntu-18.04-clang-6.0, ubuntu-18.04-clang-7, ubuntu-18.04-clang-8, # ubuntu-latest-clang-9, ubuntu-latest-clang-10, # ubuntu-latest-clang-11, windows-2016-cl, windows-2016-clang-cl, windows-2016-clang, # windows-2016-gcc, windows-2019-cl, windows-2019-clang-cl, windows-2019-clang, # windows-2019-gcc, macOS-latest-xcode-11.3, ] include: - name: ubuntu-18.04-gcc-4.8 os: ubuntu-18.04 compiler: gcc version: "4.8" - name: ubuntu-18.04-gcc-4.9 os: ubuntu-18.04 compiler: gcc version: "4.9" - name: ubuntu-18.04-gcc-5 os: ubuntu-18.04 compiler: gcc version: "5" - name: ubuntu-18.04-gcc-6 os: ubuntu-18.04 compiler: gcc version: "6" - name: ubuntu-18.04-gcc-7 os: ubuntu-18.04 compiler: gcc version: "7" - name: ubuntu-18.04-gcc-8 os: ubuntu-18.04 compiler: gcc version: "8" - name: ubuntu-18.04-gcc-9 os: ubuntu-18.04 compiler: gcc version: "9" - name: ubuntu-latest-gcc-10 os: ubuntu-latest compiler: gcc version: "10" - name: ubuntu-18.04-clang-3.5 os: ubuntu-18.04 compiler: clang version: "3.5" - name: ubuntu-18.04-clang-3.6 os: ubuntu-18.04 compiler: clang version: "3.6" - name: ubuntu-18.04-clang-3.7 os: ubuntu-18.04 compiler: clang version: "3.7" - name: ubuntu-18.04-clang-3.8 os: ubuntu-18.04 compiler: clang version: "3.8" - name: ubuntu-18.04-clang-3.9 os: ubuntu-18.04 compiler: clang version: "3.9" - name: ubuntu-18.04-clang-4.0 os: ubuntu-18.04 compiler: clang version: "4.0" - name: ubuntu-18.04-clang-5.0 os: ubuntu-18.04 compiler: clang version: "5.0" - name: ubuntu-18.04-clang-6.0 os: ubuntu-18.04 compiler: clang version: "6.0" - name: ubuntu-18.04-clang-7 os: ubuntu-18.04 compiler: clang version: "7" - name: ubuntu-18.04-clang-8 os: ubuntu-18.04 compiler: clang version: "8" # fails like this: https://github.com/onqtam/doctest/runs/1562896476?check_suite_focus=true # - name: ubuntu-latest-clang-9 # os: ubuntu-latest # compiler: clang # version: "9" - name: ubuntu-latest-clang-10 os: ubuntu-latest compiler: clang version: "10" # fails like this: https://github.com/onqtam/doctest/runs/1562896512?check_suite_focus=true # - name: ubuntu-latest-clang-11 # os: ubuntu-latest # compiler: clang # version: "11" - name: windows-2016-cl os: windows-2016 compiler: cl - name: windows-2016-clang-cl os: windows-2016 compiler: clang-cl - name: windows-2016-clang os: windows-2016 compiler: clang - name: windows-2019-cl os: windows-2019 compiler: cl # fails to install it... # - name: windows-2016-gcc # os: windows-2016 # compiler: gcc - name: windows-2019-clang-cl os: windows-2019 compiler: clang-cl - name: windows-2019-clang os: windows-2019 compiler: clang # fails to install it... # - name: windows-2019-gcc # os: windows-2019 # compiler: gcc - name: macOS-latest-xcode-11.3 os: macOS-10.15 compiler: xcode version: "11.3" steps: - uses: actions/checkout@v1 - name: Install (Linux) if: runner.os == 'Linux' run: | # CMake 3.15 allows specifying the generator using the CMAKE_GENERATOR # environment variable. curl -sSL https://github.com/Kitware/CMake/releases/download/v3.15.4/cmake-3.15.4-Linux-x86_64.tar.gz -o cmake.tar.gz sudo tar xf cmake.tar.gz --strip 1 -C /usr/local # Required for libc6-dbg:i386 and g++-multilib packages which are # needed for x86 builds. sudo dpkg --add-architecture i386 # clang-3.7 and earlier are not available in Bionic anymore so we get # them from the Xenial repositories instead. sudo add-apt-repository "deb http://dk.archive.ubuntu.com/ubuntu/ xenial main" sudo add-apt-repository "deb http://dk.archive.ubuntu.com/ubuntu/ xenial universe" # LLVM 9 is not in Bionic's repositories so we add the official LLVM repository. if [ "${{ matrix.compiler }}" = "clang" ] && [ "${{ matrix.version }}" = "9" ]; then sudo add-apt-repository "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main" fi sudo apt-get update # sudo apt-get install libopenmpi-dev # sudo apt-get install openmpi-bin # libc6-dbg:i386 is required for running valgrind on x86. sudo apt-get install -y ninja-build valgrind libc6-dbg:i386 if [ "${{ matrix.compiler }}" = "gcc" ]; then sudo apt-get install -y g++-${{ matrix.version }} g++-${{ matrix.version }}-multilib echo "::set-env name=CC::gcc-${{ matrix.version }}" echo "::set-env name=CXX::g++-${{ matrix.version }}" else sudo apt-get install -y clang-${{ matrix.version }} g++-multilib echo "::set-env name=CC::clang-${{ matrix.version }}" echo "::set-env name=CXX::clang++-${{ matrix.version }}" fi - name: Install (macOS) if: runner.os == 'macOS' run: | brew install cmake ninja if [ "${{ matrix.compiler }}" = "gcc" ]; then brew install gcc@${{ matrix.version }} echo "::set-env name=CC::gcc-${{ matrix.version }}" echo "::set-env name=CXX::g++-${{ matrix.version }}" else ls -ls /Applications/ sudo xcode-select -switch /Applications/Xcode_${{ matrix.version }}.app echo "::set-env name=CC::clang" echo "::set-env name=CXX::clang++" fi - name: Install (Windows) if: runner.os == 'Windows' shell: powershell run: | Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh') scoop install ninja --global if ("${{ matrix.compiler }}".StartsWith("clang")) { scoop install llvm --global } if ("${{ matrix.compiler }}" -eq "gcc") { # Chocolatey GCC is broken on the windows-2019 image. # See: https://github.com/DaanDeMeyer/doctest/runs/231595515 # See: https://github.community/t5/GitHub-Actions/Something-is-wrong-with-the-chocolatey-installed-version-of-gcc/td-p/32413 scoop install gcc --global echo "::set-env name=CC::gcc" echo "::set-env name=CXX::g++" } elseif ("${{ matrix.compiler }}" -eq "clang") { echo "::set-env name=CC::clang" echo "::set-env name=CXX::clang++" } else { echo "::set-env name=CC::${{ matrix.compiler }}" echo "::set-env name=CXX::${{ matrix.compiler }}" } # Scoop modifies the PATH so we make the modified PATH global. echo "::set-env name=PATH::$env:PATH" - name: Configure ASAN/UBSAN if: runner.os == 'Linux' || runner.os == 'macOS' run: | # https://stackoverflow.com/a/37939589/11900641 function version { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; } # Disable sanitizers in configurations where we know they are buggy. # TODO: Move these conditions to the if clause if Github Actions ever # adds support for comparing versions. # See: https://github.community/t5/GitHub-Actions/Allow-comparing-versions-in-if-conditions/m-p/33912#M1710 if [ "${{ runner.os }}" = "Linux" ] && \ [ "${{ matrix.compiler }}" = "gcc" ] && \ [ $(version ${{ matrix.version }}) -le $(version "5.0") ]; then exit 0 fi if [ "${{ runner.os }}" = "Linux" ] && \ [ "${{ matrix.compiler }}" = "clang" ] && \ [ $(version ${{ matrix.version }}) -le $(version "6.0") ]; then exit 0 fi if [ "${{ runner.os }}" = "macOS" ] && \ [ "${{ matrix.compiler }}" = "xcode" ] && \ [ $(version ${{ matrix.version }}) -le $(version "9.4.1") ]; then exit 0 fi if [ "${{ runner.os }}" = "macOS" ] && \ [ "${{ matrix.compiler }}" = "gcc" ]; then exit 0 fi ASAN_UBSAN_FLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer" # Link statically against ASAN libraries because dynamically linking # against ASAN libraries causes problems when using dlopen on Ubuntu. # See: https://github.com/DaanDeMeyer/doctest/runs/249002713 if [ "${{ runner.os }}" = "Linux" ] && [ "${{ matrix.compiler }}" = "gcc" ]; then ASAN_UBSAN_FLAGS="$ASAN_UBSAN_FLAGS -static-libasan" fi # Compiling in bash on Windows doesn't work and powershell doesn't # exit on non-zero exit codes so we're forced to use cmd which means # we don't have a cross platform way to access environment variables. # To circumvent this, we put the sanitizer flags in an environment # variable that is automatically picked up by CMake. echo "::set-env name=CXXFLAGS::$ASAN_UBSAN_FLAGS" - name: Configure TSAN if: runner.os == 'Linux' || runner.os == 'macOS' run: | # https://stackoverflow.com/a/37939589/11900641 function version { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; } if [ "${{ runner.os }}" = "Linux" ] && \ [ "${{ matrix.compiler }}" = "gcc" ] && \ [ $(version ${{ matrix.version }}) -le $(version "6.0") ]; then exit 0 fi if [ "${{ runner.os }}" = "Linux" ] && \ [ "${{ matrix.compiler }}" = "clang" ] && \ [ $(version ${{ matrix.version }}) -le $(version "3.9") ]; then exit 0 fi if [ "${{ runner.os }}" = "macOS" ] && \ [ "${{ matrix.compiler }}" = "gcc" ]; then exit 0 fi TSAN_FLAGS="-fsanitize=thread -pie -fPIE" if [ "${{ runner.os }}" = "Linux" ] && [ "${{ matrix.compiler }}" = "gcc" ]; then TSAN_FLAGS="$TSAN_FLAGS -static-libtsan" fi # The thread sanitizers build does not run on Windows so we can just # use bash syntax to access the TSAN flags in the thread sanitizers # build step. echo "::set-env name=TSAN_FLAGS::$TSAN_FLAGS" - name: Configure x64 if: runner.os == 'Windows' run: .github\workflows\vsenv.bat -arch=x64 -host_arch=x64 - name: Build & Test Debug x64 run: | cmake -E remove_directory build cmake -B build -S . -DCMAKE_BUILD_TYPE=Debug -DDOCTEST_TEST_MODE=COMPARE cmake --build build cd build ctest - name: Build & Test Release x64 run: | cmake -E remove_directory build cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DDOCTEST_TEST_MODE=COMPARE cmake --build build cd build ctest # Valgrind doesn't support the latest macOS versions. # `-DCMAKE_CXX_FLAGS=""` overrides CXXFLAGS (disables sanitizers). - name: Build & Test Debug x64 Valgrind if: runner.os == 'Linux' run: | cmake -E remove_directory build cmake -B build -S . -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="" -DDOCTEST_TEST_MODE=VALGRIND cmake --build build cd build ctest - name: Build & Test Release x64 Valgrind if: runner.os == 'Linux' run: | cmake -E remove_directory build cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="" -DDOCTEST_TEST_MODE=VALGRIND cmake --build build cd build ctest - name: Build & Test Debug x64 Thread Sanitizers if: runner.os == 'Linux' || runner.os == 'macOS' run: | cmake -E remove_directory build cmake -B build -S . -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="$TSAN_FLAGS" -DDOCTEST_TEST_MODE=COMPARE cmake --build build cd build ctest - name: Build & Test Debug x64 without RTTI if: runner.os == 'Linux' || runner.os == 'macOS' run: | cmake -E remove_directory build cmake -B build -S . -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-fno-rtti" -DDOCTEST_TEST_MODE=COMPARE cmake --build build cd build ctest - name: Build x64 Debug without exceptions if: runner.os == 'Linux' || runner.os == 'macOS' run: | cmake -E remove_directory build cmake -B build -S . -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-fno-exceptions -DDOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS" cmake --build build # MinGW x86 tests fail on Windows: https://github.com/DaanDeMeyer/doctest/runs/240600881. # MacOS doesn't support x86 from Xcode 10 onwards. - name: Configure x86 shell: pwsh if: (runner.os == 'Windows' && matrix.compiler != 'gcc') || runner.os == 'Linux' run: | if ("${{ runner.os }}" -eq "Windows") { & .github\workflows\vsenv.bat -arch=x86 -host_arch=x64 } if ("${{ matrix.compiler }}" -notcontains "cl") { echo "::set-env name=CXXFLAGS::$env:CXXFLAGS -m32" } - name: Build & Test Debug x86 if: (runner.os == 'Windows' && matrix.compiler != 'gcc') || runner.os == 'Linux' run: | cmake -E remove_directory build cmake -B build -S . -DCMAKE_BUILD_TYPE=Debug -DDOCTEST_TEST_MODE=COMPARE cmake --build build cd build ctest - name: Build & Test Release x86 if: (runner.os == 'Windows' && matrix.compiler != 'gcc') || runner.os == 'Linux' run: | cmake -E remove_directory build cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DDOCTEST_TEST_MODE=COMPARE cmake --build build cd build ctest - name: Build & Test Debug x86 Valgrind if: runner.os == 'Linux' run: | cmake -E remove_directory build cmake -B build -S . -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-m32" -DDOCTEST_TEST_MODE=VALGRIND cmake --build build cd build ctest - name: Build & Test Release x86 Valgrind if: runner.os == 'Linux' run: | cmake -E remove_directory build cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-m32" -DDOCTEST_TEST_MODE=VALGRIND cmake --build build cd build ctest