name: Build UC2

on: 
  push:
    paths-ignore:
      - ".gitignore"
      - "docs/**"
      - "README"
      - "CREDITS.TXT"
      - "COPYING_GLIB"
      - "COPYING.LGPL2"
      - "AUTHORS.TXT"
      - "CHANGELOG"
      - "COPYING"
  pull_request:


env:
  CI: true

jobs:
  Windows:
    runs-on: ${{ matrix.config.os }}
    name: ${{ matrix.config.name }}
    strategy:
      fail-fast: false
      matrix:
        config:
          - { 
              os: windows-latest,
              arch: x64,
              python-arch: x64,
              python-ver: '3.8',
              name: 'windows-x64 MINGW64',
              mingw: MINGW64,
              mingw-arch: x86_64,
              artifact: 'windows_mingw64.7z',
              build_type: 'Debug',
              archiver: '7z a',
              generators: 'Ninja'
            }
          - { 
              os: windows-latest,
              arch: x64,
              python-arch: x64,
              python-ver: '3.8',
              name: 'windows-x64 MINGW32',
              mingw: MINGW32,
              mingw-arch: i686,
              artifact: 'windows_mingw32.7z',
              build_type: 'Debug',
              archiver: '7z a',
              generators: 'Ninja'
            }
          - { 
              os: windows-latest,
              arch: x64,
              python-arch: x64,
              python-ver: '3.8',
              name: 'windows-x64 MSVC 64bit',
              msvc-arch: x64,
              artifact: 'windows_msvc64.7z',
              build_type: 'Debug',
              archiver: '7z a',
              generators: 'Visual Studio 16 2019'
            }
          - { 
              os: windows-latest,
              arch: x86,
              python-arch: x86,
              python-ver: '3.8',
              name: 'windows-x86 MSVC 32bit',
              msvc-arch: x86,
              artifact: 'windows_msvc32.7z',
              build_type: 'Debug',
              archiver: '7z a',
              generators: 'Visual Studio 16 2019'
            }
        compiler: [ gcc ]
    steps:
    - uses: actions/checkout@v2

    - name: '🛠️ Win MINGW setup'
      if: contains(matrix.config.mingw, 'MINGW')
      uses: msys2/setup-msys2@v2
      with:
        msystem: ${{ matrix.config.mingw }}
        install: >-
          git
          mingw-w64-${{ matrix.config.mingw-arch }}-cmake
          mingw-w64-${{ matrix.config.mingw-arch }}-ninja
          mingw-w64-${{ matrix.config.mingw-arch }}-cmocka
          mingw-w64-${{ matrix.config.mingw-arch }}-${{ matrix.compiler }}
          mingw-w64-${{ matrix.config.mingw-arch }}-toolchain

    - name: '🛠️ Win MSVC 64 setup'
      if: contains(matrix.config.name, 'MSVC 64')
      uses: microsoft/setup-msbuild@v1

    - name: '🚧 Win MSVC 64 build'
      if: contains(matrix.config.name, 'MSVC 64')
      shell: bash
      run: |
        choco install ninja cmake
        ninja --version
        cmake --version
        mkdir build
        cmake \
          -S . \
          -B . \
          -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
          -G "${{ matrix.config.generators }}" \
          -DCMAKE_INSTALL_PREFIX:PATH=instdir
        cmake --build . --config ${{ matrix.config.build_type }}
        cmake --install . --strip --config ${{ matrix.config.build_type }}
        ctest -VV -C ${{ matrix.config.build_type }}
        mv Debug instdir

    - name: '🛠️ Win MSVC 32 setup'
      if: contains(matrix.config.name, 'MSVC 32')
      uses: ilammy/msvc-dev-cmd@v1
      with:
        arch: x86

    - name: '🚧 Win MSVC 32 build'
      if: contains(matrix.config.name, 'MSVC 32')
      shell: bash
      run: |
        choco install ninja cmake
        ninja --version
        cmake --version
        mkdir build
        cmake \
          -S . \
          -B . \
          -A "win32" \
          -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
          -G "${{ matrix.config.generators }}" \
          -DCMAKE_INSTALL_PREFIX:PATH=instdir
        cmake --build . --config ${{ matrix.config.build_type }}
        cmake --install . --strip --config ${{ matrix.config.build_type }}
        ctest -VV -C ${{ matrix.config.build_type }}
        mv Debug instdir

    - name: '🚧 Win MINGW build'
      if: contains(matrix.config.mingw, 'MINGW')
      shell: msys2 {0}
      run: |
        if [ ${{ matrix.config.mingw }} == 'MINGW32' ]; then
          export CPPFLAGS=-D__USE_MINGW_ANSI_STDIO=1
          #export CC=i686-w64-mingw32-gcc
          export AR=gcc-ar
          export RANLIB=gcc-ranlib
          export CFLAGS="-m32"
          export LDFLAGS="-m32"
          export LDFLAGS_STATIC="-m32"
          export UNICORN_QEMU_FLAGS="--cpu=i386"
        fi
        mkdir build
        mkdir instdir
        cmake \
          -S . \
          -B . \
          -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
          -G "${{ matrix.config.generators }}" \
          -DCMAKE_INSTALL_PREFIX:PATH=instdir
        cmake --build . --config ${{ matrix.config.build_type }}
        cmake --install . --strip
        ctest -VV -C ${{ matrix.config.build_type }}

    - name: '📦 Pack artifact'
      if: always()
      shell: bash
      working-directory: instdir
      run: |
        ls -laR
        ${{ matrix.config.archiver }} ../${{ matrix.config.artifact }} . ../test*

    - name: '📤 Upload artifact'
      if: always()
      uses: actions/upload-artifact@v1
      with:
        path: ./${{ matrix.config.artifact }}
        name: ${{ matrix.config.artifact }}

  Macos:
    runs-on: ${{ matrix.config.os }}
    name: ${{ matrix.config.name }} - ${{ matrix.compiler }}
    strategy:
      fail-fast: false
      matrix:
        config:
          - { 
              os: macos-latest,
              arch: x64,
              python-arch: x64,
              python-ver: '3.8',
              name: 'macos-x64 cmake',
              artifact: 'macos-cmake-x64.7z',
              build_type: 'Debug',
              archiver: '7za a',
              generators: 'Ninja'
            }
          - { 
              os: macos-11,
              arch: x86_64,
              python-arch: x86_64,
              python-ver: '3.8',
              name: 'android cmake',
              artifact: 'Android-x86_64.7z',
              build_type: 'Debug',
              archiver: '7za a',
              generators: 'Ninja'
            }
        compiler: [ gcc ]
    steps:
    - uses: actions/checkout@v2

    # - name: '🛠️ Python setup'
      # uses: actions/setup-python@v2
      # with:
        # python-version: ${{ matrix.config.python-ver }}

    - name: '🚧 Mac build'
      if: contains(matrix.config.name, 'macos-x64')
      shell: bash
      run: |
        brew install p7zip cmake ninja
        ninja --version
        cmake --version
        mkdir build
        mkdir instdir
        cmake \
          -S . \
          -B . \
          -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
          -G "${{ matrix.config.generators }}" \
          -DCMAKE_INSTALL_PREFIX:PATH=instdir
        cmake --build . --config ${{ matrix.config.build_type }}
        cmake --install . --strip
        ctest -VV -C ${{ matrix.config.build_type }}

    - name: '🚧 Android x86_64 build'
      if: contains(matrix.config.name, 'android')
      shell: bash
      run: |
        brew install p7zip cmake ninja
        mkdir build
        mkdir instdir
        cmake . -DCMAKE_TOOLCHAIN_FILE="$ANDROID_HOME/ndk/21.4.7075529/build/cmake/android.toolchain.cmake" \
        	-DANDROID_PLATFORM=android-28 \
          -DANDROID_NDK="$ANDROID_HOME/ndk/21.4.7075529" \
          -DANDROID_ABI=${{ matrix.config.arch }} \
          -DOLP_SDK_ENABLE_TESTING=NO \
          -DOLP_SDK_BUILD_EXAMPLES=ON \
          -S . \
          -B . \
          -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
          -G "${{ matrix.config.generators }}" \
          -DCMAKE_INSTALL_PREFIX:PATH=instdir
        cmake --build . --config ${{ matrix.config.build_type }}
        cmake --install . --strip

    - name: '🚧 AVD Cache'
      if: contains(matrix.config.name, 'android')
      uses: actions/cache@v2
      id: avd-cache
      with:
        path: |
          ~/.android/avd/*
          ~/.android/adb*
        key: avd-28
    
    - name: '🚧 Create x86_64 tests environment'
      if: contains(matrix.config.name, 'android') && steps.avd-cache.outputs.cache-hit != 'true'
      uses: reactivecircus/android-emulator-runner@v2
      with:
        api-level: 28
        arch: ${{ matrix.config.arch }}
        force-avd-creation: false
        disable-animations: false
        target: default
        profile: Nexus 6
        emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -verbose -show-kernel
        script: echo "Generated AVD snapshot for caching."

    - name: '🚧 Android x86_64 tests'
      if: contains(matrix.config.name, 'android')
      uses: reactivecircus/android-emulator-runner@v2
      with:
        api-level: 28
        force-avd-creation: false
        disable-animations: true
        arch: ${{ matrix.config.arch }}
        target: default
        profile: Nexus 6
        emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -verbose -show-kernel
        script: bash ./adb.sh

    - name: '📦 Pack artifact'
      if: always()
      shell: bash
      working-directory: instdir
      run: |
        ls -laR
        ${{ matrix.config.archiver }} ../${{ matrix.config.artifact }} . ../test*

    - name: '📤 Upload artifact'
      if: always()
      uses: actions/upload-artifact@v1
      with:
        path: ./${{ matrix.config.artifact }}
        name: ${{ matrix.config.artifact }}

  Linux:
    runs-on: ${{ matrix.config.os }}
    name: ${{ matrix.config.name }} - ${{ matrix.compiler }}
    strategy:
      fail-fast: false
      matrix:
        config:
          - { 
              os: ubuntu-latest, 
              arch: x64, 
              python-arch: x64, 
              python-ver: '3.8', 
              name: 'ubuntu-x64 cmake',
              artifact: 'ubuntu-cmake-x64.7z',
              build_type: 'Debug',
              archiver: '7z a',
              generators: 'Ninja'
            }
          - { 
              os: ubuntu-latest,
              arch: x86,
              python-arch: x86,
              python-ver: '3.8',
              name: 'ubuntu-x86 cmake',
              artifact: 'ubuntu-cmake-x86.7z',
              build_type: 'Debug',
              archiver: '7z a',
              generators: 'Ninja' 
            }
          - { 
              os: ubuntu-latest,
              arch: aarch64,
              python-arch: aarch64,
              python-ver: '3.8',
              name: 'ubuntu-aarch64 cmake',
              artifact: 'ubuntu-cmake-aarch64.7z',
              build_type: 'Debug',
              archiver: '7z a',
              generators: 'Ninja',
              distro: ubuntu20.04
            }
          - { 
              os: ubuntu-latest,
              arch: ppc64le,
              python-arch: ppc,
              python-ver: '3.8',
              name: 'ubuntu-ppc64le cmake',
              artifact: 'ubuntu-cmake-ppc64le.7z',
              build_type: 'Debug',
              archiver: '7z a',
              generators: 'Ninja',
              distro: ubuntu20.04
            }
        compiler: [ gcc ]
    steps:
    - uses: actions/checkout@v2

    # - name: '🛠️ Python setup'
      # uses: actions/setup-python@v2
      # with:
        # python-version: ${{ matrix.config.python-ver }}

    - name: '🚧 Linux x64/x86 build'
      if: contains(matrix.config.arch, 'x64') || contains(matrix.config.arch, 'x86')
      shell: 'script -q -e -c "bash {0}"'
      run: |
        if [ ${{ matrix.config.arch }} == 'x64' ]; then
              sudo apt install -q -y libcmocka-dev ninja-build 
        else
              export CFLAGS="-m32" LDFLAGS="-m32" LDFLAGS_STATIC="-m32" UNICORN_QEMU_FLAGS="--cpu=i386" 
              sudo dpkg --add-architecture i386
              sudo apt install -q -y lib32ncurses-dev lib32z1-dev lib32gcc-9-dev libc6-dev-i386 gcc-multilib \
                libcmocka-dev:i386 libcmocka0:i386 libc6:i386 libgcc-s1:i386 ninja-build
        fi
        mkdir build
        mkdir instdir
        cmake \
          -S . \
          -B . \
          -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
          -G "${{ matrix.config.generators }}" \
          -DCMAKE_INSTALL_PREFIX:PATH=instdir
        cmake --build . --config ${{ matrix.config.build_type }}
        cmake --install . --strip
        ctest -VV -C ${{ matrix.config.build_type }}
    
    - name: '🚧 Linux ppc64le/aarch64 build'
      if: contains(matrix.config.arch, 'ppc64le') || contains(matrix.config.arch, 'aarch64')
      uses: uraimo/run-on-arch-action@v2.0.5
      with:
        arch: ${{ matrix.config.arch }}
        distro: ${{ matrix.config.distro }}
        setup: |
          mkdir -p "${PWD}/instdir"
        dockerRunArgs: |
          --volume "${PWD}/instdir:/instdir"
        shell: /bin/sh
        install: |
          apt-get update -q -y
          apt-get install -q -y git cmake build-essential automake libcmocka-dev pkg-config ${{ matrix.compiler }} ninja-build
        run: |
          mkdir build
          cmake \
            -S . \
            -B . \
            -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
            -G "${{ matrix.config.generators }}" \
            -DCMAKE_INSTALL_PREFIX:PATH=/instdir
          cmake --build . --config ${{ matrix.config.build_type }}
          cmake --install . --strip
          ctest -VV -C ${{ matrix.config.build_type }}

    - name: '📦 Pack artifact'
      if: always()
      shell: bash
      working-directory: instdir
      run: |
        ls -laR
        ${{ matrix.config.archiver }} ../${{ matrix.config.artifact }} . ../test*

    - name: '📤 Upload artifact'
      if: always()
      uses: actions/upload-artifact@v1
      with:
        path: ./${{ matrix.config.artifact }}
        name: ${{ matrix.config.artifact }}
