name: build

on: push

jobs:
  build:
    runs-on: ${{ matrix.os }}

    strategy:
      matrix:
        os: [ubuntu-20.04, macos-10.15]
        compiler: [gcc, clang]
        buildtool: [autotools, cmake]
        http3: [http3, no-http3]
        openssl: [openssl1, openssl3]
        exclude:
        - os: macos-10.15
          openssl: openssl3
        - http3: no-http3
          openssl: openssl3
        - os: macos-10.15
          compiler: gcc

    steps:
    - uses: actions/checkout@v2
    - name: Linux setup
      if: runner.os == 'Linux'
      run: |
        sudo apt-get install \
          g++-8 \
          clang-10 \
          autoconf \
          automake \
          autotools-dev \
          libtool \
          pkg-config \
          zlib1g-dev \
          libcunit1-dev \
          libssl-dev \
          libxml2-dev \
          libev-dev \
          libevent-dev \
          libjansson-dev \
          libjemalloc-dev \
          libc-ares-dev \
          libelf-dev \
          cmake \
          cmake-data
        echo 'CPPFLAGS=-fsanitize=address,undefined -fno-sanitize-recover=undefined -g' >> $GITHUB_ENV
        echo 'LDFLAGS=-fsanitize=address,undefined -fno-sanitize-recover=undefined' >> $GITHUB_ENV
    - name: MacOS setup
      if: runner.os == 'macOS'
      run: |
        brew install \
          libev \
          libevent \
          c-ares \
          cunit \
          libressl \
          autoconf \
          automake \
          pkg-config \
          libtool
        echo 'PKG_CONFIG_PATH=/usr/local/opt/libressl/lib/pkgconfig:/usr/local/opt/libxml2/lib/pkgconfig' >> $GITHUB_ENV
    - name: Setup clang (Linux)
      if: runner.os == 'Linux' && matrix.compiler == 'clang'
      run: |
        echo 'CC=clang-10' >> $GITHUB_ENV
        echo 'CXX=clang++-10' >> $GITHUB_ENV
    - name: Setup clang (MacOS)
      if: runner.os == 'macOS' && matrix.compiler == 'clang'
      run: |
        echo 'CC=clang' >> $GITHUB_ENV
        echo 'CXX=clang++' >> $GITHUB_ENV
    - name: Setup gcc (Linux)
      if: runner.os == 'Linux' && matrix.compiler == 'gcc'
      run: |
        echo 'CC=gcc-8' >> $GITHUB_ENV
        echo 'CXX=g++-8' >> $GITHUB_ENV
    - name: Setup gcc (MacOS)
      if: runner.os == 'macOS' && matrix.compiler == 'gcc'
      run: |
        echo 'CC=gcc' >> $GITHUB_ENV
        echo 'CXX=g++' >> $GITHUB_ENV
    - name: Build libbpf
      if: matrix.http3 == 'http3' && matrix.compiler == 'clang' && runner.os == 'Linux'
      run: |
        git clone -b v0.6.1 https://github.com/libbpf/libbpf
        cd libbpf
        PREFIX=$PWD/build make -C src install

        EXTRA_AUTOTOOLS_OPTS="--with-libbpf"
        EXTRA_CMAKE_OPTS="-DWITH_LIBBPF=1"

        echo 'EXTRA_AUTOTOOLS_OPTS='"$EXTRA_AUTOTOOLS_OPTS" >> $GITHUB_ENV
        echo 'EXTRA_CMAKE_OPTS='"$EXTRA_CMAKE_OPTS" >> $GITHUB_ENV
    - name: Build quictls/openssl v1.1.1
      if: matrix.http3 == 'http3' && matrix.openssl == 'openssl1'
      run: |
        git clone --depth 1 -b OpenSSL_1_1_1m+quic https://github.com/quictls/openssl
        cd openssl
        ./config enable-tls1_3 --prefix=$PWD/build
        make -j$(nproc)
        make install_sw
    - name: Build quictls/openssl v3.0.x
      if: matrix.http3 == 'http3' && matrix.openssl == 'openssl3'
      run: |
        unset CPPFLAGS
        unset LDFLAGS

        git clone --depth 1 -b openssl-3.0.1+quic https://github.com/quictls/openssl
        cd openssl
        ./config enable-tls1_3 --prefix=$PWD/build --libdir=$PWD/build/lib
        make -j$(nproc)
        make install_sw
    - name: Build nghttp3
      if: matrix.http3 == 'http3'
      run: |
        git clone https://github.com/ngtcp2/nghttp3
        cd nghttp3
        git checkout 74a222fe0c89b7202bcdaf6ef27a232edffc85e3
        autoreconf -i
        ./configure --prefix=$PWD/build --enable-lib-only
        make -j$(nproc) check
        make install
    - name: Build ngtcp2
      if: matrix.http3 == 'http3'
      run: |
        git clone --depth 1 -b v0.1.0 https://github.com/ngtcp2/ngtcp2
        cd ngtcp2
        autoreconf -i
        ./configure --prefix=$PWD/build --enable-lib-only PKG_CONFIG_PATH="../openssl/build/lib/pkgconfig"
        make -j$(nproc) check
        make install
    - name: Setup extra environment variables for HTTP/3
      if: matrix.http3 == 'http3'
      run: |
        PKG_CONFIG_PATH="$PWD/openssl/build/lib/pkgconfig:$PWD/nghttp3/build/lib/pkgconfig:$PWD/ngtcp2/build/lib/pkgconfig:$PWD/libbpf/build/lib64/pkgconfig:$PKG_CONFIG_PATH"
        LDFLAGS="$LDFLAGS -Wl,-rpath,$PWD/openssl/build/lib -Wl,-rpath,$PWD/libbpf/build/lib64"
        EXTRA_AUTOTOOLS_OPTS="--enable-http3 $EXTRA_AUTOTOOLS_OPTS"
        EXTRA_CMAKE_OPTS="-DENABLE_HTTP3=1 $EXTRA_CMAKE_OPTS"

        echo 'PKG_CONFIG_PATH='"$PKG_CONFIG_PATH" >> $GITHUB_ENV
        echo 'LDFLAGS='"$LDFLAGS" >> $GITHUB_ENV
        echo 'EXTRA_AUTOTOOLS_OPTS='"$EXTRA_AUTOTOOLS_OPTS" >> $GITHUB_ENV
        echo 'EXTRA_CMAKE_OPTS='"$EXTRA_CMAKE_OPTS" >> $GITHUB_ENV
    - name: Setup git submodules
      run: |
        git submodule update --init
    - name: Configure autotools
      run: |
        autoreconf -i
        ./configure
    - name: Configure cmake
      if: matrix.buildtool == 'cmake'
      run: |
        make dist
        VERSION=$(grep PACKAGE_VERSION config.h | cut -d' ' -f3 | tr -d '"')
        tar xf nghttp2-$VERSION.tar.gz
        cd nghttp2-$VERSION
        echo 'NGHTTP2_CMAKE_DIR='"$PWD" >> $GITHUB_ENV

        # This fixes infamous 'stdio.h not found' error.
        echo 'SDKROOT='"$(xcrun --sdk macosx --show-sdk-path)" >> $GITHUB_ENV

        cmake -DENABLE_WERROR=1 -DWITH_MRUBY=1 -DWITH_NEVERBLEED=1 -DENABLE_APP=1 $EXTRA_CMAKE_OPTS -DCPPFLAGS="$CPPFLAGS" -DLDFLAGS="$LDFLAGS" .
    - name: Build nghttp2 with autotools
      if: matrix.buildtool == 'autotools'
      run: |
        make distcheck \
          DISTCHECK_CONFIGURE_FLAGS="--with-mruby --with-neverbleed --with-libev --enable-werror $EXTRA_AUTOTOOLS_OPTS CPPFLAGS=\"$CPPFLAGS\" LDFLAGS=\"$LDFLAGS\""
    - name: Build nghttp2 with cmake
      if: matrix.buildtool == 'cmake'
      run: |
        cd $NGHTTP2_CMAKE_DIR
        make
        make check
    - name: Integration test
      # Integration tests for nghttpx; autotools erases build
      # artifacts.
      if: matrix.buildtool == 'cmake'
      run: |
        cd $NGHTTP2_CMAKE_DIR/integration-tests
        make itprep it

  build-windows:
    runs-on: windows-latest

    steps:
    - uses: actions/checkout@v2
    - name: Configure cmake
      run: |
        mkdir build
        cd build
        cmake ..
    - name: Build nghttp2
      run: |
        cmake --build build
