name: CMake

on:
  push:
    branches:
    - master
    - try-github-actions-for-windows
    paths:
    - .github/workflows/cmake.yml
    - '**CMakeLists.txt'
    - 'BLAS/**'
    - 'CBLAS/**'
    - 'CMAKE/**'
    - 'INSTALL/**'
    - 'LAPACKE/**'
    - 'SRC/**'
    - 'TESTING/**'
    - '!**README'
    - '!**Makefile'
    - '!**md'
  pull_request:
    paths:
    - .github/workflows/cmake.yml
    - '**CMakeLists.txt'
    - 'BLAS/**'
    - 'CBLAS/**'
    - 'CMAKE/**'
    - 'INSTALL/**'
    - 'LAPACKE/**'
    - 'SRC/**'
    - 'TESTING/**'
    - '!**README'
    - '!**Makefile'
    - '!**md'

permissions:
  contents: read

env:
  CFLAGS: "-Wall -pedantic"
  # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)

defaults:
  run:
    shell: bash

jobs:

  test-install-release:
    # Use GNU compilers
  
    # The CMake configure and build commands are platform agnostic and should work equally
    # well on Windows or Mac.  You can convert this to a matrix build if you need
    # cross-platform coverage.
    # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
    runs-on: ${{ matrix.os }}

    env:
      BUILD_TYPE: Release
      FFLAGS: ${{ matrix.fflags }}

    strategy:
      fail-fast: true
      matrix:
        os: [ macos-latest, ubuntu-latest, windows-latest ]
        fflags: [
          "-Wall -Wno-unused-dummy-argument -Wno-unused-variable -Wno-unused-label -Werror=conversion -fimplicit-none -frecursive -fcheck=all",
          "-Wall -Wno-unused-dummy-argument -Wno-unused-variable -Wno-unused-label -Werror=conversion -fimplicit-none -frecursive -fcheck=all -fopenmp" ]
    
    steps:
    
    - name: Checkout LAPACK
      uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2

    - name: Install ninja-build tool
      uses: seanmiddleditch/gha-setup-ninja@16b940825621068d98711680b6c3ff92201f8fc0 # v3

    - name: Use GCC-14 on MacOS
      if: ${{ matrix.os == 'macos-latest' }}
      run: >
        cmake -B build -G Ninja
        -D CMAKE_C_COMPILER="gcc-14"
        -D CMAKE_Fortran_COMPILER="gfortran-14"
        -D USE_FLAT_NAMESPACE:BOOL=ON

    - name: Special flags for Windows
      if: ${{ matrix.os == 'windows-latest' }}
      run: >
        cmake -B build -G Ninja
        -D CMAKE_EXE_LINKER_FLAGS="-Wl,--stack=2097152"

    - name: Configure CMake
      # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
      # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
      run: >
        cmake -B build -G Ninja
        -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
        -D CMAKE_INSTALL_PREFIX=${{github.workspace}}/lapack_install
        -D CBLAS:BOOL=ON
        -D LAPACKE:BOOL=ON
        -D BUILD_TESTING:BOOL=ON
        -D LAPACKE_WITH_TMG:BOOL=ON
        -D BUILD_SHARED_LIBS:BOOL=ON

    - name: Build
      # Execute tests defined by the CMake configuration.  
      # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
      run: cmake --build build --config ${{env.BUILD_TYPE}}

    - name: Test with OpenMP
      working-directory: ${{github.workspace}}/build
      if: ${{ contains( matrix.fflags, 'openmp' ) && (matrix.os != 'windows-latest') }}
      run: ctest -C ${{env.BUILD_TYPE}} --schedule-random -j1 --output-on-failure --timeout 100

    - name: Test
      working-directory: ${{github.workspace}}/build
      if: ${{ !contains( matrix.fflags, 'openmp' ) && (matrix.os != 'windows-latest') }}
      run: ctest -C ${{env.BUILD_TYPE}} --schedule-random -j2 --output-on-failure --timeout 100

    - name: Install
      run: cmake --build build --target install -j2

  coverage:
    runs-on: ubuntu-latest 
    env:
      BUILD_TYPE: Coverage
      FFLAGS: "-fopenmp"
    steps:     
    
    - name: Checkout LAPACK
      uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2

    - name: Install ninja-build tool
      uses: seanmiddleditch/gha-setup-ninja@16b940825621068d98711680b6c3ff92201f8fc0 # v3

    - name: Configure CMake
      # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
      # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
      run: >
        cmake -B build -G Ninja
        -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
        -D CMAKE_INSTALL_PREFIX=${{github.workspace}}/lapack_install
        -D CBLAS:BOOL=ON
        -D LAPACKE:BOOL=ON
        -D BUILD_TESTING:BOOL=ON
        -D LAPACKE_WITH_TMG:BOOL=ON
        -D BUILD_SHARED_LIBS:BOOL=ON

    - name: Install
      run: cmake --build build --target install -j2

    - name: Coverage
      run: |
        echo "Coverage"
        cmake --build build --target coverage
        bash <(curl -s https://codecov.io/bash) -X gcov

  test-install-cblas-lapacke-without-fortran-compiler:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout LAPACK
      uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2

    - name: Install ninja-build tool
      uses: seanmiddleditch/gha-setup-ninja@16b940825621068d98711680b6c3ff92201f8fc0 # v3

    - name: Install basics
      run: |
        sudo apt update
        sudo apt install -y cmake liblapack-dev libblas-dev
        sudo apt purge gfortran

    - name: Configure CMake
      run: >
        cmake -B build -G Ninja
        -D CMAKE_BUILD_TYPE=Release
        -D CMAKE_INSTALL_PREFIX=${{github.workspace}}/lapack_install
        -D CBLAS:BOOL=ON
        -D LAPACKE:BOOL=ON
        -D USE_OPTIMIZED_BLAS:BOOL=ON
        -D USE_OPTIMIZED_LAPACK:BOOL=ON
        -D BUILD_TESTING:BOOL=OFF
        -D LAPACKE_WITH_TMG:BOOL=OFF
        -D BUILD_SHARED_LIBS:BOOL=ON

    - name: Install
      run: cmake --build build --target install -j2

  memory-check:
    runs-on: ubuntu-latest
    env:
      BUILD_TYPE: Debug

    steps:

    - name: Checkout LAPACK
      uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2

    - name: Install ninja-build tool
      uses: seanmiddleditch/gha-setup-ninja@16b940825621068d98711680b6c3ff92201f8fc0 # v3
    
    - name: Install APT packages
      run: |
        sudo apt update
        sudo apt install -y cmake valgrind gfortran

    - name: Configure CMake
      run: >
        cmake -B build -G Ninja
        -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
        -D CBLAS:BOOL=ON
        -D LAPACKE:BOOL=ON
        -D BUILD_TESTING:BOOL=ON
        -D LAPACKE_WITH_TMG:BOOL=ON
        -D BUILD_SHARED_LIBS:BOOL=ON
        -D LAPACK_TESTING_USE_PYTHON:BOOL=OFF

    - name: Build
      run: cmake --build build --config ${{env.BUILD_TYPE}}

    - name: Test
      working-directory: ${{github.workspace}}/build
      run: |
        ctest -C ${{env.BUILD_TYPE}} --schedule-random -j2 -T memcheck > memcheck.out
        cat memcheck.out
        if tail -n 1 memcheck.out | grep -q "Memory checking results:"; then
          exit 0
        else
          for f in Testing/Temporary/MemoryChecker.*.log; do
            if tail -n 1 $f | grep -q "ERROR SUMMARY: 0 errors"; then
              tail -n 1 $f
              continue
            else
              echo "Memory check failed in $f"
              cat $f
              exit 1
            fi
          done
          exit 0
        fi
