name: Linux builds

on:
  push:
    paths-ignore:
      - '.clang-format'
      - '.mdl-styles'
      - '*.md'
      - 'docs/**'
      - 'licenses/**'
      - 'website/**'

  pull_request:
    paths-ignore:
      - '.clang-format'
      - '.mdl-styles'
      - '*.md'
      - 'docs/**'
      - 'licenses/**'
      - 'website/**'

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  cache_subprojects:
    name: Cache subprojects
    runs-on: ubuntu-latest
    if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          submodules: false

      - name: Install Meson
        run:  |
          export DEBIAN_FRONTEND=noninteractive
          sudo apt-get update
          sudo apt-get install -y python3-setuptools
          sudo pip3 install --upgrade meson

      - name: Cache subprojects
        id:   cache-subprojects
        uses: actions/cache@v4
        with:
          path: subprojects.tar
          key: subprojects-${{ hashFiles('subprojects/*.wrap') }}-1
          enableCrossOsArchive: true

      - if:   steps.cache-subprojects.outputs.cache-hit != 'true'
        name: Generate subprojects cache
        run:  scripts/fetch-and-tar-subprojects.sh

  build_ubuntu:
    name: ${{ matrix.conf.name }} ${{ matrix.arch }}
    runs-on: ${{ matrix.conf.os }}${{ matrix.arch == 'arm64' && '-arm' || '' }}
    if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
    needs: cache_subprojects
    strategy:
      matrix:
        arch: [x64, arm64]
        conf:

          - name: GCC 12, Ubuntu 22.04
            os: ubuntu-22.04
            packages: g++-12
            build_flags: -Dbuildtype=debug --native-file=.github/meson/native-gcc-12.ini
            max_warnings: 1000
            needs_all_deps: true
            run_tests: true

          - name: Clang 15, Ubuntu 22.04
            os: ubuntu-22.04
            packages: clang-15
            build_flags: -Dbuildtype=debug --native-file=.github/meson/native-clang-15.ini
            max_warnings: 1000
            needs_all_deps: true
            run_tests: true

          - name: GCC 12, Ubuntu 22.04, debugger build
            os: ubuntu-22.04
            packages: g++-12
            build_flags: -Denable_debugger=heavy --native-file=.github/meson/native-gcc-12.ini
            max_warnings: 1000
            needs_all_deps: true

          - name: GCC 11, Ubuntu 22.04, minimal build
            os: ubuntu-22.04
            build_flags: >-
              -Dbuildtype=minsize
              -Dunit_tests=disabled
              -Duse_alsa=false
              -Duse_fluidsynth=false
              -Duse_mt32emu=false
              -Duse_opengl=false
              -Duse_sdl2_net=false
              -Duse_slirp=false
            needs_min_deps: true
            max_warnings: 1000

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          submodules: false
      
      - name: Install minimum dependencies
        if:  matrix.conf.needs_min_deps
        run: |
          export DEBIAN_FRONTEND=noninteractive
          sudo apt-get update
          sudo apt-get install -y build-essential libsdl2-dev libopusfile-dev libspeexdsp-dev python3-setuptools
          sudo pip3 install --upgrade meson ninja
      
      - name: Install all dependencies
        if:   matrix.conf.needs_all_deps
        run: |
          export DEBIAN_FRONTEND=noninteractive
          sudo apt-get update
          sudo apt-get install -y \
            ${{ matrix.conf.packages }} \
            $(cat packages/${{ matrix.conf.os }}-apt.txt)
          sudo pip3 install --upgrade meson ninja

      - name: Log environment
        run:  ./scripts/log-env.sh
     
      - name: Restore subprojects cache
        id:   cache-subprojects
        uses: actions/cache@v4
        with:
          path: subprojects.tar
          key: subprojects-${{ hashFiles('subprojects/*.wrap') }}-1
          enableCrossOsArchive: true

      - name: Extract subprojects cache
        run:  scripts/extract-subprojects-tar.sh

      - name: Meson setup
        run:  |
          meson setup ${{ matrix.conf.build_flags }} build \
          || ( cat build/meson-logs/meson-log.txt ; exit 1 )

      - name: Build
        run: |
          set -xo pipefail
          meson compile -C build |& tee build.log

      - name: Run tests
        if:   matrix.conf.run_tests
        run:  meson test --num-processes 128 -t 0 -C build --print-errorlogs

      - name: Summarize warnings
        env:
          MAX_WARNINGS: ${{ matrix.conf.max_warnings }}
        run:  ./scripts/count-warnings.py -lf build.log


  build_linux_release:
    name: Release build
    runs-on: ubuntu-22.04
    if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
    needs: cache_subprojects
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          submodules: false

      - run:  sudo apt-get update

      - name: Install dependencies
        run: |
          sudo apt-get install -y tree \
            $(cat packages/ubuntu-22.04-apt.txt)
          sudo pip3 install --upgrade meson ninja

      - name: Restore subprojects cache
        id:   cache-subprojects
        uses: actions/cache@v4
        with:
          path: subprojects.tar
          key: subprojects-${{ hashFiles('subprojects/*.wrap') }}-1
          enableCrossOsArchive: true

      - name: Extract subprojects cache
        run:  scripts/extract-subprojects-tar.sh

      - name: Log environment
        run:  ./scripts/log-env.sh

      - name: Inject version string
        run: |
          set -x
          VERSION=$(./scripts/get-version.sh version-and-hash)
          echo "VERSION=$VERSION" >> $GITHUB_ENV

      - name: Setup release build
        run: |
          meson setup \
            -Duse_xinput2=false \
            -Duse_zlib_ng=sse2,ssse3,neon \
            -Ddefault_library=static \
            --wrap-mode=forcefallback \
            -Db_lto=true -Db_lto_threads=$(nproc) \
            build \
          || ( cat build/meson-logs/meson-log.txt ; exit 1 )


      - name: Build
        run:  meson compile -C build

      - name: Package
        run: |
          ./scripts/create-package.sh \
            -p linux \
            build \
            "dosbox-staging-linux-x86_64-$VERSION"

      - name: Create tarball
        run: |
          tar -cJf "dosbox-staging-linux-x86_64-$VERSION.tar.xz" \
            "dosbox-staging-linux-x86_64-$VERSION"

      - name: Upload tarball
        uses: actions/upload-artifact@v4.3.1
        # GitHub automatically zips the artifacts (there's no way to create
        # a tarball), and it removes all executable flags while zipping.
        # Letting it zip a tarball preserves flags in the compressed files.
        with:
          name: dosbox-staging-linux-x86_64-${{ env.VERSION }}
          path: dosbox-staging-linux-x86_64-${{ env.VERSION }}.tar.xz
