name: Build
on: [push, pull_request]

jobs:
  build-linux:
    strategy:
      matrix:
        compiler: [gcc, clang]
        arch: [i386, amd64]
        config: [Debug, Release]
        dllver: ['0x502', '0x600']
        exclude:
          - dllver: 0x600
            compiler: clang
          - dllver: 0x600
            config: Release
      fail-fast: false
    runs-on: ubuntu-22.04
    steps:
    - name: Get RosBE build specifics
      id: get_rosbe_spec
      run: |
        # Print actual cpu-type option only.
        echo -march = $(gcc -march=native -Q --help=target | grep "\-march=  " | awk '{print $NF}')
        # Take all options/text into account.
        echo march-sha=$(gcc -march=native -Q --help=target | sha1sum | awk '{print $1}') >> $GITHUB_OUTPUT
        echo git-sha=$(git ls-remote https://github.com/zefklop/RosBE.git | grep unix_amd64 | awk '{print $1}') >> $GITHUB_OUTPUT
        wget https://gist.githubusercontent.com/zefklop/b2d6a0b470c70183e93d5285a03f5899/raw/build_rosbe_ci.sh
        # Fallback for GNU file server problems.
        sed -i '/gcc-8.4.0\/gcc-8.4.0.tar.xz/c\wget https://ftpmirror.gnu.org/gcc/gcc-8.4.0/gcc-8.4.0.tar.xz || wget -L https://web.archive.org/web/2025if_/https://ftpmirror.gnu.org/gcc/gcc-8.4.0/gcc-8.4.0.tar.xz' ./build_rosbe_ci.sh
    - name: Get RosBE
      id: get_rosbe
      uses: actions/cache@v5
      with:
        path: RosBE-CI
        key: RosBE-CI-${{runner.os}}-${{steps.get_rosbe_spec.outputs.march-sha}}-${{steps.get_rosbe_spec.outputs.git-sha}}-${{hashfiles('./build_rosbe_ci.sh')}}
    - name: Compile RosBE
      if: ${{ steps.get_rosbe.outputs.cache-hit != 'true' }}
      run: |
        chmod +x build_rosbe_ci.sh
        ./build_rosbe_ci.sh ${{github.workspace}}/RosBE-CI
    - name: Install ccache
      run: sudo apt install ccache
    - name: Install LLVM
      if: ${{ matrix.compiler == 'clang' }}
      run: |
        export LLVM_VERSION=13
        wget https://apt.llvm.org/llvm.sh
        chmod +x llvm.sh
        sudo ./llvm.sh $LLVM_VERSION
        echo "D_CLANG_VERSION=-DCLANG_VERSION=$LLVM_VERSION" >> $GITHUB_ENV
    - name: Source checkout
      uses: actions/checkout@v6
      with:
        path: src
    - name: Set up cache for ccache
      uses: actions/cache@v5
      with:
        path: ccache
        key: ccache-${{matrix.compiler}}-${{matrix.arch}}-${{matrix.config}}-${{matrix.dllver}}-${{github.sha}}
        restore-keys: |
          ccache-${{matrix.compiler}}-${{matrix.arch}}-${{matrix.config}}-${{matrix.dllver}}-
    - name: Set ccache settings
      run: |
        echo "CCACHE_BASEDIR=${{github.workspace}}" >> $GITHUB_ENV
        echo "CCACHE_DIR=${{github.workspace}}/ccache" >> $GITHUB_ENV
        echo "CCACHE_MAXSIZE=1G" >> $GITHUB_ENV
        echo "CCACHE_SLOPPINESS=time_macros" >> $GITHUB_ENV
    - name: Configure problem matchers
      run: echo ::add-matcher::src/.github/workflows/problem-matcher.json
    - name: Ease ccache compiler check (GCC)
      if: ${{ matrix.compiler == 'gcc' }}
      run: echo "CCACHE_COMPILERCHECK=string:${{steps.get_rosbe_spec.outputs.git-sha}}-${{hashfiles('./build_rosbe_ci.sh')}}" >> $GITHUB_ENV
    - name: Configure
      run: echo 'cmake -S ${{github.workspace}}/src -B ${{github.workspace}}/build -G Ninja -DCMAKE_TOOLCHAIN_FILE:FILEPATH=toolchain-${{matrix.compiler}}.cmake -DARCH:STRING=${{matrix.arch}} -DCMAKE_BUILD_TYPE=${{matrix.config}} -DDLL_EXPORT_VERSION=${{matrix.dllver}} -DENABLE_CCACHE=1 -DENABLE_ROSTESTS=1 -DENABLE_ROSAPPS=1 ${{env.D_CLANG_VERSION}}' | ${{github.workspace}}/RosBE-CI/RosBE.sh . 0 ${{matrix.arch}}
    # GCC and Clang use relative file paths for error messages, use sed to convert these to absolute paths so that GitHub could parse them
    - name: Build
      run: set -o pipefail && echo 'cmake --build ${{github.workspace}}/build -- -k0' | ${{github.workspace}}/RosBE-CI/RosBE.sh . 0 ${{matrix.arch}} 2>&1 | sed 's|^\.\./src/|${{github.workspace}}/src/|'
    - name: Generate ISOs
      run: echo 'cmake --build ${{github.workspace}}/build --target bootcd' | ${{github.workspace}}/RosBE-CI/RosBE.sh . 0 ${{matrix.arch}}
    - name: Print ccache statistics
      run: ccache -s
    - name: Upload ISOs
      uses: actions/upload-artifact@v7
      with:
        name: reactos-${{matrix.compiler}}-${{matrix.arch}}-${{matrix.config}}-${{matrix.dllver}}-${{github.sha}}
        path: |
          build/bootcd.iso

  build-msvc:
    strategy:
      matrix:
        os: [windows-latest]
        toolset: ['14','14.2'] # VS 2022, and 2019 (see below)
        arch: [i386, amd64]
        config: [Debug, Release]
        dllver: ['0x502', '0x600']
        exclude: # Build NT6 ISOs only with the latest toolset when compiled as a debug build
          - dllver: 0x600
            toolset: 14.2
          - dllver: 0x600
            config: Release
      fail-fast: false
    runs-on: ${{matrix.os}}
    steps:
    - name: Install ninja
      run: choco install -y ninja
    - name: Install Flex & Bison
      run: |
        curl -O https://svn.reactos.org/storage/vperevertkin/flexbison.7z || curl -OL https://web.archive.org/web/2025if_/https://svn.reactos.org/storage/vperevertkin/flexbison.7z
        7z x flexbison.7z -O${{github.workspace}}\bin
        echo "${{github.workspace}}\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
        echo "BISON_PKGDATADIR=${{github.workspace}}\bin\share\bison" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
        echo "M4=${{github.workspace}}\bin\m4.exe" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
    - name: Activate VS cmd (x86)
      if: ${{ matrix.arch == 'i386' }}
      uses: ilammy/msvc-dev-cmd@v1
      with:
        arch: amd64_x86
        toolset: ${{matrix.toolset}}
    - name: Activate VS cmd (amd64)
      if: ${{ matrix.arch == 'amd64' }}
      uses: ilammy/msvc-dev-cmd@v1
      with:
        arch: amd64
        toolset: ${{matrix.toolset}}
    - name: Source checkout
      uses: actions/checkout@v6
      with:
        path: src
    - name: Configure problem matchers
      run: echo ::add-matcher::src/.github/workflows/problem-matcher.json
    - name: Configure
      run: cmake -S src -B build -G Ninja -DCMAKE_TOOLCHAIN_FILE:FILEPATH=toolchain-msvc.cmake -DARCH:STRING=${{matrix.arch}} -DCMAKE_BUILD_TYPE=${{matrix.config}} -DDLL_EXPORT_VERSION=${{matrix.dllver}} -DENABLE_ROSTESTS=1 -DENABLE_ROSAPPS=1
    - name: Build
      run: cmake --build build -- -k0
    - name: Generate ISOs
      run: cmake --build build --target bootcd
    - name: Upload ISOs
      uses: actions/upload-artifact@v7
      with:
        name: reactos-msvc${{matrix.toolset}}-${{matrix.arch}}-${{matrix.config}}-${{matrix.dllver}}-${{github.sha}}
        path: |
          build/bootcd.iso
    - name: Upload debug symbols
      if: ${{ matrix.config == 'Debug' }}
      uses: actions/upload-artifact@v7
      with:
        name: reactos-syms-msvc${{matrix.toolset}}-${{matrix.arch}}-${{matrix.config}}-${{matrix.dllver}}-${{github.sha}}
        path: build/msvc_pdb

  build-msvc-arm:
    strategy:
      matrix:
        os: [windows-2022, windows-latest]
        toolset: ['14', '14.29'] # VS 2022 (ongoing), 2019 (last)
        arch: [arm, arm64]
        config: [Debug, Release]
        exclude:
          # arm64: windows-latest is enough/fine.
          - os: windows-2022
            arch: arm64
          # arm (sdk): only available on windows-2022.
          - os: windows-latest
            arch: arm
      fail-fast: false
    runs-on: ${{matrix.os}}
    steps:
    - name: Install ninja
      run: choco install -y ninja
    - name: Install Flex & Bison
      run: |
        curl -O https://svn.reactos.org/storage/vperevertkin/flexbison.7z || curl -OL https://web.archive.org/web/2025if_/https://svn.reactos.org/storage/vperevertkin/flexbison.7z
        7z x flexbison.7z -O${{github.workspace}}\bin
        echo "${{github.workspace}}\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
        echo "BISON_PKGDATADIR=${{github.workspace}}\bin\share\bison" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
        echo "M4=${{github.workspace}}\bin\m4.exe" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
    - name: Activate VS cmd (arm)
      if: ${{ matrix.arch == 'arm' }}
      uses: ilammy/msvc-dev-cmd@v1
      with:
        arch: amd64_arm
        sdk: 10.0.22621.0   # Windows SDK 10.0.26100.0 dropped support for 32-bit ARM
        toolset: ${{matrix.toolset}}
    - name: Activate VS cmd (arm64)
      if: ${{ matrix.arch == 'arm64' }}
      uses: ilammy/msvc-dev-cmd@v1
      with:
        arch: amd64_arm64
        toolset: ${{matrix.toolset}}
    - name: Source checkout
      uses: actions/checkout@v6
      with:
        path: src
    - name: Configure problem matchers
      run: echo ::add-matcher::src/.github/workflows/problem-matcher.json
    - name: Configure
      run: cmake -S src -B build -G Ninja -DCMAKE_TOOLCHAIN_FILE:FILEPATH=toolchain-msvc.cmake -DARCH:STRING=${{matrix.arch}} -DCMAKE_BUILD_TYPE=${{matrix.config}} -DENABLE_ROSTESTS=1 -DENABLE_ROSAPPS=1
    - name: Build base module
      if: ${{ matrix.arch == 'arm' }}
      run: cmake --build build --target base/all
    - name: Build dll:3rdparty
      if: ${{ matrix.arch == 'arm' }}
      run: cmake --build build --target dll/3rdparty/all -- -k0
    - name: Build control panel applets
      if: ${{ matrix.arch == 'arm' }}
      run: cmake --build build --target dll/cpl/all
    - name: Build dll:opengl
      if: ${{ matrix.arch == 'arm' }}
      run: cmake --build build --target dll/opengl/all -- -k0
    - name: Build dll:shellext
      if: ${{ matrix.arch == 'arm' }}
      run: cmake --build build --target dll/shellext/all -- -k0
    - name: Build drivers:base
      if: ${{ matrix.arch == 'arm' }}
      run: cmake --build build --target drivers/base/all -- -k0
    - name: Build rosapps
      if: ${{ matrix.arch == 'arm' }}
      run: cmake --build build --target modules/rosapps/all
    - name: Build subsystems
      if: ${{ matrix.arch == 'arm' }}
      run: cmake --build build --target subsystems/all
    - name: Build some applications (arm64)
      if: ${{ matrix.arch == 'arm64' }}
      run: cmake --build build --target calc magnify mstsc notepad osk regedit taskmgr winmine wordpad base/applications/screensavers/all -- -k0
    - name: Build control panel applets (arm64)
      if: ${{ matrix.arch == 'arm64' }}
      run: cmake --build build --target dll/cpl/all -- -k0
    - name: Upload compiled binaries
      uses: actions/upload-artifact@v7
      with:
        name: reactos-msvc${{matrix.toolset}}-${{matrix.arch}}-${{matrix.config}}-${{github.sha}}
        path: |
          build/base
          build/dll/3rdparty
          build/dll/cpl
          build/dll/opengl
          build/dll/shellext
          build/drivers/base
          build/modules/rosapps
          build/subsystems
          !**/CMakeFiles
          !**/cmake_install.cmake
          !**/*.asm
          !**/*.bin
          !**/*.c
          !**/*.def
          !**/*.exp
          !**/*.h
          !**/*.lib
          !**/*.mc
          !**/*.obj
          !**/*.rc
          !**/*.tlb
    - name: Upload debug symbols
      if: ${{ matrix.config == 'Debug' }}
      uses: actions/upload-artifact@v7
      with:
        name: reactos-syms-msvc${{matrix.toolset}}-${{matrix.arch}}-${{matrix.config}}-${{github.sha}}
        path: build/msvc_pdb

  # FIXME: Does not boot on toolset 14.1, 14.3+ is untested
  build-clang-cl:
    strategy:
      matrix:
        arch: [i386, amd64]
        config: [Debug, Release]
      fail-fast: false
    runs-on: windows-latest
    steps:
    - name: Install ninja
      run: choco install -y ninja
    - name: Install LLVM
      run: |
        choco install -y --allow-downgrade llvm --version 13.0.1
        echo "LLVM_PATH=${env:PROGRAMFILES}\llvm\bin" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
    - name: Install Flex & Bison
      run: |
        curl -O https://svn.reactos.org/storage/vperevertkin/flexbison.7z || curl -OL https://web.archive.org/web/2025if_/https://svn.reactos.org/storage/vperevertkin/flexbison.7z
        7z x flexbison.7z -O${{github.workspace}}\bin
        echo "${{github.workspace}}\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
        echo "BISON_PKGDATADIR=${{github.workspace}}\bin\share\bison" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
        echo "M4=${{github.workspace}}\bin\m4.exe" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
    - name: Activate VS cmd (x86)
      if: ${{ matrix.arch == 'i386' }}
      uses: ilammy/msvc-dev-cmd@v1
      with:
        arch: amd64_x86
        toolset: '14'
    - name: Activate VS cmd (amd64)
      if: ${{ matrix.arch == 'amd64' }}
      uses: ilammy/msvc-dev-cmd@v1
      with:
        arch: amd64
        toolset: '14'
    - name: Add LLVM to PATH
      run: echo "${env:LLVM_PATH}" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
    - name: Source checkout
      uses: actions/checkout@v6
      with:
        path: src
    - name: Configure problem matchers
      run: echo ::add-matcher::src/.github/workflows/problem-matcher.json
    - name: Configure
      run: cmake -S src -B build -G Ninja -DCMAKE_TOOLCHAIN_FILE:FILEPATH=toolchain-msvc.cmake -DARCH:STRING=${{matrix.arch}} -DCMAKE_BUILD_TYPE=${{matrix.config}} -DENABLE_ROSTESTS=1 -DENABLE_ROSAPPS=1 -DUSE_CLANG_CL:BOOL=TRUE
    - name: Build
      run: cmake --build build -- -k0
    - name: Generate ISOs
      run: cmake --build build --target bootcd
    - name: Upload ISOs
      uses: actions/upload-artifact@v7
      with:
        name: reactos-clang-cl-${{matrix.arch}}-${{matrix.config}}-${{github.sha}}
        path: |
          build/bootcd.iso
    - name: Upload debug symbols
      if: ${{ matrix.config == 'Debug' }}
      uses: actions/upload-artifact@v7
      with:
        name: reactos-syms-clang-cl-${{matrix.arch}}-${{matrix.config}}-${{github.sha}}
        path: build/msvc_pdb

  build-msbuild-i386:
    name: MSBuild (i386)
    runs-on: windows-latest
    steps:
    - name: Install Flex and Bison
      run: |
        curl -O https://svn.reactos.org/storage/vperevertkin/flexbison.7z || curl -OL https://web.archive.org/web/2025if_/https://svn.reactos.org/storage/vperevertkin/flexbison.7z
        7z x flexbison.7z -O${{github.workspace}}\bin
        echo "${{github.workspace}}\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
        echo "BISON_PKGDATADIR=${{github.workspace}}\bin\share\bison" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
        echo "M4=${{github.workspace}}\bin\m4.exe" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
    - name: Add CL to PATH
      uses: ilammy/msvc-dev-cmd@v1
      with:
        arch: amd64_x86
    - uses: actions/checkout@v6
      with:
        path: src
    - name: Configure problem matchers
      run: echo ::add-matcher::src/.github/workflows/problem-matcher.json
    - name: Configure
      run: |
        mkdir build
        cd build
        $GENERATOR = "Visual Studio 17 2022"
        if ($env:VisualStudioVersion -ge "18") { $GENERATOR = "Visual Studio 18 2026" }
        cmake -G $GENERATOR -A Win32 -DCMAKE_TOOLCHAIN_FILE:FILEPATH=toolchain-msvc.cmake -DARCH:STRING=i386 -DENABLE_ROSTESTS=1 -DENABLE_ROSAPPS=1 ${{github.workspace}}\src
    - name: Build
      run: cmake --build ${{github.workspace}}\build --target bootcd