name: asio CI

on:
  push:
    branches: [ master, citest-* ]

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        build-type: ['sanity']
        runs-on: [ubuntu-20.04, ubuntu-22.04, macos-latest]
        compiler: [g++-8, g++-9, g++-10, g++-12, clang++-10, clang++-14, g++]
        cxx-std: ['c++11', 'c++14', 'c++17', 'c++2a', 'c++20']
        separate-compilation: ['', '--enable-separate-compilation']
        optim-level: ['-O0']
        no-deprecated: ['']
        select-reactor: ['', '-DASIO_DISABLE_EPOLL', '-DASIO_DISABLE_KQUEUE']
        handler-tracking: ['']
        boost: ['']
        boost-url: ['']
        exclude:
          # New compilers don't run on ubuntu 20.04
          - runs-on: ubuntu-20.04
            compiler: g++-12
          - runs-on: ubuntu-20.04
            compiler: clang++-14
          # Older compilers don't run on ubuntu 22.04
          - runs-on: ubuntu-22.04
            compiler: g++-8
          - runs-on: ubuntu-22.04
            compiler: clang++-10
          # Unversioned g++ doesn't run on ubuntu
          - runs-on: ubuntu-20.04
            compiler: g++
          - runs-on: ubuntu-22.04
            compiler: g++
          # Versioned g++ and clang++ don't run on macOS
          - runs-on: macos-latest
            compiler: g++-8
          - runs-on: macos-latest
            compiler: g++-9
          - runs-on: macos-latest
            compiler: g++-10
          - runs-on: macos-latest
            compiler: g++-12
          - runs-on: macos-latest
            compiler: clang++-10
          - runs-on: macos-latest
            compiler: clang++-14
          # Older compilers don't support newer std variants
          - compiler: g++-8
            cxx-std: c++20
          - compiler: g++-9
            cxx-std: c++20
          - compiler: g++-10
            cxx-std: c++2a
          - compiler: g++-12
            cxx-std: c++2a
          - compiler: clang++-10
            cxx-std: c++20
          - compiler: clang++-14
            cxx-std: c++20
          - compiler: clang++-14
            cxx-std: c++2a
          - runs-on: macos-latest
            cxx-std: c++20
          # Specifying the select reactor is OS-specific
          - runs-on: ubuntu-20.04
            select-reactor: -DASIO_DISABLE_KQUEUE
          - runs-on: ubuntu-22.04
            select-reactor: -DASIO_DISABLE_KQUEUE
          - runs-on: macos-latest
            select-reactor: -DASIO_DISABLE_EPOLL
          # Trim builds that use separate compilation
          - compiler: g++-8
            separate-compilation: --enable-separate-compilation
          - compiler: g++-9
            separate-compilation: --enable-separate-compilation
          - compiler: g++-10
            separate-compilation: --enable-separate-compilation
          - runs-on: macos-latest
            cxx-std: c++14
            separate-compilation: --enable-separate-compilation
          - runs-on: macos-latest
            cxx-std: c++17
            separate-compilation: --enable-separate-compilation
          # Trim builds that use select reactor
          - compiler: g++-8
            select-reactor: -DASIO_DISABLE_EPOLL
          - compiler: g++-9
            select-reactor: -DASIO_DISABLE_EPOLL
          - compiler: g++-10
            select-reactor: -DASIO_DISABLE_EPOLL
        include:
          #
          # Linux / g++-12 -std=c++20 -fcoroutines / -O2 / standalone
          #
          - build-type: full
            runs-on: ubuntu-22.04
            compiler: g++-12
            cxx-std: c++20 -fcoroutines
            optim-level: -O2
          #
          # Linux / g++-12 -std=c++17 / -O2 / boost 1.76
          #
          - build-type: full
            runs-on: ubuntu-22.04
            compiler: g++-12
            cxx-std: c++17
            optim-level: -O2
            with-boost: --with-boost=$GITHUB_WORKSPACE/boost_1_76_0
            boost-url: https://boostorg.jfrog.io/artifactory/main/release/1.76.0/source/boost_1_76_0.tar.bz2
          #
          # Linux / g++-10 / -O2 / standalone
          #
          - build-type: full
            runs-on: ubuntu-20.04
            compiler: g++-10
            cxx-std: c++14
            optim-level: -O2
          #
          # Linux / g++-10 / -O0 / standalone / handler tracking
          #
          - build-type: full
            runs-on: ubuntu-20.04
            compiler: g++-10
            cxx-std: c++14
            optim-level: -O0
            handler-tracking: -DASIO_ENABLE_HANDLER_TRACKING
          #
          # Linux / g++-10 / -O0 / standalone / epoll disabled
          #
          - build-type: full
            runs-on: ubuntu-20.04
            compiler: g++-10
            cxx-std: c++14
            optim-level: -O0
            select-reactor: -DASIO_DISABLE_EPOLL
          #
          # Linux / g++-10 / -O0 / standalone / separate compilation / handler tracking
          #
          - build-type: full
            runs-on: ubuntu-20.04
            compiler: g++-10
            cxx-std: c++14
            separate-compilation: --enable-separate-compilation
            optim-level: -O0
            handler-tracking: -DASIO_ENABLE_HANDLER_TRACKING
          #
          # Linux / g++-10 / -O0 / standalone / separate compilation / epoll disabled
          #
          - build-type: full
            runs-on: ubuntu-20.04
            compiler: g++-10
            cxx-std: c++14
            separate-compilation: --enable-separate-compilation
            optim-level: -O0
            select-reactor: -DASIO_DISABLE_EPOLL
          #
          # Linux / g++-10 / -O2 / boost 1.83
          #
          - build-type: full
            runs-on: ubuntu-20.04
            compiler: g++-10
            cxx-std: c++14
            optim-level: -O2
            with-boost: --with-boost=$GITHUB_WORKSPACE/boost_1_83_0
            boost-url: https://boostorg.jfrog.io/artifactory/main/release/1.83.0/source/boost_1_83_0.tar.bz2
          #
          # Linux / g++-10 / -O0 / boost 1.83 / epoll disabled
          #
          - build-type: full
            runs-on: ubuntu-20.04
            compiler: g++-10
            cxx-std: c++14
            optim-level: -O0
            with-boost: --with-boost=$GITHUB_WORKSPACE/boost_1_83_0
            boost-url: https://boostorg.jfrog.io/artifactory/main/release/1.83.0/source/boost_1_83_0.tar.bz2
            select-reactor: -DASIO_DISABLE_EPOLL
          #
          # Linux / g++-10 / -O0 / boost 1.83 / separate compilation
          #
          - build-type: full
            runs-on: ubuntu-20.04
            compiler: g++-10
            cxx-std: c++14
            separate-compilation: --enable-separate-compilation
            optim-level: -O0
            with-boost: --with-boost=$GITHUB_WORKSPACE/boost_1_83_0
            boost-url: https://boostorg.jfrog.io/artifactory/main/release/1.83.0/source/boost_1_83_0.tar.bz2
          #
          # Linux / g++-8 / -O2 / standalone
          #
          - build-type: full
            runs-on: ubuntu-20.04
            compiler: g++-8
            cxx-std: c++11
            optim-level: -O2
          #
          # Linux / g++-8 / -O0 / standalone / separate compilation
          #
          - build-type: full
            runs-on: ubuntu-20.04
            compiler: g++-8
            cxx-std: c++11
            separate-compilation: --enable-separate-compilation
            optim-level: -O0
          #
          # Linux / g++-8 -std=c++11 / -O2 / boost 1.83
          #
          - build-type: full
            runs-on: ubuntu-20.04
            compiler: g++-8
            cxx-std: c++11
            separate-compilation: --enable-separate-compilation
            optim-level: -O2
            with-boost: --with-boost=$GITHUB_WORKSPACE/boost_1_83_0
            boost-url: https://boostorg.jfrog.io/artifactory/main/release/1.83.0/source/boost_1_83_0.tar.bz2
          #
          # Linux / clang++-14 -std=c++2a / -O2 / standalone
          #
          - build-type: full
            runs-on: ubuntu-22.04
            compiler: clang++-14
            cxx-std: c++2a
            cxx-stdlib: -stdlib=libc++
            optim-level: -O2
          #
          # Linux / clang++-14 -std=c++11 / -O0 / standalone / separate compilation
          #
          - build-type: full
            runs-on: ubuntu-22.04
            compiler: clang++-14
            cxx-std: c++11
            separate-compilation: --enable-separate-compilation
            optim-level: -O0
          #
          # Linux / clang++-14 -std=c++20 / -O2 / standalone / separate compilation
          #
          - build-type: full
            runs-on: ubuntu-22.04
            compiler: clang++-14
            cxx-std: c++20
            cxx-stdlib: -stdlib=libc++
            separate-compilation: --enable-separate-compilation
            optim-level: -O2
          #
          # Linux / clang++-10 -std=c++11 / -O2 / standalone
          #
          - build-type: full
            runs-on: ubuntu-20.04
            compiler: clang++-10
            cxx-std: c++11
            optim-level: -O2
          #
          # macOS / c++2a -fcoroutines-ts / -O2 / standalone
          #
          - build-type: full
            runs-on: macos-latest
            compiler: g++
            cxx-std: c++2a -fcoroutines-ts
            optim-level: -O2
          #
          # macOS / c++11 / -O2 / standalone
          #
          - build-type: full
            runs-on: macos-latest
            compiler: g++
            cxx-std: c++11
            optim-level: -O2
          #
          # macOS / c++11 / -O0 / standalone / kqueue disabled
          #
          - build-type: full
            runs-on: macos-latest
            compiler: g++
            cxx-std: c++11
            optim-level: -O0
            select-reactor: -DASIO_DISABLE_KQUEUE
          #
          # macOS / c++11 / -O0 / standalone / separate compilation
          #
          - build-type: full
            runs-on: macos-latest
            compiler: g++
            cxx-std: c++11
            separate-compilation: --enable-separate-compilation
            optim-level: -O0
          #
          # macOS / c++11 / -O2 / boost 1.83
          #
          - build-type: full
            runs-on: macos-latest
            compiler: g++
            cxx-std: c++11
            optim-level: -O2
            with-boost: --with-boost=$GITHUB_WORKSPACE/boost_1_83_0
            boost-url: https://boostorg.jfrog.io/artifactory/main/release/1.83.0/source/boost_1_83_0.tar.bz2
          #
          # macOS / c++11 / -O2 / boost 1.83 / separate compilation
          #
          - build-type: full
            runs-on: macos-latest
            compiler: g++
            cxx-std: c++11
            separate-compilation: --enable-separate-compilation
            optim-level: -O0
            with-boost: --with-boost=$GITHUB_WORKSPACE/boost_1_83_0
            boost-url: https://boostorg.jfrog.io/artifactory/main/release/1.83.0/source/boost_1_83_0.tar.bz2
    runs-on: ${{ matrix.runs-on }}
    env:
      CXX: ${{ matrix.compiler }}
      CXXFLAGS: -std=${{ matrix.cxx-std }} ${{ matrix.cxx-stdlib }} ${{ matrix.optim-level }} -Wall -Wextra ${{ matrix.no-deprecated }} ${{ matrix.select-reactor }} ${{ matrix.handler-tracking }}
    steps:
    - uses: actions/checkout@v4
    - name: Install autotools
      if: startsWith(matrix.runs-on, 'macos')
      run: brew install automake
    - name: Install compiler
      if: startsWith(matrix.runs-on, 'ubuntu')
      run: sudo apt-get install -y ${{ matrix.compiler }}
    - name: Install boost
      if: startsWith(matrix.with-boost, '--with-boost=$GITHUB_WORKSPACE')
      run: |
        wget --quiet -O - ${{ matrix.boost-url }} | tar -xj
    - name: Configure
      working-directory: asio
      run: |
        ./autogen.sh
        ./configure ${{ matrix.separate-compilation }} ${{ matrix.with-boost }}
    - name: Line length check
      working-directory: asio
      run: perl ./boostify.pl --includes-only
    - name: Sanity check
      if: startsWith(matrix.build-type, 'sanity')
      working-directory: asio/src/tests
      run: make unit/io_context.log unit/ip/tcp.log unit/ts/net.log
    - name: Build
      if: startsWith(matrix.build-type, 'full')
      working-directory: asio
      run: make && make check
