name: "Build"
on:
  push:
  pull_request:

concurrency:
  group: ${{github.ref}}
  cancel-in-progress: ${{github.ref != 'refs/heads/master'}}

defaults:
  run:
    shell: bash

jobs:
  source-check:
    name: "source check"
    runs-on: ubuntu-latest

    steps:
    - name: "Checkout"
      uses: actions/checkout@v4

    - name: "Setup node.js"
      uses: actions/setup-node@v4
      with:
        node-version: "*"

    - name: "Check Enumerations"
      run: |
        cd tools
        node enumgen.js --verify

  build:
    strategy:
      fail-fast: false
      matrix:
        include:
          - { title: "diag-analyze"    , host: "ubuntu-latest" , arch: "x64"    , cc: "clang-18", conf: "Debug"  , diagnostics: "analyze-build" }
          - { title: "diag-asan"       , host: "ubuntu-latest" , arch: "x64"    , cc: "clang-18", conf: "Release", diagnostics: "asan", defs: "ASMJIT_TEST=1" }
          - { title: "diag-msan"       , host: "ubuntu-latest" , arch: "x64"    , cc: "clang-18", conf: "Release", diagnostics: "msan", defs: "ASMJIT_TEST=1" }
          - { title: "diag-ubsan"      , host: "ubuntu-latest" , arch: "x64"    , cc: "clang-18", conf: "Release", diagnostics: "ubsan", defs: "ASMJIT_TEST=1" }
          - { title: "diag-hardened"   , host: "ubuntu-latest" , arch: "x64"    , cc: "clang-18", conf: "Release", diagnostics: "hardened", defs: "ASMJIT_TEST=1" }
          - { title: "diag-valgrind"   , host: "ubuntu-24.04"  , arch: "x64"    , cc: "clang-18", conf: "Release", diagnostics: "valgrind", defs: "ASMJIT_TEST=1" }

          - { title: "no-deprecated"   , host: "ubuntu-latest" , arch: "x64"    , cc: "clang-18", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_DEPRECATED=1" }
          - { title: "no-intrinsics"   , host: "ubuntu-latest" , arch: "x64"    , cc: "clang-18", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_INTRINSICS=1" }
          - { title: "no-logging"      , host: "ubuntu-latest" , arch: "x64"    , cc: "clang-18", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_LOGGING=1" }
          - { title: "no-logging-text" , host: "ubuntu-latest" , arch: "x64"    , cc: "clang-18", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_LOGGING=1,ASMJIT_NO_TEXT=1" }
          - { title: "no-builder"      , host: "ubuntu-latest" , arch: "x64"    , cc: "clang-18", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_BUILDER=1" }
          - { title: "no-compiler"     , host: "ubuntu-latest" , arch: "x64"    , cc: "clang-18", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_COMPILER=1" }
          - { title: "no-introspection", host: "ubuntu-latest" , arch: "x64"    , cc: "clang-18", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_COMPILER=1,ASMJIT_NO_INTROSPECTION=1" }
          - { title: "no-jit"          , host: "ubuntu-latest" , arch: "x64"    , cc: "clang-18", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_JIT=1" }
          - { title: "no-validation"   , host: "ubuntu-latest" , arch: "x64"    , cc: "clang-18", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_VALIDATION=1" }
          - { title: "no-x86"          , host: "ubuntu-latest" , arch: "x64"    , cc: "clang-18", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_X86=1" }
          - { title: "no-aarch64"      , host: "ubuntu-latest" , arch: "x64"    , cc: "clang-18", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_AARCH64=1" }

          - { title: "lang-c++17"      , host: "ubuntu-latest" , arch: "x64"    , cc: "clang-18", conf: "Debug"  , defs: "ASMJIT_TEST=1,CMAKE_CXX_FLAGS=-std=c++17" }
          - { title: "lang-c++20"      , host: "ubuntu-latest" , arch: "x64"    , cc: "clang-18", conf: "Debug"  , defs: "ASMJIT_TEST=1,CMAKE_CXX_FLAGS=-std=c++20" }
          - { title: "lang-c++23"      , host: "ubuntu-latest" , arch: "x64"    , cc: "clang-18", conf: "Debug"  , defs: "ASMJIT_TEST=1,CMAKE_CXX_FLAGS=-std=c++23" }

          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "gcc-9"   , conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "gcc-9"   , conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "gcc-9"   , conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "gcc-9"   , conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "gcc-10"  , conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "gcc-10"  , conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "gcc-10"  , conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "gcc-10"  , conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "gcc-11"  , conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "gcc-11"  , conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "gcc-11"  , conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "gcc-11"  , conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "gcc-12"  , conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "gcc-12"  , conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "gcc-12"  , conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "gcc-12"  , conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "gcc-13"  , conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "gcc-13"  , conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "gcc-13"  , conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "gcc-13"  , conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "clang-11", conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "clang-11", conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "clang-11", conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "clang-11", conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "clang-12", conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "clang-12", conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "clang-12", conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "clang-12", conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "clang-13", conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "clang-13", conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "clang-13", conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "clang-13", conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "clang-14", conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "clang-14", conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "clang-14", conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "clang-14", conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "clang-15", conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "clang-15", conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "clang-15", conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "clang-15", conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "clang-16", conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "clang-16", conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "clang-16", conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "clang-16", conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "clang-17", conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "clang-17", conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "clang-17", conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "clang-17", conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "clang-18", conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x86"    , cc: "clang-18", conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "clang-18", conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "linux"           , host: "ubuntu-22.04"  , arch: "x64"    , cc: "clang-18", conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "macos"           , host: "macos-13"      , arch: "x64"    , cc: "gcc-14"  , conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "macos"           , host: "macos-13"      , arch: "x64"    , cc: "gcc-14"  , conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "macos"           , host: "macos-13"      , arch: "x64"    , cc: "clang"   , conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "macos"           , host: "macos-13"      , arch: "x64"    , cc: "clang"   , conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "macos"           , host: "macos-14"      , arch: "arm64"  , cc: "clang"   , conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "macos"           , host: "macos-14"      , arch: "arm64"  , cc: "clang"   , conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "windows"         , host: "windows-2019"  , arch: "x86"    , cc: "vs2019"  , conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "windows"         , host: "windows-2019"  , arch: "x86"    , cc: "vs2019"  , conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "windows"         , host: "windows-2019"  , arch: "x64"    , cc: "vs2019"  , conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "windows"         , host: "windows-2019"  , arch: "x64"    , cc: "vs2019"  , conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "windows"         , host: "windows-2022"  , arch: "x86"    , cc: "vs2022"  , conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "windows"         , host: "windows-2022"  , arch: "x86"    , cc: "vs2022"  , conf: "Release", defs: "ASMJIT_TEST=1" }
          - { title: "windows"         , host: "windows-2022"  , arch: "x64"    , cc: "vs2022"  , conf: "Debug"  , defs: "ASMJIT_TEST=1" }
          - { title: "windows"         , host: "windows-2022"  , arch: "x64"    , cc: "vs2022"  , conf: "Release", defs: "ASMJIT_TEST=1" }

          # Cross compiled, cannot run tests (Windows/ARM64).
          - { title: "windows"         , host: "windows-2022"  , arch: "arm64"  , cc: "vs2022"  , conf: "Debug"  , defs: "ASMJIT_TEST=0" }
          - { title: "windows"         , host: "windows-2022"  , arch: "arm64"  , cc: "vs2022"  , conf: "Release", defs: "ASMJIT_TEST=0" }

          # Cross compiled, cannot run tests (Windows/UWP).
          - { title: "windows/uwp"     , host: "windows-2022"  , arch: "x64"    , cc: "vs2022"  , conf: "Release", defs: "ASMJIT_TEST=0,CMAKE_SYSTEM_NAME=WindowsStore,CMAKE_SYSTEM_VERSION=10.0,CMAKE_CXX_FLAGS=-D_WIN32_WINNT=0x0A00" }

          - { title: "freebsd"         , host: "ubuntu-latest" , arch: "x64"    , cc: "clang"   , conf: "Release", vm: "freebsd", vm_ver: "14.1", defs: "ASMJIT_TEST=1" }
          - { title: "freebsd"         , host: "ubuntu-latest" , arch: "arm64"  , cc: "clang"   , conf: "Release", vm: "freebsd", vm_ver: "14.1", defs: "ASMJIT_TEST=1" }
          - { title: "netbsd"          , host: "ubuntu-latest" , arch: "x64"    , cc: "clang"   , conf: "Release", vm: "netbsd" , vm_ver: "10.0", defs: "ASMJIT_TEST=1" }
          - { title: "netbsd"          , host: "ubuntu-latest" , arch: "arm64"  , cc: "clang"   , conf: "Release", vm: "netbsd" , vm_ver: "10.0", defs: "ASMJIT_TEST=1" }
          - { title: "openbsd"         , host: "ubuntu-latest" , arch: "x64"    , cc: "clang"   , conf: "Release", vm: "openbsd", vm_ver: "7.4" , defs: "ASMJIT_TEST=1" }
          - { title: "openbsd"         , host: "ubuntu-latest" , arch: "arm64"  , cc: "clang"   , conf: "Release", vm: "openbsd", vm_ver: "7.4" , defs: "ASMJIT_TEST=1" }

          - { title: "debian"          , host: "ubuntu-latest" , arch: "arm/v7" , cc: "clang"   , conf: "Release", vm: "debian:unstable", defs: "ASMJIT_TEST=1" }
          - { title: "debian"          , host: "ubuntu-latest" , arch: "arm64"  , cc: "clang"   , conf: "Release", vm: "debian:unstable", defs: "ASMJIT_TEST=1" }
          - { title: "debian"          , host: "ubuntu-latest" , arch: "riscv64", cc: "clang"   , conf: "Release", vm: "debian:unstable", defs: "ASMJIT_TEST=1" }
          - { title: "debian"          , host: "ubuntu-latest" , arch: "ppc64le", cc: "clang"   , conf: "Release", vm: "debian:unstable", defs: "ASMJIT_TEST=1" }

    name: "${{matrix.title}}/${{matrix.arch}}, ${{matrix.cc}} ${{matrix.conf}}"
    runs-on: "${{matrix.host}}"

    steps:
      - name: "Checkout"
        uses: actions/checkout@v4
        with:
          path: "source"

      - name: "Checkout Build Actions"
        uses: actions/checkout@v4
        with:
          repository: build-actions/build-actions
          path: "build-actions"

      - name: "Python"
        uses: actions/setup-python@v5
        with:
          python-version: "3.x"

      - name: QEMU
        if: ${{matrix.vm && !matrix.vm_ver}}
        uses: docker/setup-qemu-action@v3
        with:
          platforms: linux/${{matrix.arch}}

      - name: "Build & Test - Native"
        if: ${{!matrix.vm}}
        run: python build-actions/action.py
               --source-dir=source
               --config=source/.github/workflows/build-config.json
               --compiler=${{matrix.cc}}
               --diagnostics=${{matrix.diagnostics}}
               --architecture=${{matrix.arch}}
               --problem-matcher=auto
               --build-type=${{matrix.conf}}
               --build-defs=${{matrix.defs}}

      - name: "Build & Test - Cross Platform Actions"
        if: ${{matrix.vm && matrix.vm_ver}}
        uses: cross-platform-actions/action@master
        with:
          operating_system: ${{matrix.vm}}
          architecture: ${{matrix.arch}}
          version: ${{matrix.vm_ver}}
          sync_files: "runner-to-vm"
          shutdown_vm: false
          shell: bash
          run: |
            set -e

            PATH="/usr/sbin:/usr/pkg/sbin:/usr/pkg/bin:$PATH:$(pwd)/build-actions"
            CI_NETBSD_USE_PKGIN=1

            export PATH
            export CI_NETBSD_USE_PKGIN

            sh ./build-actions/prepare-environment.sh
            python3 build-actions/action.py                        \
              --source-dir=source                                  \
              --config=source/.github/workflows/build-config.json  \
              --compiler=${{matrix.cc}}                            \
              --diagnostics=${{matrix.diagnostics}}                \
              --architecture=${{matrix.arch}}                      \
              --problem-matcher=auto                               \
              --build-type=${{matrix.conf}}                        \
              --build-defs=${{matrix.defs}}

      - name: "Build & Test - Docker + QEMU"
        if: ${{matrix.vm && !matrix.vm_ver}}
        run: |
          docker run                                               \
            --rm                                                   \
            -v $(pwd):/${{github.workspace}}                       \
            -w ${{github.workspace}}/build-actions                 \
            --platform linux/${{matrix.arch}}                      \
            ${{matrix.vm}}                                         \
            bash action.sh                                         \
            --source-dir=../source                                 \
            --config=../source/.github/workflows/build-config.json \
            --compiler=${{matrix.cc}}                              \
            --diagnostics=${{matrix.diagnostics}}                  \
            --architecture=${{matrix.arch}}                        \
            --problem-matcher=auto                                 \
            --build-type=${{matrix.conf}}                          \
            --build-defs=${{matrix.defs}}
