name: Ubuntu-sanitizers

on:
  push:
  pull_request:
  schedule:
    # https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows#scheduled-events
    # * is a special character in YAML so you have to quote this string
    # every Sunday at 2 am
    - cron:  '0 2 * * SUN'

jobs:
  build-ubuntu-sanitizers:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        flags: ["-fsanitize=address", "-fsanitize=leak", "-fsanitize=thread", "-fsanitize=undefined"]

    steps:
    # https://github.com/marketplace/actions/cancel-workflow-action
    - name: Cancel Previous Runs
      uses: styfle/cancel-workflow-action@0.9.1
      with:
        access_token: ${{ github.token }}

    - name: Checkout repository
      uses: actions/checkout@v3

    - name: Print system information
      run: lscpu

    - name: Print OS information
      run: lsb_release -a

    - name: Install dependencies
      run: sudo apt-get update && sudo apt-get install -y libx11-dev libdc1394-dev libv4l-dev liblapack-dev libblas-dev libeigen3-dev nlohmann-json3-dev

    - name: Linear algebra liblapack/libblas alternatives
      run: |
        update-alternatives --list liblapack.so.3-x86_64-linux-gnu
        update-alternatives --list libblas.so.3-x86_64-linux-gnu

    - name: Clone visp-images
      env:
        BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
      # https://remarkablemark.org/blog/2022/09/25/check-git-branch-exists-in-remote-repository/
      run: |
        git clone --depth 1 https://github.com/lagadic/visp-images ${HOME}/visp-images
        echo "VISP_INPUT_IMAGE_PATH=$HOME/visp-images" >> $GITHUB_ENV
        echo ${VISP_INPUT_IMAGE_PATH}

    - name: Configure CMake
      run: |
        mkdir build
        cd build
        cmake .. -DCMAKE_C_FLAGS=${{ matrix.flags }} -DCMAKE_CXX_FLAGS=${{ matrix.flags }} -DCMAKE_LDFLAGS=${{ matrix.flags }} -DCMAKE_BUILD_TYPE=RelWithDebInfo -DUSE_OPENMP=OFF
        cat ViSP-third-party.txt

    - name: Compile
      working-directory: build
      run: make -j$(nproc)

    - name: Run unit tests with sanitizers
      env:
        # Workaround error in SimdLib
        # ==20865==ERROR: AddressSanitizer: odr-violation (0x7f4ad36c4500):
        #   [1] size=8 'ALIGNMENT' /home/runner/work/visp/visp/3rdparty/simdlib/Simd/SimdLib.cpp:82:18
        #   [2] size=8 'ALIGNMENT' /home/runner/work/visp/visp/3rdparty/simdlib/Simd/SimdLib.cpp:82:18
        # These globals were registered at these points:
        #   [1]:
        #     #0 0x7f4ad3702928 in __asan_register_globals ../../../../src/libsanitizer/asan/asan_globals.cpp:341
        #     #1 0x7f4ad2eea39a in _sub_I_00099_1 (/home/runner/work/visp/visp/build/lib/libvisp_mbt.so.3.5+0x4e839a)
        #     #2 0x7f4ad40c847d  (/lib64/ld-linux-x86-64.so.2+0x647d)
        #
        #   [2]:
        #     #0 0x7f4ad3702928 in __asan_register_globals ../../../../src/libsanitizer/asan/asan_globals.cpp:341
        #     #1 0x7f4ad1957db0 in _sub_I_00099_1 (/home/runner/work/visp/visp/build/lib/libvisp_core.so.3.5+0x6aadb0)
        #     #2 0x7f4ad40c847d  (/lib64/ld-linux-x86-64.so.2+0x647d)
        #
        # ==20865==HINT: if you don't care about these errors you may set ASAN_OPTIONS=detect_odr_violation=0
        # SUMMARY: AddressSanitizer: odr-violation: global 'ALIGNMENT' at /home/runner/work/visp/visp/3rdparty/simdlib/Simd/SimdLib.cpp:82:18
        ASAN_OPTIONS: detect_odr_violation=0
      working-directory: build
      run: ctest -j$(nproc) --output-on-failure
