瀏覽代碼

Merge pull request #15 from PatTheMav/template-overhaul

Overhaul of plugin template for modern CMake build system and GitHub Actions
Joel Bethke 3 年之前
父節點
當前提交
257c4f26c9
共有 51 個文件被更改,包括 4006 次插入1687 次删除
  1. 394 0
      .github/workflows/main.yml
  2. 103 0
      CI/build-linux.sh
  3. 129 0
      CI/build-macos.sh
  4. 132 0
      CI/build-windows.ps1
  5. 2 0
      CI/include/Brewfile
  6. 1 0
      CI/include/Xcnotary
  7. 2 0
      CI/include/build_environment.ps1.in
  8. 3 0
      CI/include/build_environment.sh.in
  9. 229 0
      CI/include/build_support.sh
  10. 33 0
      CI/include/build_support_linux.sh
  11. 149 0
      CI/include/build_support_macos.sh
  12. 139 0
      CI/include/build_support_windows.ps1
  13. 127 0
      CI/linux/01_install_dependencies.sh
  14. 73 0
      CI/linux/02_build_obs_libs.sh
  15. 66 0
      CI/linux/03_build_plugin.sh
  16. 68 0
      CI/linux/04_package_plugin.sh
  17. 120 0
      CI/macos/01_install_dependencies.sh
  18. 79 0
      CI/macos/02_build_obs_libs.sh
  19. 85 0
      CI/macos/03_build_plugin.sh
  20. 150 0
      CI/macos/04_package_plugin.sh
  21. 11 0
      CI/utility/check-format.sh
  22. 60 0
      CI/utility/formatcode.sh
  23. 158 0
      CI/windows/01_install_dependencies.ps1
  24. 102 0
      CI/windows/02_build_obs_libs.ps1
  25. 92 0
      CI/windows/03_build_plugin.ps1
  26. 141 0
      CI/windows/04_package_plugin.ps1
  27. 81 149
      CMakeLists.txt
  28. 12 14
      README.md
  29. 0 166
      azure-pipelines.yml
  30. 947 0
      bundle/installer-macOS.pkgproj.in
  31. 26 0
      bundle/macOS/Plugin-Info.plist.in
  32. 17 0
      bundle/macOS/entitlements.plist
  33. 0 2
      ci/ci_includes.cmd.in
  34. 0 4
      ci/ci_includes.sh.in
  35. 0 6
      ci/linux/build-ubuntu.sh
  36. 0 19
      ci/linux/install-dependencies-ubuntu.sh
  37. 0 25
      ci/linux/package-ubuntu.sh
  38. 0 28
      ci/macos/build-macos.sh
  39. 0 43
      ci/macos/install-build-obs-macos.sh
  40. 0 62
      ci/macos/install-dependencies-macos.sh
  41. 0 93
      ci/macos/package-macos.sh
  42. 0 163
      ci/macos/qt.rb
  43. 0 6
      ci/windows/download-obs-deps.cmd
  44. 0 8
      ci/windows/install-qt-win.cmd
  45. 0 14
      ci/windows/package-windows.cmd
  46. 0 36
      ci/windows/prepare-obs-windows.cmd
  47. 0 15
      ci/windows/prepare-windows.cmd
  48. 0 107
      external/FindLibObs.cmake
  49. 274 0
      external/ObsPluginHelpers.cmake
  50. 1 1
      installer/installer-Windows.iss.in
  51. 0 726
      installer/installer-macOS.pkgproj.in

+ 394 - 0
.github/workflows/main.yml

@@ -0,0 +1,394 @@
+name: 'BUILD'
+
+on:
+  push:
+    paths-ignore: ['**.md']
+    branches: [master]
+    tags: ['*']
+  pull_request:
+    paths-ignore: ['**.md']
+    branches: [master]
+
+env:
+  OBS_VERSION: '26.1.2'
+  PRODUCT_NAME: 'obs-plugin'
+  QT_VERSION_MAC: '5.15.2'
+  QT_HASH_MAC: 'a09690095d16b3f476ae6e0f5bf3154effcd6571738c1c40f8abbb83676d2afb'
+  QT_VERSION_WIN: '5.15.2'
+  DEPS_VERSION_MAC: '2021-08-17'
+  DEPS_HASH_MAC: 'fc6b356572c4703d56f5b2deb98e46cddffb29a0d36c988702dd76329efe7072'
+  DEPS_VERSION_WIN: '2019'
+
+jobs:
+  clang_check:
+    name: '01 - Code Format Check'
+    runs-on: [ubuntu-latest]
+    steps:
+      - name: 'Checkout'
+        uses: actions/checkout@v2.3.3
+        with:
+          submodules: 'recursive'
+
+      - name: 'Install clang-format'
+        run: sudo apt-get install -y clang-format-12
+
+      - name: 'Run clang-format'
+        run: |
+          ./CI/formatcode.sh
+          ./CI/check-format.sh
+
+  macos_build:
+    name: '02 - macOS (Latest)'
+    runs-on: [macos-11]
+    strategy:
+      matrix:
+        arch: ['x86_64']
+    if: always()
+    needs: [clang_check]
+    env:
+      MACOSX_DEPLOYMENT_TARGET: '10.13'
+      BLOCKED_FORMULAS: 'speexdsp curl php'
+      CODESIGN_IDENT: '-'
+      CODESIGN_IDENT_INSTALLER: '-'
+      HAVE_CODESIGN_IDENTITY: ${{ secrets.MACOS_SIGNING_APPLICATION_IDENTITY != '' && secrets.MACOS_SIGNING_INSTALLER_IDENTITY && secrets.MACOS_SIGNING_CERT != '' }}
+    defaults:
+      run:
+        shell: bash
+    steps:
+      - name: 'Checkout'
+        uses: actions/checkout@v2.3.3
+        with:
+          path: 'plugin'
+          submodules: 'recursive'
+
+      - name: 'Checkout'
+        uses: actions/checkout@v2.3.3
+        with:
+          repository: 'obsproject/obs-studio'
+          path: 'obs-studio'
+          ref: '${{ env.OBS_VERSION }}'
+          fetch-depth: 0
+          submodules: 'recursive'
+
+      - name: 'Check for Github Labels'
+        if: github.event_name == 'pull_request'
+        run: |
+          if test -n "$(curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -s "${{ github.event.pull_request.url }}" | jq -e '.labels[] | select(.name == "Seeking Testers")')"; then
+            echo "SEEKING_TESTERS=1" >> $GITHUB_ENV
+          else
+            echo "SEEKING_TESTERS=0" >> $GITHUB_ENV
+          fi
+
+          echo "CACHE_DATE=$(date +"%Y-%m-%d")" >> $GITHUB_ENV
+
+      - name: 'Restore ccache from cache'
+        id: ccache-cache
+        uses: actions/cache@v2.1.2
+        env:
+          CACHE_NAME: 'ccache-cache'
+        with:
+          path: ${{ github.workspace }}/.ccache
+          key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ matrix.arch }}-${{ env.CACHE_DATE }}
+
+      - name: 'Setup build environment'
+        run: |
+          REMOVE_FORMULAS=""
+          for FORMULA in ${{ env.BLOCKED_FORMULAS }}; do
+            if [ -d "/usr/local/opt/${FORMULA}" ]; then
+              REMOVE_FORMULAS="${REMOVE_FORMULAS}${FORMULA} "
+            fi
+          done
+
+          if [ -n "${REMOVE_FORMULAS}" ]; then
+            brew uninstall ${REMOVE_FORMULAS}
+          fi
+
+      - name: 'Install dependencies'
+        run: CI/macos/01_install_dependencies.sh --architecture "${{ matrix.arch }}"
+
+      - name: 'Restore libobs and obs-frontend-api from cache'
+        id: libobs-cache
+        uses: actions/cache@v2.1.2
+        env:
+          CACHE_NAME: 'libobs-cache'
+        with:
+          path: |
+            ${{ github.workspace }}/.cmake/packages/libobs
+            ${{ github.workspace }}/.cmake/packages/obs-frontend-api
+            ${{ github.workspace }}/obs-studio/build/libobs
+            ${{ github.workspace }}/obs-studio/build/UI/obs-frontend-api
+          key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.OBS_VERSION }}
+
+      - name: 'Build libobs and obs-frontend-api'
+        if: steps.libobs-cache.outputs.cache-hit != 'true'
+        working-directory: 'plugin'
+        run: CI/macos/02_build_obs-libs.sh --architecture "${{ matrix.arch }}"
+
+      - name: 'Install Apple Developer Certificate'
+        if: startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' && env.HAVE_CODESIGN_IDENTITY == 'true'
+        uses: apple-actions/import-codesign-certs@253ddeeac23f2bdad1646faac5c8c2832e800071
+        with:
+          p12-file-base64: ${{ secrets.MACOS_SIGNING_CERT }}
+          p12-password: ${{ secrets.MACOS_SIGNING_CERT_PASSWORD }}
+
+      - name: 'Set Signing Identity'
+        if: startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' && env.HAVE_CODESIGN_IDENTITY == 'true'
+        run: |
+          echo "CODESIGN_IDENT=${{ secrets.MACOS_SIGNING_APPLICATION_IDENTITY }}" >> $GITHUB_ENV
+          echo "CODESIGN_IDENT_INSTALLER=${{ secrets.MACOS_SIGNING_INSTALLER_IDENTITY }}" >> $GITHUB_ENV
+
+      - name: 'Build plugin'
+        working-directory: 'plugin'
+        run: CI/macos/03_build_plugin.sh --codesign --architecture "${{ matrix.arch }}"
+
+      - name: 'Create build artifact'
+        if: success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1')
+        working-directory: 'plugin'
+        run: CI/macos/04_package_plugin.sh --codesign --architecture "${{ matrix.arch }}"
+
+      - name: 'Upload build Artifact'
+        if: success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1')
+        uses: actions/upload-artifact@v2
+        with:
+          name: '${{ env.PRODUCT_NAME }}-macos-${{ matrix.arch }}'
+          path: '${{ github.workspace }}/plugin/*-macOS.pkg'
+
+  linux_build:
+    name: '02 - Linux (Ubuntu, 20.04)'
+    runs-on: ${{ matrix.ubuntu }}
+    strategy:
+      matrix:
+        ubuntu: ['ubuntu-20.04', 'ubuntu-18.04']
+    if: always()
+    needs: [clang_check]
+    defaults:
+      run:
+        shell: bash
+    steps:
+      - name: 'Checkout'
+        uses: actions/checkout@v2.3.3
+        with:
+          path: 'plugin'
+          submodules: 'recursive'
+
+      - name: 'Checkout'
+        uses: actions/checkout@v2.3.3
+        with:
+          repository: 'obsproject/obs-studio'
+          path: 'obs-studio'
+          ref: '${{ env.OBS_VERSION }}'
+          fetch-depth: 0
+          submodules: 'recursive'
+
+      - name: 'Check for Github Labels'
+        if: github.event_name == 'pull_request'
+        run: |
+          if test -n "$(curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -s "${{ github.event.pull_request.url }}" | jq -e '.labels[] | select(.name == "Seeking Testers")')"; then
+            echo "SEEKING_TESTERS=1" >> $GITHUB_ENV
+          else
+            echo "SEEKING_TESTERS=0" >> $GITHUB_ENV
+          fi
+
+          echo "CACHE_DATE=$(date +"%Y-%m-%d")" >> $GITHUB_ENV
+
+      - name: 'Restore ccache from cache'
+        id: ccache-cache
+        uses: actions/cache@v2.1.2
+        env:
+          CACHE_NAME: 'ccache-cache'
+        with:
+          path: ${{ github.workspace }}/.ccache
+          key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ matrix.ubuntu }}-${{ env.CACHE_DATE }}
+
+      - name: "Install Dependencies"
+        working-directory: 'plugin'
+        run: CI/linux/01_install_dependencies.sh --disable-pipewire
+
+      - name: 'Restore libobs and obs-frontend-api from cache'
+        id: libobs-cache
+        uses: actions/cache@v2.1.2
+        env:
+          CACHE_NAME: 'libobs-cache'
+        with:
+          path: |
+            ${{ github.workspace }}/.cmake/packages/libobs
+            ${{ github.workspace }}/.cmake/packages/obs-frontend-api
+            ${{ github.workspace }}/obs-studio/CI_BUILD/libobs
+            ${{ github.workspace }}/obs-studio/CI_BUILD/UI/obs-frontend-api
+          key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.OBS_VERSION }}
+
+      - name: 'Build libobs and obs-frontend-api'
+        if: steps.libobs-cache.outputs.cache-hit != 'true'
+        working-directory: 'plugin'
+        run: CI/linux/02_build_obs-libs.sh --disable-pipewire
+
+      - name: 'Build plugin'
+        working-directory: 'plugin'
+        run: CI/linux/03_build_plugin.sh
+
+      - name: 'Create build artifact'
+        working-directory: 'plugin'
+        if: success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1')
+        run: CI/linux/04_package_plugin.sh
+
+      - name: 'Upload build Artifact'
+        if: success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1')
+        uses: actions/upload-artifact@v2
+        with:
+          name: '${{ env.PRODUCT_NAME }}-linux-${{ matrix.arch }}'
+          path: '${{ github.workspace }}/plugin/*.deb'
+
+  windows_build:
+    name: '02 - Windows (Latest)'
+    runs-on: [windows-latest]
+    needs: [clang_check]
+    if: always()
+    strategy:
+      matrix:
+        arch: [64, 32]
+    env:
+      CMAKE_GENERATOR: "Visual Studio 16 2019"
+      CMAKE_SYSTEM_VERSION: "10.0.18363.657"
+    steps:
+      - name: 'Add msbuild to PATH'
+        uses: microsoft/setup-msbuild@v1.0.2
+
+      - name: 'Checkout'
+        uses: actions/checkout@v2.3.3
+        with:
+          path: 'plugin'
+          submodules: 'recursive'
+
+      - name: 'Checkout'
+        uses: actions/checkout@v2.3.3
+        with:
+          repository: 'obsproject/obs-studio'
+          path: 'obs-studio'
+          ref: '${{ env.OBS_VERSION }}'
+          fetch-depth: 0
+          submodules: 'recursive'
+
+      - name: 'Check for Github Labels'
+        if: github.event_name == 'pull_request'
+        run: |
+          $LabelFound = try { (Invoke-RestMethod -Authentication 'Bearer' -Token (ConvertTo-SecureString '${{ secrets.GITHUB_TOKEN }}' -AsPlainText) -Uri "${{ github.event.pull_request.url }}" -UseBasicParsing).labels.name.contains("Seeking Testers") } catch { $false }
+          Write-Output "SEEKING_TESTERS=$(if( $LabelFound -eq $true ) { 1 } else { 0 })" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
+
+      - name: "Install Dependencies"
+        working-directory: 'plugin'
+        run: CI/windows/01_install_dependencies.ps1 -BuildArch ${{ matrix.arch }}-bit -NoChoco
+
+      - name: 'Restore libobs and obs-frontend-api from cache'
+        id: libobs-cache
+        uses: actions/cache@v2.1.2
+        env:
+          CACHE_NAME: 'libobs-cache'
+        with:
+          path: |
+            ${{ github.workspace }}/obs-studio/build/libobs
+            ${{ github.workspace }}/obs-studio/build/UI/obs-frontend-api
+            ${{ github.workspace }}/obs-studio/build/deps/w32-pthreads
+          key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ env.OBS_VERSION }}
+
+      - name: 'Build libobs and obs-frontend-api'
+        working-directory: 'obs-studio'
+        run: CI/windows/02_build_obs_libs.ps1 -BuildArch "${{ matrix.arch }}-bit"
+
+      - name: 'Build plugin'
+        working-directory: 'plugin'
+        run: CI/windows/03_build_plugin.ps1 -BuildArch "${{ matrix.arch }}-bit"
+
+      - name: 'Create build artifact'
+        if: success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1')
+        run: CI/windows/04_package_plugin.ps1 -BuildArch "${{ matrix.arch }}-bit"
+
+      - name: 'Upload build Artifact'
+        if: success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1')
+        uses: actions/upload-artifact@v2
+        with:
+          name: '${{ env.PRODUCT_NAME }}-windows-${{ matrix.arch }}'
+          path: '${{ github.workspace }}/plugin/*-Win${{ matrix.arch }}.zip'
+
+  windows_package:
+    name: '03 - Windows Installer'
+    runs-on: [ubuntu-latest]
+    needs: [windows_build]
+    if: startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request'
+    steps:
+      - name: 'Checkout'
+        uses: actions/checkout@v2.3.3
+        with:
+          submodules: 'recursive'
+
+      - name: 'Download 64-bit artifact'
+        uses: actions/download-artifact@v2
+        with:
+          name: '${{ env.PRODUCT_NAME }}-windows-64'
+          path: ${{ github.workspace }}
+
+      - name: 'Download 32-bit artifact'
+        uses: actions/download-artifact@v2
+        with:
+          name: '${{ env.PRODUCT_NAME }}-windows-32'
+          path: ${{ github.workspace }}
+
+      - name: 'Build InnoSetup installer'
+        run: |
+          Get-ChildItem -Filter "*-Win32.zip" -File | Expand-Archive -DestinationPath ./release/
+          Get-ChildItem -Filter "*-Win64.zip" -File | Expand-Archive -DestinationPath ./release/
+          CI/windows/04_package_plugin.ps1 -BuildInstaller -CombinedArchs
+
+      - name: 'Upload build Artifact'
+        if: success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1')
+        uses: actions/upload-artifact@v2
+        with:
+          name: '${{ env.PRODUCT_NAME }}-windows-release'
+          path: '${{ github.workspace }}/plugin/*-Windows-Installer.exe'
+
+  macos_release:
+    name: '03 - macOS notarized image'
+    runs-on: [macos-latest]
+    needs: [macos_build]
+    env:
+      HAVE_CODESIGN_IDENTITY: ${{ secrets.MACOS_SIGNING_APPLICATION_IDENTITY != '' && secrets.MACOS_SIGNING_INSTALLER_IDENTITY && secrets.MACOS_SIGNING_CERT != '' }}
+    if: startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request'
+    defaults:
+      run:
+        shell: bash
+    steps:
+      - name: 'Checkout'
+        if: env.HAVE_CODESIGN_IDENTITY == 'true'
+        uses: actions/checkout@v2.3.3
+        with:
+          submodules: 'recursive'
+
+      - name: 'Download artifact'
+        if: env.HAVE_CODESIGN_IDENTITY == 'true'
+        uses: actions/download-artifact@v2
+        with:
+          name: '${{ env.PRODUCT_NAME }}-macos'
+
+      - name: 'Install Apple Developer Certificate'
+        if: env.HAVE_CODESIGN_IDENTITY == 'true'
+        uses: apple-actions/import-codesign-certs@253ddeeac23f2bdad1646faac5c8c2832e800071
+        with:
+          p12-file-base64: ${{ secrets.MACOS_SIGNING_CERT }}
+          p12-password: ${{ secrets.MACOS_SIGNING_CERT_PASSWORD }}
+
+      - name: 'Install prerequisite XCNotary'
+        if: env.HAVE_CODESIGN_IDENTITY == 'true'
+        run: brew bundle --file CI/include/Xcnotary
+
+      - name: 'Create disk image for distribution'
+        if: env.HAVE_CODESIGN_IDENTITY == 'true'
+        env:
+          CODESIGN_IDENT_USER: '${{ secrets.MACOS_NOTARIZATION_USERNAME }}'
+          CODESIGN_IDENT_PASS: '${{ secrets.MACOS_NOTARIZATION_PASSWORD }}'
+        run: CI/macos/04_package_plugin.sh --notarize
+
+      - name: 'Upload notarized installer package'
+        if: env.HAVE_CODESIGN_IDENTITY == 'true'
+        uses: actions/upload-artifact@v2
+        with:
+          name: '${{ env.PRODUCT_NAME }}-macos-release'
+          path: '${{ github.workspace }}/plugin/*-macOS.pkg'

+ 103 - 0
CI/build-linux.sh

@@ -0,0 +1,103 @@
+#!/bin/bash
+
+##############################################################################
+# Linux plugin build script
+##############################################################################
+#
+# This script contains all steps necessary to:
+#
+#   * Build libobs and obs-frontend-api with all required dependencies
+#   * Build your plugin
+#   * Create debian package
+#
+# Parameters:
+#   -h, --help                      : Print usage help
+#   -q, --quiet                     : Suppress most build process output
+#   -v, --verbose                   : Enable more verbose build process output
+#   -p, --package                   : Create installer for plugin
+#   -b, --build-dir                 : Specify alternative build directory
+#                                     (default: build)
+#
+# Environment Variables (optional):
+#   OBS_VERSION         : OBS Version
+#
+##############################################################################
+
+# Halt on errors
+set -eE
+
+## SET UP ENVIRONMENT ##
+_RUN_OBS_BUILD_SCRIPT=TRUE
+
+CHECKOUT_DIR="$(git rev-parse --show-toplevel)"
+if [ -f "${CHECKOUT_DIR}/CI/include/build_environment.sh" ]; then
+    source "${CHECKOUT_DIR}/CI/include/build_environment.sh"
+fi
+PRODUCT_NAME="${PRODUCT_NAME:-obs-plugin}"
+DEPS_BUILD_DIR="${CHECKOUT_DIR}/../obs-build-dependencies"
+OBS_BUILD_DIR="${CHECKOUT_DIR}/../obs-studio"
+source "${CHECKOUT_DIR}/CI/include/build_support.sh"
+source "${CHECKOUT_DIR}/CI/include/build_support_linux.sh"
+
+## DEPENDENCY INSTALLATION ##
+source "${CHECKOUT_DIR}/CI/linux/01_install_dependencies.sh"
+
+## OBS LIBRARY BUILD ##
+source "${CHECKOUT_DIR}/CI/linux/02_build_obs_libs.sh"
+
+## PLUGIN BUILD ##
+source "${CHECKOUT_DIR}/CI/linux/03_build_plugin.sh"
+
+## PLUGIN PACKAGE AND NOTARIZE ##
+source "${CHECKOUT_DIR}/CI/linux/04_package_plugin.sh"
+
+## MAIN SCRIPT FUNCTIONS ##
+print_usage() {
+    echo -e "build_linux.sh - Build script for ${PRODUCT_NAME}\n"
+    echo -e "Usage: ${0}\n" \
+        "-h, --help                     : Print this help\n" \
+        "-q, --quiet                    : Suppress most build process output\n" \
+        "-v, --verbose                  : Enable more verbose build process output\n" \
+        "-d, --skip-dependency-checks   : Skip dependency checks\n" \
+        "-p, --package                  : Create installer for plugin\n" \
+        "-b, --build-dir                : Specify alternative build directory (default: build)\n"
+
+}
+
+obs-build-main() {
+    while true; do
+        case "${1}" in
+            -h | --help ) print_usage; exit 0 ;;
+            -d | --skip-dependency-checks ) SKIP_DEP_CHECKS=TRUE; shift ;;
+            -q | --quiet ) export QUIET=TRUE; shift ;;
+            -v | --verbose ) export VERBOSE=TRUE; shift ;;
+            -p | --package ) PACKAGE=TRUE; shift ;;
+            -b | --build-dir ) BUILD_DIR="${2}"; shift 2 ;;
+            -- ) shift; break ;;
+            * ) break ;;
+        esac
+    done
+
+    ensure_dir "${CHECKOUT_DIR}"
+    step "Fetching version tags..."
+    git fetch origin --tags
+    GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
+    GIT_HASH=$(git rev-parse --short HEAD)
+    GIT_TAG=$(git describe --tags --abbrev=0 2&>/dev/null || true)
+    FILE_NAME="${PRODUCT_NAME}-${GIT_TAG:-${PRODUCT_VERSION}}-${GIT_HASH}-linux"
+
+    if [ -z "${SKIP_DEP_CHECKS}" ]; then
+        install_dependencies
+    fi
+
+    build_obs_libs
+    build_obs_plugin
+
+    if [ -n "${PACKAGE}" ]; then
+        package_obs_plugin
+    fi
+
+    cleanup
+}
+
+obs-build-main $*

+ 129 - 0
CI/build-macos.sh

@@ -0,0 +1,129 @@
+#!/bin/bash
+
+##############################################################################
+# macOS plugin build script
+##############################################################################
+#
+# This script contains all steps necessary to:
+#
+#   * Build libobs and obs-frontend-api with all required dependencies
+#   * Build your plugin
+#   * Create macOS module bundle
+#   * Create macOS plugin installer package
+#   * Notarize macOS plugin installer package
+#
+# Parameters:
+#   -h, --help                      : Print usage help
+#   -q, --quiet                     : Suppress most build process output
+#   -v, --verbose                   : Enable more verbose build process output
+#   -d, --skip-dependency-checks    : Skip dependency checks
+#   -p, --package                   : Create installer for plugin
+#   -c, --codesign                  : Codesign plugin and installer
+#   -n, --notarize                  : Notarize plugin installer
+#                                     (implies --codesign)
+#   -b, --build-dir                 : Specify alternative build directory
+#                                     (default: build)
+#
+# Environment Variables (optional):
+#   MACOS_DEPS_VERSION  : Pre-compiled macOS dependencies version
+#   QT_VERSION          : Pre-compiled Qt version
+#   OBS_VERSION         : OBS version
+#
+##############################################################################
+
+# Halt on errors
+set -eE
+
+## SET UP ENVIRONMENT ##
+_RUN_OBS_BUILD_SCRIPT=TRUE
+
+CHECKOUT_DIR="$(/usr/bin/git rev-parse --show-toplevel)"
+if [ -f "${CHECKOUT_DIR}/CI/include/build_environment.sh" ]; then
+    source "${CHECKOUT_DIR}/CI/include/build_environment.sh"
+fi
+PRODUCT_NAME="${PRODUCT_NAME:-obs-plugin}"
+DEPS_BUILD_DIR="${CHECKOUT_DIR}/../obs-build-dependencies"
+OBS_BUILD_DIR="${CHECKOUT_DIR}/../obs-studio"
+source "${CHECKOUT_DIR}/CI/include/build_support.sh"
+source "${CHECKOUT_DIR}/CI/include/build_support_macos.sh"
+
+## DEPENDENCY INSTALLATION ##
+source "${CHECKOUT_DIR}/CI/macos/01_install_dependencies.sh"
+
+## OBS LIBRARY BUILD ##
+source "${CHECKOUT_DIR}/CI/macos/02_build_obs_libs.sh"
+
+## PLUGIN BUILD ##
+source "${CHECKOUT_DIR}/CI/macos/03_build_plugin.sh"
+
+## PLUGIN PACKAGE AND NOTARIZE ##
+source "${CHECKOUT_DIR}/CI/macos/04_package_plugin.sh"
+
+## MAIN SCRIPT FUNCTIONS ##
+print_usage() {
+    echo -e "build_macos.sh - Build script for ${PRODUCT_NAME}\n"
+    echo -e "Usage: ${0}\n" \
+        "-h, --help                     : Print this help\n" \
+        "-q, --quiet                    : Suppress most build process output\n" \
+        "-v, --verbose                  : Enable more verbose build process output\n" \
+        "-a, --architecture             : Specify build architecture (default: universal, alternative: x86_64, arm64)\n" \
+        "-d, --skip-dependency-checks   : Skip dependency checks\n" \
+        "-p, --package                  : Create installer for plugin\n" \
+        "-c, --codesign                 : Codesign plugin and installer\n" \
+        "-n, --notarize                 : Notarize plugin installer (implies --codesign)\n" \
+        "-b, --build-dir                : Specify alternative build directory (default: build)\n"
+}
+
+obs-build-main() {
+    while true; do
+        case "${1}" in
+            -h | --help ) print_usage; exit 0 ;;
+            -q | --quiet ) export QUIET=TRUE; shift ;;
+            -v | --verbose ) export VERBOSE=TRUE; shift ;;
+            -a | --architecture ) ARCH="${2}"; shift 2 ;;
+            -d | --skip-dependency-checks ) SKIP_DEP_CHECKS=TRUE; shift ;;
+            -p | --package ) PACKAGE=TRUE; shift ;;
+            -c | --codesign ) CODESIGN=TRUE; shift ;;
+            -n | --notarize ) NOTARIZE=TRUE; PACKAGE=TRUE CODESIGN=TRUE; shift ;;
+            -b | --build-dir ) BUILD_DIR="${2}"; shift 2 ;;
+            -- ) shift; break ;;
+            * ) break ;;
+        esac
+    done
+
+    ensure_dir "${CHECKOUT_DIR}"
+    check_macos_version
+    check_archs
+    step "Fetching version tags..."
+    /usr/bin/git fetch origin --tags
+    GIT_BRANCH=$(/usr/bin/git rev-parse --abbrev-ref HEAD)
+    GIT_HASH=$(/usr/bin/git rev-parse --short HEAD)
+    GIT_TAG=$(/usr/bin/git describe --tags --abbrev=0 2&>/dev/null || true)
+
+    if [ "${ARCH}" = "arm64" ]; then
+        FILE_NAME="${PRODUCT_NAME}-${GIT_TAG:-${PRODUCT_VERSION}}-${GIT_HASH}-macOS-Apple.pkg"
+    elif [ "${ARCH}" = "x86_64" ]; then
+        FILE_NAME="${PRODUCT_NAME}-${GIT_TAG:-${PRODUCT_VERSION}}-${GIT_HASH}-macOS-Intel.pkg"
+    else
+        FILE_NAME="${PRODUCT_NAME}-${GIT_TAG:-${PRODUCT_VERSION}}-${GIT_HASH}-macOS-Universal.pkg"
+    fi
+
+    if [ -z "${SKIP_DEP_CHECKS}" ]; then
+        install_dependencies
+    fi
+
+    build_obs_libs
+    build_obs_plugin
+
+    if [ -n "${PACKAGE}" ]; then
+        package_obs_plugin
+    fi
+
+    if [ -n "${NOTARIZE}" ]; then
+        notarize_obs_plugin
+    fi
+
+    cleanup
+}
+
+obs-build-main $*

+ 132 - 0
CI/build-windows.ps1

@@ -0,0 +1,132 @@
+Param(
+    [Switch]$Help,
+    [Switch]$Quiet,
+    [Switch]$Verbose,
+    [Switch]$NoChoco,
+    [Switch]$SkipDependencyChecks,
+    [Switch]$BuildInstaller,
+    [Switch]$CombinedArchs,
+    [String]$BuildDirectory = "build",
+    [String]$BuildArch = (Get-CimInstance CIM_OperatingSystem).OSArchitecture,
+    [String]$BuildConfiguration = "RelWithDebInfo"
+)
+
+##############################################################################
+# Windows plugin build script
+##############################################################################
+#
+# This script contains all steps necessary to:
+#
+#   * Build libobs and obs-frontend-api with all required dependencies
+#   * Build your plugin
+#   * Create 64-bit or 32-bit packages
+#   * Create 64-bit or 32-bit installation packages
+#   * Create combined installation packages
+#
+# Parameters:
+#   -Help                   : Print usage help
+#   -NoChco                 : Skip automatic dependency installation
+#                             via Chocolatey
+#   -SkipDependencyChecks   : Skips dependency checks
+#   -BuildDirectory         : Directory to use for builds
+#                             Default: Win64 on 64-bit systems
+#                                      Win32 on 32-bit systems
+#  -BuildArch               : Build architecture to use (32bit or 64bit)
+#  -BuildConfiguration      : Build configuration to use
+#                             Default: RelWithDebInfo
+#  -BuildInstaller          : Build InnoSetup installer - Default: off"
+#  -CombinedArchs           : Create combined packages and installer
+#                             (64-bit and 32-bit) - Default: off"
+#
+# Environment Variables (optional):
+#  WindowsDepsVersion       : Pre-compiled Windows dependencies version
+#  WindowsQtVersion         : Pre-compiled Qt version
+#  ObsVersion               : OBS Version
+#
+##############################################################################
+
+$ErrorActionPreference = "Stop"
+
+$_RunObsBuildScript = $true
+
+$CheckoutDir = git rev-parse --show-toplevel
+
+$DepsBuildDir = "${CheckoutDir}/../obs-build-dependencies"
+$ObsBuildDir = "${CheckoutDir}/../obs-studio"
+
+if (Test-Path ${CheckoutDir}/CI/include/build_environment.ps1) {
+    . ${CheckoutDir}/CI/include/build_environment.ps1
+}
+
+. ${CheckoutDir}/CI/include/build_support_windows.ps1
+
+## DEPENDENCY INSTALLATION ##
+. ${CheckoutDir}/CI/windows/01_install_dependencies.ps1
+
+## OBS LIBRARY BUILD ##
+. ${CheckoutDir}/CI/windows/02_build_obs_libs.ps1
+
+## PLUGIN BUILD ##
+. ${CheckoutDir}/CI/windows/03_build_plugin.ps1
+
+## PLUGIN PACKAGE AND NOTARIZE ##
+. ${CheckoutDir}/CI/windows/04_package_plugin.ps1
+
+## MAIN SCRIPT FUNCTIONS ##
+function Build-Obs-Plugin-Main {
+    Ensure-Directory ${CheckoutDir}
+    Write-Step "Fetching version tags..."
+    & git fetch origin --tags
+    $GitBranch = git rev-parse --abbrev-ref HEAD
+    $GitHash = git rev-parse --short HEAD
+    $ErrorActionPreference = "SilentlyContiue"
+    $GitTag = git describe --tags --abbrev=0
+    $ErrorActionPreference = "Stop"
+
+    if ($GitTag -eq $null) {
+        $GitTag=$ProductVersion
+    }
+
+    $FileName = "${ProductName}-${GitTag}-${GitHash}"
+
+    if(!($SkipDependencyChecks.isPresent)) {
+        Install-Dependencies -NoChoco:$NoChoco
+    }
+
+    if($CombinedArchs.isPresent) {
+        Build-OBS-Libs -BuildArch 64-bit
+        Build-OBS-Libs -BuildArch 32-bit
+        Build-OBS-Plugin -BuildArch 64-bit
+        Build-OBS-Plugin -BuildArch 32-bit
+    } else {
+        Build-OBS-Libs
+        Build-OBS-Plugin
+    }
+
+    Package-OBS-Plugin
+}
+
+function Print-Usage {
+    Write-Host "build-windows.ps1 - Build script for ${ProductName}"
+    $Lines = @(
+        "Usage: ${MyInvocation.MyCommand.Name}",
+        "-Help                    : Print this help",
+        "-Quiet                   : Suppress most build process output"
+        "-Verbose                 : Enable more verbose build process output"
+        "-NoChoco                 : Skip automatic dependency installation via Chocolatey - Default: on",
+        "-SkipDependencyChecks    : Skips dependency checks - Default: off",
+        "-BuildDirectory          : Directory to use for builds - Default: build64 on 64-bit systems, build32 on 32-bit systems",
+        "-BuildArch               : Build architecture to use (32bit or 64bit) - Default: local architecture",
+        "-BuildConfiguration      : Build configuration to use - Default: RelWithDebInfo",
+        "-BuildInstaller          : Build InnoSetup installer - Default: off",
+        "-CombinedArchs           : Create combined packages and installer (64-bit and 32-bit) - Default: off"
+    )
+    $Lines | Write-Host
+}
+
+if($Help.isPresent) {
+    Print-Usage
+    exit 0
+}
+
+Build-Obs-Plugin-Main

+ 2 - 0
CI/include/Brewfile

@@ -0,0 +1,2 @@
+brew "cmake"
+brew "ninja"

+ 1 - 0
CI/include/Xcnotary

@@ -0,0 +1 @@
+brew "akeru-inc/tap/xcnotary"

+ 2 - 0
CI/include/build_environment.ps1.in

@@ -0,0 +1,2 @@
+$ProductName = "@CMAKE_PROJECT_NAME@"
+$ProductVersion = "@CMAKE_PROJECT_VERSION@"

+ 3 - 0
CI/include/build_environment.sh.in

@@ -0,0 +1,3 @@
+PRODUCT_NAME="@CMAKE_PROJECT_NAME@"
+PRODUCT_VERSION="@CMAKE_PROJECT_VERSION@"
+LINUX_MAINTAINER_EMAIL="@LINUX_MAINTAINER_EMAIL@"

+ 229 - 0
CI/include/build_support.sh

@@ -0,0 +1,229 @@
+#!/bin/bash
+
+##############################################################################
+# Unix support functions
+##############################################################################
+#
+# This script file can be included in build scripts for UNIX-compatible
+# shells to compose build scripts.
+#
+##############################################################################
+
+## DEFINE UTILITIES ##
+
+if [ -z "${QUIET}" ]; then
+    status() {
+        echo -e "${COLOR_BLUE}[${PRODUCT_NAME}] ${1}${COLOR_RESET}"
+    }
+
+    step() {
+        echo -e "${COLOR_GREEN}  + ${1}${COLOR_RESET}"
+    }
+
+    info() {
+        echo -e "${COLOR_ORANGE}  + ${1}${COLOR_RESET}"
+    }
+
+    error() {
+        echo -e "${COLOR_RED}  + ${1}${COLOR_RESET}"
+    }
+else
+    status() {
+        :
+    }
+
+    step() {
+        :
+    }
+
+    info() {
+        :
+    }
+
+    error() {
+        echo -e "${COLOR_RED}  + ${1}${COLOR_RESET}"
+    }
+fi
+
+exists() {
+  /usr/bin/command -v "$1" >/dev/null 2>&1
+}
+
+ensure_dir() {
+    [[ -n "${1}" ]] && /bin/mkdir -p "${1}" && builtin cd "${1}"
+}
+
+cleanup() {
+    :
+}
+
+caught_error() {
+    error "ERROR during build step: ${1}"
+    cleanup
+    exit 1
+}
+
+# Setup build environment
+
+BUILD_DIR="${BUILD_DIR:-build}"
+BUILD_CONFIG="${BUILD_CONFIG:-RelWithDebInfo}"
+CI_WORKFLOW="${CHECKOUT_DIR}/.github/workflows/main.yml"
+CURRENT_ARCH=$(uname -m)
+CURRENT_DATE="$(date +"%Y-%m-%d")"
+
+## Utility functions ##
+
+check_ccache() {
+    if ccache -V >/dev/null 2>&1; then
+        info "CCache available"
+        CMAKE_CCACHE_OPTIONS="-DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache"
+
+        if [ "${CI}" ]; then
+            ccache --set-config=cache_dir=${GITHUB_WORKSPACE:-${HOME}}/.ccache
+            ccache --set-config=max_size=${CCACHE_SIZE:-500M}
+            ccache --set-config=compression=true
+            ccache -z
+        fi
+    else
+        info "CCache not available"
+    fi
+}
+
+_add_ccache_to_path() {
+    if [ "${CMAKE_CCACHE_OPTIONS}" ]; then
+        PATH="/usr/local/opt/ccache/libexec:${PATH}"
+        status "Compiler Info:"
+        local IFS=$'\n'
+        for COMPILER_INFO in $(type cc c++ gcc g++ clang clang++ || true); do
+            info "${COMPILER_INFO}"
+        done
+    fi
+}
+
+safe_fetch() {
+    if [ $# -lt 2 ]; then
+        error "Usage: safe_fetch URL HASH"
+        return 1
+    fi
+
+    while true; do
+        case "${1}" in
+            -n | --nocontinue ) NOCONTINUE=TRUE; shift ;;
+            -- ) shift; break ;;
+            * ) break ;;
+        esac
+    done
+
+    DOWNLOAD_URL="${1}"
+    DOWNLOAD_HASH="${2}"
+    DOWNLOAD_FILE="$(basename ${DOWNLOAD_URL})"
+    CURLCMD=${CURLCMD:-curl}
+
+
+    if [ "${NOCONTINUE}" ]; then
+        ${CURLCMD/--continue-at -/} "${DOWNLOAD_URL}"
+    else
+        ${CURLCMD} "${DOWNLOAD_URL}"
+    fi
+
+    if [ "${DOWNLOAD_HASH}" = "$(sha256sum "${DOWNLOAD_FILE}" | cut -d " " -f 1)" ]; then
+        info "${DOWNLOAD_FILE} downloaded successfully and passed hash check"
+        return 0
+    else
+        error "${DOWNLOAD_FILE} downloaded successfully and failed hash check"
+        return 1
+    fi
+}
+
+check_and_fetch() {
+    if [ $# -lt 2 ]; then
+        caught_error "Usage: check_and_fetch URL HASH"
+    fi
+
+    while true; do
+        case "${1}" in
+            -n | --nocontinue ) NOCONTINUE=TRUE; shift ;;
+            -- ) shift; break ;;
+            * ) break ;;
+        esac
+    done
+
+    DOWNLOAD_URL="${1}"
+    DOWNLOAD_HASH="${2}"
+    DOWNLOAD_FILE="$(basename "${DOWNLOAD_URL}")"
+
+    if [ -f "${DOWNLOAD_FILE}" ] && [ "${DOWNLOAD_HASH}" = "$(sha256sum "${DOWNLOAD_FILE}" | cut -d " " -f 1)" ]; then
+        info "${DOWNLOAD_FILE} exists and passed hash check"
+        return 0
+    else
+        safe_fetch "${DOWNLOAD_URL}" "${DOWNLOAD_HASH}"
+    fi
+}
+
+github_fetch() {
+    if [ $# -ne 3 ]; then
+        error "Usage: github_fetch GITHUB_USER GITHUB_REPOSITORY GITHUB_COMMIT_HASH"
+        return 1
+    fi
+
+    GH_USER="${1}"
+    GH_REPO="${2}"
+    GH_REF="${3}"
+
+    if [ -d "./.git" ]; then
+        info "Repository ${GH_USER}/${GH_REPO} already exists, updating..."
+        git config advice.detachedHead false
+        git config remote.origin.url "https://github.com/${GH_USER}/${GH_REPO}.git"
+        git config remote.origin.fetch "+refs/heads/master:refs/remotes/origin/master"
+        git config remote.origin.tapOpt --no-tags
+
+        if ! git rev-parse -q --verify "${GH_COMMIT}^{commit}"; then
+            git fetch origin
+        fi
+
+        git checkout -f "${GH_REF}" --
+        git reset --hard "${GH_REF}" --
+        if [ -d "./.gitmodules" ]; then
+            git submodule foreach --recursive git submodule sync
+            git submodule update --init --recursive
+        fi
+
+    else
+        git clone "https://github.com/${GH_USER}/${GH_REPO}.git" "$(pwd)"
+        git config advice.detachedHead false
+        info "Checking out commit ${GH_REF}.."
+        git checkout -f "${GH_REF}" --
+
+        if [ -d "./.gitmodules" ]; then
+            git submodule foreach --recursive git submodule sync
+            git submodule update --init --recursive
+        fi
+    fi
+}
+
+apply_patch() {
+    if [ $# -ne 2 ]; then
+        error "Usage: apply_patch PATCH_URL PATCH_HASH"
+        return 1
+    fi
+
+    COMMIT_URL="${1}"
+    COMMIT_HASH="${2}"
+    PATCH_FILE="$(basename ${COMMIT_URL})"
+
+    if [ "${COMMIT_URL:0:5}" = "https" ]; then
+        ${CURLCMD:-curl} "${COMMIT_URL}"
+        if [ "${COMMIT_HASH}" = "$(sha256sum ${PATCH_FILE} | cut -d " " -f 1)" ]; then
+            info "${PATCH_FILE} downloaded successfully and passed hash check"
+        else
+            error "${PATCH_FILE} downloaded successfully and failed hash check"
+            return 1
+        fi
+
+        info "Applying patch ${COMMIT_URL}"
+    else
+        PATCH_FILE="${COMMIT_URL}"
+    fi
+
+    patch -g 0 -f -p1 -i "${PATCH_FILE}"
+}

+ 33 - 0
CI/include/build_support_linux.sh

@@ -0,0 +1,33 @@
+#!/bin/bash
+
+##############################################################################
+# Linux support functions
+##############################################################################
+#
+# This script file can be included in build scripts for Linux.
+#
+##############################################################################
+
+# Setup build environment
+
+CI_OBS_VERSION=$(cat "${CI_WORKFLOW}" | sed -En "s/[ ]+OBS_VERSION: '([0-9\.]+)'/\1/p")
+
+if [ "${TERM-}" -a -z "${CI}" ]; then
+    COLOR_RED=$(tput setaf 1)
+    COLOR_GREEN=$(tput setaf 2)
+    COLOR_BLUE=$(tput setaf 4)
+    COLOR_ORANGE=$(tput setaf 3)
+    COLOR_RESET=$(tput sgr0)
+else
+    COLOR_RED=""
+    COLOR_GREEN=""
+    COLOR_BLUE=""
+    COLOR_ORANGE=""
+    COLOR_RESET=""
+fi
+
+if [ "${CI}" -o "${QUIET}" ]; then
+    export CURLCMD="curl --silent --show-error --location -O"
+else
+    export CURLCMD="curl --progress-bar --location --continue-at - -O"
+fi

+ 149 - 0
CI/include/build_support_macos.sh

@@ -0,0 +1,149 @@
+#!/bin/bash
+
+##############################################################################
+# macOS support functions
+##############################################################################
+#
+# This script file can be included in build scripts for macOS.
+#
+##############################################################################
+
+# Setup build environment
+
+CI_DEPS_VERSION=$(/bin/cat "${CI_WORKFLOW}" | /usr/bin/sed -En "s/[ ]+DEPS_VERSION_MAC: '([0-9\-]+)'/\1/p")
+CI_DEPS_HASH=$(/bin/cat "${CI_WORKFLOW}" | /usr/bin/sed -En "s/[ ]+DEPS_HASH_MAC: '([0-9a-f]+)'/\1/p")
+CI_QT_VERSION=$(/bin/cat "${CI_WORKFLOW}" | /usr/bin/sed -En "s/[ ]+QT_VERSION_MAC: '([0-9\.]+)'/\1/p" | /usr/bin/head -1)
+CI_QT_HASH=$(/bin/cat "${CI_WORKFLOW}" | /usr/bin/sed -En "s/[ ]+QT_HASH_MAC: '([0-9a-f]+)'/\1/p")
+CI_MACOSX_DEPLOYMENT_TARGET=$(/bin/cat "${CI_WORKFLOW}" | /usr/bin/sed -En "s/[ ]+MACOSX_DEPLOYMENT_TARGET: '([0-9\.]+)'/\1/p")
+CI_OBS_VERSION=$(/bin/cat "${CI_WORKFLOW}" | /usr/bin/sed -En "s/[ ]+OBS_VERSION: '([0-9\.]+)'/\1/p")
+
+MACOS_VERSION="$(/usr/bin/sw_vers -productVersion)"
+MACOS_MAJOR="$(echo ${MACOS_VERSION} | /usr/bin/cut -d '.' -f 1)"
+MACOS_MINOR="$(echo ${MACOS_VERSION} | /usr/bin/cut -d '.' -f 2)"
+
+if [ "${TERM-}" -a -z "${CI}" ]; then
+    COLOR_RED=$(/usr/bin/tput setaf 1)
+    COLOR_GREEN=$(/usr/bin/tput setaf 2)
+    COLOR_BLUE=$(/usr/bin/tput setaf 4)
+    COLOR_ORANGE=$(/usr/bin/tput setaf 3)
+    COLOR_RESET=$(/usr/bin/tput sgr0)
+else
+    COLOR_RED=""
+    COLOR_GREEN=""
+    COLOR_BLUE=""
+    COLOR_ORANGE=""
+    COLOR_RESET=""
+fi
+
+## DEFINE UTILITIES ##
+check_macos_version() {
+    step "Check macOS version..."
+    MIN_VERSION=${MACOSX_DEPLOYMENT_TARGET:-${CI_MACOSX_DEPLOYMENT_TARGET}}
+    MIN_MAJOR=$(echo ${MIN_VERSION} | /usr/bin/cut -d '.' -f 1)
+    MIN_MINOR=$(echo ${MIN_VERSION} | /usr/bin/cut -d '.' -f 2)
+
+    if [ "${MACOS_MAJOR}" -lt "11" ] && [ "${MACOS_MINOR}" -lt "${MIN_MINOR}" ]; then
+        error "WARNING: Minimum required macOS version is ${MIN_VERSION}, but running on ${MACOS_VERSION}"
+    fi
+
+    if [ "${MACOS_MAJOR}" -ge "11" ]; then
+        export CODESIGN_LINKER="ON"
+    fi
+}
+
+install_homebrew_deps() {
+    if ! exists brew; then
+        error "Homebrew not found - please install homebrew (https://brew.sh)"
+        exit 1
+    fi
+
+    brew bundle --file "${CHECKOUT_DIR}/CI/include/Brewfile" ${QUIET:+--quiet}
+
+    check_curl
+}
+
+check_curl() {
+    if [ "${MACOS_MAJOR}" -lt "11" ] && [ "${MACOS_MINOR}" -lt "15" ]; then
+        if [ ! -d /usr/local/opt/curl ]; then
+            step "Installing Homebrew curl.."
+            brew install curl
+        fi
+
+        CURLCMD="/usr/local/opt/curl/bin/curl"
+    else
+        CURLCMD="curl"
+    fi
+
+    if [ "${CI}" -o "${QUIET}" ]; then
+        export CURLCMD="${CURLCMD} --silent --show-error --location -O"
+    else
+        export CURLCMD="${CURLCMD} --progress-bar --location --continue-at - -O"
+    fi
+}
+
+check_archs() {
+    step "Check Architecture..."
+    ARCH="${ARCH:-universal}"
+    if [ "${ARCH}" = "universal" ]; then
+        CMAKE_ARCHS="x86_64;arm64"
+    elif [ "${ARCH}" != "x86_64" -a "${ARCH}" != "arm64" ]; then
+        caught_error "Unsupported architecture '${ARCH}' provided"
+    else
+        CMAKE_ARCHS="${ARCH}"
+    fi
+}
+
+## SET UP CODE SIGNING AND NOTARIZATION CREDENTIALS ##
+##############################################################################
+# Apple Developer Identity needed:
+#
+#    + Signing the code requires a developer identity in the system's keychain
+#    + codesign will look up and find the identity automatically
+#
+##############################################################################
+read_codesign_ident() {
+    if [ ! -n "${CODESIGN_IDENT}" ]; then
+        step "Code-signing Setup"
+        read -p "${COLOR_ORANGE}  + Apple developer application identity: ${COLOR_RESET}" CODESIGN_IDENT
+    fi
+}
+
+read_codesign_ident_installer() {
+    if [ ! -n "${CODESIGN_IDENT_INSTALLER}" ]; then
+        step "Code-signing Setup for Installer"
+        read -p "${COLOR_ORANGE}  + Apple developer installer identity: ${COLOR_RESET}" CODESIGN_IDENT_INSTALLER
+    fi
+}
+
+##############################################################################
+# Apple Developer credentials necessary:
+#
+#   + Signing for distribution and notarization require an active Apple
+#     Developer membership
+#   + An Apple Development identity is needed for code signing
+#     (i.e. 'Apple Development: YOUR APPLE ID (PROVIDER)')
+#   + Your Apple developer ID is needed for notarization
+#   + An app-specific password is necessary for notarization from CLI
+#   + This password will be stored in your macOS keychain under the identifier
+#     'OBS-Codesign-Password'with access Apple's 'altool' only.
+##############################################################################
+
+read_codesign_pass() {
+    step "Notarization Setup"
+
+    if [ -z "${CODESIGN_IDENT_USER}" ]; then
+        read -p "${COLOR_ORANGE}  + Apple account id: ${COLOR_RESET}" CODESIGN_IDENT_USER
+    fi
+
+    if [ -z "${CODESIGN_IDENT_PASS}" ]; then
+        CODESIGN_IDENT_PASS=$(stty -echo; read -p "${COLOR_ORANGE}  + Apple developer password: ${COLOR_RESET}" secret; stty echo; echo $secret)
+        echo ""
+    fi
+
+    step "Updating notarization keychain"
+
+    echo -n "${COLOR_ORANGE}"
+    /usr/bin/xcrun altool --store-password-in-keychain-item "OBS-Codesign-Password" -u "${CODESIGN_IDENT_USER}" -p "${CODESIGN_IDENT_PASS}"
+    echo -n "${COLOR_RESET}"
+    CODESIGN_IDENT_SHORT=$(echo "${CODESIGN_IDENT}" | /usr/bin/sed -En "s/.+\((.+)\)/\1/p")
+}

+ 139 - 0
CI/include/build_support_windows.ps1

@@ -0,0 +1,139 @@
+$CIWorkflow = "${CheckoutDir}/.github/workflows/main.yml"
+
+$CIDepsVersion = Get-Content ${CIWorkflow} | Select-String "[ ]+DEPS_VERSION_WIN: '([0-9\-]+)'" | ForEach-Object{$_.Matches.Groups[1].Value}
+$CIQtVersion = Get-Content ${CIWorkflow} | Select-String "[ ]+QT_VERSION_WIN: '([0-9\.]+)'" | ForEach-Object{$_.Matches.Groups[1].Value}
+$CIObsVersion = Get-Content ${CIWorkflow} | Select-String "[ ]+OBS_VERSION: '([0-9\.]+)'" | ForEach-Object{$_.Matches.Groups[1].Value}
+
+function Write-Status {
+    param(
+        [parameter(Mandatory=$true)]
+        [string] $output
+    )
+
+    if (!($Quiet.isPresent)) {
+        if (Test-Path env:CI) {
+            Write-Host "[${ProductName}] ${output}"
+        } else {
+            Write-Host -ForegroundColor blue "[${ProductName}] ${output}"
+        }
+    }
+}
+
+function Write-Info {
+    param(
+        [parameter(Mandatory=$true)]
+        [string] $output
+    )
+
+    if (!($Quiet.isPresent)) {
+        if (Test-Path env:CI) {
+            Write-Host " + ${output}"
+        } else {
+            Write-Host -ForegroundColor DarkYellow " + ${output}"
+        }
+    }
+}
+
+function Write-Step {
+    param(
+        [parameter(Mandatory=$true)]
+        [string] $output
+    )
+
+    if (!($Quiet.isPresent)) {
+        if (Test-Path env:CI) {
+            Write-Host " + ${output}"
+        } else {
+            Write-Host -ForegroundColor green " + ${output}"
+        }
+    }
+}
+
+function Write-Error {
+    param(
+        [parameter(Mandatory=$true)]
+        [string] $output
+    )
+
+    if (Test-Path env:CI) {
+        Write-Host " + ${output}"
+    } else {
+        Write-Host -ForegroundColor red " + ${output}"
+    }
+}
+
+function Test-CommandExists {
+    param(
+        [parameter(Mandatory=$true)]
+        [string] $Command
+    )
+
+    $CommandExists = $false
+    $OldActionPref = $ErrorActionPreference
+    $ErrorActionPreference = "stop"
+
+    try {
+        if (Get-Command $Command) {
+            $CommandExists = $true
+        }
+    } Catch {
+        $CommandExists = $false
+    } Finally {
+        $ErrorActionPreference = $OldActionPref
+    }
+
+    return $CommandExists
+}
+
+function Ensure-Directory {
+    param(
+        [parameter(Mandatory=$true)]
+        [string] $Directory
+    )
+
+    if (!(Test-Path $Directory)) {
+        $null = New-Item -ItemType Directory -Force -Path $Directory
+    }
+
+    Set-Location -Path $Directory
+}
+
+$BuildDirectory = "$(if (Test-Path Env:BuildDirectory) { $env:BuildDirectory } else { $BuildDirectory })"
+$BuildConfiguration = "$(if (Test-Path Env:BuildConfiguration) { $env:BuildConfiguration } else { $BuildConfiguration })"
+$BuildArch = "$(if (Test-Path Env:BuildArch) { $env:BuildArch } else { $BuildArch })"
+$OBSBranch = "$(if (Test-Path Env:OBSBranch) { $env:OBSBranch } else { $OBSBranch })"
+$WindowsDepsVersion = "$(if (Test-Path Env:WindowsDepsVersion ) { $env:WindowsDepsVersion } else { $CIDepsVersion })"
+$WindowsQtVersion = "$(if (Test-Path Env:WindowsQtVersion ) { $env:WindowsQtVersion } else { $CIQtVersion }")
+$CmakeSystemVersion = "$(if (Test-Path Env:CMAKE_SYSTEM_VERSION) { $Env:CMAKE_SYSTEM_VERSION } else { "10.0.18363.657" })"
+$OBSVersion = "$(if ( Test-Path Env:OBSVersion ) { $env:ObsVersion } else { $CIObsVersion })"
+
+function Install-Windows-Dependencies {
+    Write-Status "Checking Windows build dependencies"
+
+    $ObsBuildDependencies = @(
+        @("7z", "7zip"),
+        @("cmake", "cmake --install-arguments 'ADD_CMAKE_TO_PATH=System'"),
+        @("iscc", "innosetup")
+    )
+
+    if(!(Test-CommandExists "choco")) {
+        Set-ExecutionPolicy AllSigned
+        Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
+    }
+
+    Foreach($Dependency in $ObsBuildDependencies) {
+        if($Dependency -is [system.array]) {
+            $Command = $Dependency[0]
+            $ChocoName = $Dependency[1]
+        } else {
+            $Command = $Dependency
+            $ChocoName = $Dependency
+        }
+
+        if(!(Test-CommandExists "${Command}")) {
+            Invoke-Expression "choco install -y ${ChocoName}"
+        }
+    }
+
+    $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
+}

+ 127 - 0
CI/linux/01_install_dependencies.sh

@@ -0,0 +1,127 @@
+#!/bin/bash
+
+##############################################################################
+# Linux dependency management function
+##############################################################################
+#
+# This script file can be included in build scripts for Linux or run directly
+#
+##############################################################################
+
+# Halt on errors
+set -eE
+
+install_obs-studio() {
+    if [ -n "${OBS_BRANCH}" ]; then
+        CHECKOUT_REF="${OBS_BRANCH}"
+    else
+        CHECKOUT_REF="tags/${OBS_VERSION:-${CI_OBS_VERSION}}"
+    fi
+
+    ensure_dir "${OBS_BUILD_DIR}"
+
+    if [ ! -d "${OBS_BUILD_DIR}/.git" ]; then
+        git clone --recursive https://github.com/obsproject/obs-studio "$(pwd)"
+        git fetch origin --tags
+        git checkout ${CHECKOUT_REF} -b obs-plugin-build
+    else
+        if ! git show-ref --verify --quiet refs/heads/obs-plugin-build; then
+            git checkout ${CHECKOUT_REF} -b obs-plugin-build
+        else
+            git checkout obs-plugin-build
+        fi
+    fi
+}
+
+install_linux_dependencies() {
+    sudo dpkg --add-architecture amd64
+    sudo apt-get -qq update
+    sudo apt-get install -y \
+        build-essential \
+        ninja-build \
+        clang \
+        clang-format \
+        qtbase5-dev \
+        libqt5svg5-dev \
+        libqt5x11extras5-dev \
+        qtbase5-private-dev \
+        libwayland-dev \
+        libavcodec-dev \
+        libavdevice-dev \
+        libavfilter-dev \
+        libavformat-dev \
+        libavutil-dev \
+        libswresample-dev \
+        libswscale-dev \
+        libx264-dev \
+        libjansson-dev \
+        libpulse-dev \
+        libx11-dev \
+        libx11-xcb-dev \
+        libmbedtls-dev \
+        libgl1-mesa-dev \
+        pkg-config \
+        libcurl4-openssl-dev
+
+    if ! type cmake &>/dev/null; then
+        sudo apt-get install -y cmake
+    fi
+}
+
+install_dependencies() {
+    status "Installing build dependencies"
+    trap "caught_error 'install_dependencies'" ERR
+
+    BUILD_DEPS=(
+        "obs-studio ${OBS_VERSION:-${CI_OBS_VERSION}}"
+    )
+
+    install_linux_dependencies
+
+    for DEPENDENCY in "${BUILD_DEPS[@]}"; do
+        set -- ${DEPENDENCY}
+        trap "caught_error ${DEPENDENCY}" ERR
+        FUNC_NAME="install_${1}"
+        ${FUNC_NAME} ${2} ${3}
+    done
+}
+
+install-dependencies-standalone() {
+    CHECKOUT_DIR="$(git rev-parse --show-toplevel)"
+    if [ -f "${CHECKOUT_DIR}/CI/include/build_environment.sh" ]; then
+        source "${CHECKOUT_DIR}/CI/include/build_environment.sh"
+    fi
+    PRODUCT_NAME="${PRODUCT_NAME:-obs-plugin}"
+    DEPS_BUILD_DIR="${CHECKOUT_DIR}/../obs-build-dependencies"
+    OBS_BUILD_DIR="${CHECKOUT_DIR}/../obs-studio"
+    source "${CHECKOUT_DIR}/CI/include/build_support.sh"
+    source "${CHECKOUT_DIR}/CI/include/build_support_linux.sh"
+
+    status "Setting up plugin build dependencies"
+    install_dependencies
+}
+
+print_usage() {
+    echo -e "Usage: ${0}\n" \
+            "-h, --help                     : Print this help\n" \
+            "-q, --quiet                    : Suppress most build process output\n" \
+            "-v, --verbose                  : Enable more verbose build process output\n"
+}
+
+install-dependencies-main() {
+    if [ -z "${_RUN_OBS_BUILD_SCRIPT}" ]; then
+        while true; do
+            case "${1}" in
+                -h | --help ) print_usage; exit 0 ;;
+                -q | --quiet ) export QUIET=TRUE; shift ;;
+                -v | --verbose ) export VERBOSE=TRUE; shift ;;
+                -- ) shift; break ;;
+                * ) break ;;
+            esac
+        done
+
+        install-dependencies-standalone
+    fi
+}
+
+install-dependencies-main $*

+ 73 - 0
CI/linux/02_build_obs_libs.sh

@@ -0,0 +1,73 @@
+#!/bin/bash
+
+##############################################################################
+# Linux libobs library build function
+##############################################################################
+#
+# This script file can be included in build scripts for Linux or run directly
+#
+##############################################################################
+
+# Halt on errors
+set -eE
+
+build_obs_libs() {
+    status "Build libobs and obs-frontend-api"
+    trap "caught_error 'build_obs_libs'" ERR
+    check_ccache
+
+    ensure_dir "${OBS_BUILD_DIR}"
+
+    step "Configuring OBS build system"
+    check_ccache
+    cmake -S . -B plugin_${BUILD_DIR} -G Ninja ${CMAKE_CCACHE_OPTIONS} \
+        -DCMAKE_BUILD_TYPE=${BUILD_CONFIG} \
+        -DENABLE_PLUGINS=OFF \
+        -DENABLE_UI=ON \
+        -DENABLE_SCRIPTING=OFF \
+        -DENABLE_PIPEWIRE=OFF \
+        ${QUIET:+-Wno-deprecated -Wno-dev --log-level=ERROR}
+
+    step "Building libobs and obs-frontend-api"
+    cmake --build plugin_${BUILD_DIR} -t obs-frontend-api
+}
+
+build-obs-libs-standalone() {
+    CHECKOUT_DIR="$(git rev-parse --show-toplevel)"
+    if [ -f "${CHECKOUT_DIR}/CI/include/build_environment.sh" ]; then
+        source "${CHECKOUT_DIR}/CI/include/build_environment.sh"
+    fi
+    PRODUCT_NAME="${PRODUCT_NAME:-obs-plugin}"
+    OBS_BUILD_DIR="${CHECKOUT_DIR}/../obs-studio"
+    source "${CHECKOUT_DIR}/CI/include/build_support.sh"
+    source "${CHECKOUT_DIR}/CI/include/build_support_linux.sh"
+
+    build_obs_libs
+}
+
+print_usage() {
+    echo -e "Usage: ${0}\n" \
+            "-h, --help                     : Print this help\n" \
+            "-q, --quiet                    : Suppress most build process output\n" \
+            "-v, --verbose                  : Enable more verbose build process output\n" \
+            "--build-dir                    : Specify alternative build directory (default: build)\n"
+}
+
+build-obs-libs-main() {
+    if [ -z "${_RUN_OBS_BUILD_SCRIPT}" ]; then
+        while true; do
+            case "${1}" in
+                -h | --help ) print_usage; exit 0 ;;
+                -q | --quiet ) export QUIET=TRUE; shift ;;
+                -v | --verbose ) export VERBOSE=TRUE; shift ;;
+                --build-dir ) BUILD_DIR="${2}"; shift 2 ;;
+                -- ) shift; break ;;
+                * ) break ;;
+            esac
+        done
+
+        build-obs-libs-standalone
+    fi
+}
+
+build-obs-libs-main $*

+ 66 - 0
CI/linux/03_build_plugin.sh

@@ -0,0 +1,66 @@
+#!/bin/bash
+
+##############################################################################
+# Linux libobs plugin build function
+##############################################################################
+#
+# This script file can be included in build scripts for Linux or run directly
+#
+##############################################################################
+
+# Halt on errors
+set -eE
+
+build_obs_plugin() {
+    status "Build plugin ${PRODUCT_NAME}"
+    trap "caught_error 'builds_obs_plugin'" ERR
+
+    ensure_dir "${CHECKOUT_DIR}"
+
+    step "Configuring OBS plugin build system"
+    check_ccache
+
+    cmake -S . -B ${BUILD_DIR} -G Ninja ${CMAKE_CCACHE_OPTIONS} ${QUIET:+-Wno-deprecated -Wno-dev --log-level=ERROR}
+
+    step "Building OBS plugin"
+    cmake --build ${BUILD_DIR}
+}
+
+build-plugin-standalone() {
+    CHECKOUT_DIR="$(git rev-parse --show-toplevel)"
+    if [ -f "${CHECKOUT_DIR}/CI/include/build_environment.sh" ]; then
+        source "${CHECKOUT_DIR}/CI/include/build_environment.sh"
+    fi
+    PRODUCT_NAME="${PRODUCT_NAME:-obs-plugin}"
+    source "${CHECKOUT_DIR}/CI/include/build_support.sh"
+    source "${CHECKOUT_DIR}/CI/include/build_support_linux.sh"
+
+    build_obs_plugin
+}
+
+print_usage() {
+    echo -e "Usage: ${0}\n" \
+            "-h, --help                     : Print this help\n" \
+            "-q, --quiet                    : Suppress most build process output\n" \
+            "-v, --verbose                  : Enable more verbose build process output\n" \
+            "--build-dir                    : Specify alternative build directory (default: build)\n"
+}
+
+build-plugin-main() {
+    if [ -z "${_RUN_OBS_BUILD_SCRIPT}" ]; then
+        while true; do
+            case "${1}" in
+                -h | --help ) print_usage; exit 0 ;;
+                -q | --quiet ) export QUIET=TRUE; shift ;;
+                -v | --verbose ) export VERBOSE=TRUE; shift ;;
+                --build-dir ) BUILD_DIR="${2}"; shift 2 ;;
+                -- ) shift; break ;;
+                * ) break ;;
+            esac
+        done
+
+        build-plugin-standalone
+    fi
+}
+
+build-plugin-main $*

+ 68 - 0
CI/linux/04_package_plugin.sh

@@ -0,0 +1,68 @@
+#!/bin/bash
+
+##############################################################################
+# Linux libobs plugin build function
+##############################################################################
+#
+# This script file can be included in build scripts for Linux or run directly
+#
+##############################################################################
+
+# Halt on errors
+set -eE
+
+package_obs_plugin() {
+    status "Package OBS plugin ${PRODUCT_NAME}"
+    trap "caught_error 'package_obs_plugin'" ERR
+
+    ensure_dir "${CHECKOUT_DIR}"
+
+    step "Package ${PRODUCT_NAME}..."
+
+    cmake --build ${BUILD_DIR} -t package
+
+}
+
+package-plugin-standalone() {
+    CHECKOUT_DIR="$(git rev-parse --show-toplevel)"
+    if [ -f "${CHECKOUT_DIR}/CI/include/build_environment.sh" ]; then
+        source "${CHECKOUT_DIR}/CI/include/build_environment.sh"
+    fi
+    PRODUCT_NAME="${PRODUCT_NAME:-obs-plugin}"
+    source "${CHECKOUT_DIR}/CI/include/build_support.sh"
+    source "${CHECKOUT_DIR}/CI/include/build_support_linux.sh"
+
+    GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
+    GIT_HASH=$(git rev-parse --short HEAD)
+    GIT_TAG=$(git describe --tags --abbrev=0 2&>/dev/null || true)
+    FILE_NAME="${PRODUCT_NAME}-${GIT_TAG:-0.0.1}-${GIT_HASH}.deb"
+
+    package_obs_plugin
+}
+
+print_usage() {
+    echo -e "Usage: ${0}\n" \
+            "-h, --help                     : Print this help\n" \
+            "-q, --quiet                    : Suppress most build process output\n" \
+            "-v, --verbose                  : Enable more verbose build process output\n" \
+            "--build-dir                    : Specify alternative build directory (default: build)\n"
+}
+
+package-plugin-main() {
+    if [ ! -n "${_RUN_OBS_BUILD_SCRIPT}" ]; then
+        while true; do
+            case "${1}" in
+                -h | --help ) print_usage; exit 0 ;;
+                -q | --quiet ) export QUIET=TRUE; shift ;;
+                -v | --verbose ) export VERBOSE=TRUE; shift ;;
+                --build-dir ) BUILD_DIR="${2}"; shift 2 ;;
+                -- ) shift; break ;;
+                * ) break ;;
+            esac
+        done
+
+        package-plugin-standalone
+    fi
+}
+
+package-plugin-main $*

+ 120 - 0
CI/macos/01_install_dependencies.sh

@@ -0,0 +1,120 @@
+#!/bin/bash
+
+##############################################################################
+# macOS dependency management function
+##############################################################################
+#
+# This script file can be included in build scripts for macOS or run directly
+#
+##############################################################################
+
+# Halt on errors
+set -eE
+
+install_obs-deps() {
+    status "Set up precompiled macOS OBS dependencies v${1}"
+    ensure_dir "${DEPS_BUILD_DIR}"
+    step "Download..."
+    check_and_fetch "https://github.com/obsproject/obs-deps/releases/download/${1}/macos-deps-${1}-universal.tar.xz" "${2}"
+    mkdir -p obs-deps
+    step "Unpack..."
+    /usr/bin/tar -xf "./macos-deps-${1}-universal.tar.xz" -C ./obs-deps
+    /usr/bin/xattr -r -d com.apple.quarantine ./obs-deps
+}
+
+install_qt-deps() {
+    status "Set up precompiled dependency Qt v${1}"
+    ensure_dir "${DEPS_BUILD_DIR}"
+    step "Download..."
+    check_and_fetch "https://github.com/obsproject/obs-deps/releases/download/${1}/macos-deps-qt-${1}-universal.tar.xz" "${2}"
+    mkdir -p obs-deps
+    step "Unpack..."
+    /usr/bin/tar -xf "./macos-deps-qt-${1}-universal.tar.xz" -C ./obs-deps
+    /usr/bin/xattr -r -d com.apple.quarantine ./obs-deps
+}
+
+install_obs-studio() {
+    if [ "${OBS_BRANCH}" ]; then
+        CHECKOUT_REF="${OBS_BRANCH}"
+    else
+        CHECKOUT_REF="tags/${OBS_VERSION:-${CI_OBS_VERSION}}"
+    fi
+
+    ensure_dir "${OBS_BUILD_DIR}"
+
+    if [ ! -d "${OBS_BUILD_DIR}/.git" ]; then
+        /usr/bin/git clone --recursive https://github.com/obsproject/obs-studio "$(pwd)"
+        /usr/bin/git fetch origin --tags
+        /usr/bin/git checkout ${CHECKOUT_REF} -b obs-plugin-build
+    else
+        if ! /usr/bin/git show-ref --verify --quiet refs/heads/obs-plugin-build; then
+            /usr/bin/git checkout ${CHECKOUT_REF} -b obs-plugin-build
+        else
+            /usr/bin/git checkout obs-plugin-build
+        fi
+    fi
+}
+
+install_dependencies() {
+    status "Installing Homebrew dependencies"
+    trap "caught_error 'install_dependencies'" ERR
+
+    BUILD_DEPS=(
+        "obs-deps ${MACOS_DEPS_VERSION:-${CI_DEPS_VERSION}} ${MACOS_DEPS_HASH:-${CI_DEPS_HASH}}"
+        "qt-deps ${MACOS_DEPS_VERSION:-${CI_DEPS_VERSION}} ${QT_HASH:-${CI_QT_HASH}}"
+        "obs-studio ${OBS_VERSION:-${CI_OBS_VERSION}}"
+    )
+
+    install_homebrew_deps
+
+    for DEPENDENCY in "${BUILD_DEPS[@]}"; do
+        set -- ${DEPENDENCY}
+        trap "caught_error ${DEPENDENCY}" ERR
+        FUNC_NAME="install_${1}"
+        ${FUNC_NAME} ${2} ${3}
+    done
+}
+
+install-dependencies-standalone() {
+    CHECKOUT_DIR="$(/usr/bin/git rev-parse --show-toplevel)"
+    if [ -f "${CHECKOUT_DIR}/CI/include/build_environment.sh" ]; then
+        source "${CHECKOUT_DIR}/CI/include/build_environment.sh"
+    fi
+    PRODUCT_NAME="${PRODUCT_NAME:-obs-plugin}"
+    DEPS_BUILD_DIR="${CHECKOUT_DIR}/../obs-build-dependencies"
+    OBS_BUILD_DIR="${CHECKOUT_DIR}/../obs-studio"
+    source "${CHECKOUT_DIR}/CI/include/build_support.sh"
+    source "${CHECKOUT_DIR}/CI/include/build_support_macos.sh"
+
+    status "Setting up plugin build dependencies"
+    check_macos_version
+    check_archs
+    install_dependencies
+}
+
+print_usage() {
+    echo -e "Usage: ${0}\n" \
+            "-h, --help                     : Print this help\n" \
+            "-q, --quiet                    : Suppress most build process output\n" \
+            "-v, --verbose                  : Enable more verbose build process output\n" \
+            "-a, --architecture             : Specify build architecture (default: universal, alternative: x86_64, arm64)\n"
+}
+
+install-dependencies-main() {
+    if [ -z "${_RUN_OBS_BUILD_SCRIPT}" ]; then
+        while true; do
+            case "${1}" in
+                -h | --help ) print_usage; exit 0 ;;
+                -q | --quiet ) export QUIET=TRUE; shift ;;
+                -v | --verbose ) export VERBOSE=TRUE; shift ;;
+                -a | --architecture ) ARCH="${2}"; shift 2 ;;
+                -- ) shift; break ;;
+                * ) break ;;
+            esac
+        done
+
+        install-dependencies-standalone
+    fi
+}
+
+install-dependencies-main $*

+ 79 - 0
CI/macos/02_build_obs_libs.sh

@@ -0,0 +1,79 @@
+#!/bin/bash
+
+##############################################################################
+# macOS libobs library build function
+##############################################################################
+#
+# This script file can be included in build scripts for macOS or run directly
+#
+##############################################################################
+
+# Halt on errors
+set -eE
+
+build_obs_libs() {
+    status "Build libobs and obs-frontend-api"
+    trap "caught_error 'build_obs_libs'" ERR
+
+    ensure_dir "${OBS_BUILD_DIR}"
+
+    step "Configuring OBS build system"
+    check_ccache
+    cmake -S . -B plugin_${BUILD_DIR} -G Ninja ${CMAKE_CCACHE_OPTIONS} \
+        -DCMAKE_OSX_ARCHITECTURES="${CMAKE_ARCHS}" \
+        -DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET:-${CI_MACOSX_DEPLOYMENT_TARGET}} \
+        -DOBS_CODESIGN_LINKER=${CODESIGN_LINKER:-OFF} \
+        -DCMAKE_BUILD_TYPE=${BUILD_CONFIG} \
+        -DENABLE_PLUGINS=OFF \
+        -DENABLE_UI=ON \
+        -DENABLE_SCRIPTING=OFF \
+        -DCMAKE_PREFIX_PATH="${DEPS_BUILD_DIR}/obs-deps" \
+        ${QUIET:+-Wno-deprecated -Wno-dev --log-level=ERROR}
+
+    step "Building libobs and obs-frontend-api"
+    cmake --build plugin_${BUILD_DIR} -t obs-frontend-api
+}
+
+build-obs-libs-standalone() {
+    CHECKOUT_DIR="$(/usr/bin/git rev-parse --show-toplevel)"
+    if [ -f "${CHECKOUT_DIR}/CI/include/build_environment.sh" ]; then
+        source "${CHECKOUT_DIR}/CI/include/build_environment.sh"
+    fi
+    PRODUCT_NAME="${PRODUCT_NAME:-obs-plugin}"
+    OBS_BUILD_DIR="${CHECKOUT_DIR}/../obs-studio"
+    source "${CHECKOUT_DIR}/CI/include/build_support.sh"
+    source "${CHECKOUT_DIR}/CI/include/build_support_macos.sh"
+
+    check_macos_version
+    check_archs
+    build_obs_libs
+}
+
+print_usage() {
+    echo -e "Usage: ${0}\n" \
+            "-h, --help                     : Print this help\n" \
+            "-q, --quiet                    : Suppress most build process output\n" \
+            "-v, --verbose                  : Enable more verbose build process output\n" \
+            "-a, --architecture             : Specify build architecture (default: universal, alternative: x86_64, arm64)\n" \
+            "--build-dir                    : Specify alternative build directory (default: build)\n"
+}
+
+build-obs-libs-main() {
+    if [ -z "${_RUN_OBS_BUILD_SCRIPT}" ]; then
+        while true; do
+            case "${1}" in
+                -h | --help ) print_usage; exit 0 ;;
+                -q | --quiet ) export QUIET=TRUE; shift ;;
+                -v | --verbose ) export VERBOSE=TRUE; shift ;;
+                -a | --architecture ) ARCH="${2}"; shift 2 ;;
+                --build-dir ) BUILD_DIR="${2}"; shift 2 ;;
+                -- ) shift; break ;;
+                * ) break ;;
+            esac
+        done
+
+        build-obs-libs-standalone
+    fi
+}
+
+build-obs-libs-main $*

+ 85 - 0
CI/macos/03_build_plugin.sh

@@ -0,0 +1,85 @@
+#!/bin/bash
+
+##############################################################################
+# macOS libobs plugin build function
+##############################################################################
+#
+# This script file can be included in build scripts for macOS or run directly
+#
+##############################################################################
+
+# Halt on errors
+set -eE
+
+build_obs_plugin() {
+    status "Build plugin ${PRODUCT_NAME}"
+    trap "caught_error 'builds_obs_plugin'" ERR
+
+    if [ "${CODESIGN}" ]; then
+        read_codesign_ident
+    fi
+
+    ensure_dir "${CHECKOUT_DIR}"
+    step "Configuring OBS plugin build system"
+    check_ccache
+
+    cmake -S . -B ${BUILD_DIR} -G Ninja ${CMAKE_CCACHE_OPTIONS} \
+        -DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET:-${CI_MACOSX_DEPLOYMENT_TARGET}} \
+        -DCMAKE_OSX_ARCHITECTURES="${CMAKE_ARCHS}" \
+        -DOBS_CODESIGN_LINKER=${CODESIGN_LINKER:-OFF} \
+        -DCMAKE_BUILD_TYPE=${BUILD_CONFIG} \
+        -DOBS_BUNDLE_CODESIGN_IDENTITY="${CODESIGN_IDENT:--}" \
+        -DCMAKE_PREFIX_PATH="${DEPS_BUILD_DIR}/obs-deps" \
+        ${QUIET:+-Wno-deprecated -Wno-dev --log-level=ERROR}
+
+    step "Building OBS plugin"
+    cmake --build ${BUILD_DIR}
+
+}
+
+build-plugin-standalone() {
+    CHECKOUT_DIR="$(/usr/bin/git rev-parse --show-toplevel)"
+    if [ -f "${CHECKOUT_DIR}/CI/include/build_environment.sh" ]; then
+        source "${CHECKOUT_DIR}/CI/include/build_environment.sh"
+    fi
+    PRODUCT_NAME="${PRODUCT_NAME:-obs-plugin}"
+    DEPS_BUILD_DIR="${CHECKOUT_DIR}/../obs-build-dependencies"
+    source "${CHECKOUT_DIR}/CI/include/build_support.sh"
+    source "${CHECKOUT_DIR}/CI/include/build_support_macos.sh"
+
+    check_macos_version
+    check_archs
+
+    build_obs_plugin
+}
+
+print_usage() {
+    echo -e "Usage: ${0}\n" \
+            "-h, --help                     : Print this help\n" \
+            "-q, --quiet                    : Suppress most build process output\n" \
+            "-v, --verbose                  : Enable more verbose build process output\n" \
+            "-a, --architecture             : Specify build architecture (default: x86_64, alternative: arm64)\n" \
+            "-c, --codesign                 : Codesign OBS and all libraries (default: ad-hoc only)\n" \
+            "--build-dir                    : Specify alternative build directory (default: build)\n"
+}
+
+build-plugin-main() {
+    if [ -z "${_RUN_OBS_BUILD_SCRIPT}" ]; then
+        while true; do
+            case "${1}" in
+                -h | --help ) print_usage; exit 0 ;;
+                -q | --quiet ) export QUIET=TRUE; shift ;;
+                -v | --verbose ) export VERBOSE=TRUE; shift ;;
+                -c | --codesign ) CODESIGN=TRUE; shift ;;
+                -a | --architecture ) ARCH="${2}"; shift 2 ;;
+                --build-dir ) BUILD_DIR="${2}"; shift 2 ;;
+                -- ) shift; break ;;
+                * ) break ;;
+            esac
+        done
+
+        build-plugin-standalone
+    fi
+}
+
+build-plugin-main $*

+ 150 - 0
CI/macos/04_package_plugin.sh

@@ -0,0 +1,150 @@
+#!/bin/bash
+
+##############################################################################
+# macOS libobs plugin package function
+##############################################################################
+#
+# This script file can be included in build scripts for macOS or run directly
+#
+##############################################################################
+
+# Halt on errors
+set -eE
+
+package_obs_plugin() {
+    if [ "${CODESIGN}" ]; then
+        read_codesign_ident
+    fi
+
+    status "Package OBS plugin ${PRODUCT_NAME}"
+    trap "caught_error 'package_obs_plugin'" ERR
+
+    ensure_dir "${CHECKOUT_DIR}"
+
+    if [ -d "${BUILD_DIR}/rundir/${PRODUCT_NAME}.plugin" ]; then
+        rm -rf "${BUILD_DIR}/rundir/${PRODUCT_NAME}.plugin"
+    fi
+
+    cmake --install ${BUILD_DIR}
+
+    if ! type packagesbuild &>/dev/null; then
+        status "Setting up dependency Packages.app"
+        step "Download..."
+        check_and_fetch "http://s.sudre.free.fr/Software/files/Packages.dmg" "70ac111417728c17b1f27d5520afd87c33f899f12de8ace0f703e3e1c500b28e"
+
+        step "Mount disk image..."
+        hdiutil attach -noverify Packages.dmg
+
+        step "Install Packages.app"
+        PACKAGES_VOLUME=$(hdiutil info -plist | grep "/Volumes/Packages" | sed 's/<string>\/Volumes\/\([^<]*\)<\/string>/\1/' | sed -e 's/^[[:space:]]*//')
+        sudo installer -pkg "/Volumes/${PACKAGES_VOLUME}/packages/Packages.pkg" -target /
+        hdiutil detach "/Volumes/${PACKAGES_VOLUME}"
+    fi
+
+    step "Package ${PRODUCT_NAME}..."
+    packagesbuild ./bundle/installer-macOS.generated.pkgproj
+
+    step "Codesigning installer package..."
+    read_codesign_ident_installer
+
+    /usr/bin/productsign --sign "${CODESIGN_IDENT_INSTALLER}" "${BUILD_DIR}/${PRODUCT_NAME}.pkg" "${FILE_NAME}"
+}
+
+notarize_obs_plugin() {
+    status "Notarize ${PRODUCT_NAME}"
+    trap "caught_error 'notarize_obs_plugin'" ERR
+
+    if ! exists brew; then
+        error "Homebrew not found - please install homebrew (https://brew.sh)"
+        exit 1
+    fi
+
+    if ! exists xcnotary; then
+        step "Install notarization dependency 'xcnotary'"
+        brew install akeru-inc/tap/xcnotary
+    fi
+
+    ensure_dir "${CHECKOUT_DIR}"
+
+    if [ -f "${FILE_NAME}" ]; then
+        xcnotary precheck "${FILE_NAME}"
+    else
+        error "No notarization package installer ('${FILE_NAME}') found"
+        return
+    fi
+
+    if [ "$?" -eq 0 ]; then
+        read_codesign_ident_installer
+        read_codesign_pass
+
+        step "Run xcnotary with ${FILE_NAME}..."
+        xcnotary notarize "${FILE_NAME}" --developer-account "${CODESIGN_IDENT_USER}" --developer-password-keychain-item "OBS-Codesign-Password" --provider "${CODESIGN_IDENT_SHORT}"
+    fi
+}
+
+package-plugin-standalone() {
+    CHECKOUT_DIR="$(/usr/bin/git rev-parse --show-toplevel)"
+    ensure_dir "${CHECKOUT_DIR}"
+    if [ -f "${CHECKOUT_DIR}/CI/include/build_environment.sh" ]; then
+        source "${CHECKOUT_DIR}/CI/include/build_environment.sh"
+    fi
+    PRODUCT_NAME="${PRODUCT_NAME:-obs-plugin}"
+    source "${CHECKOUT_DIR}/CI/include/build_support.sh"
+    source "${CHECKOUT_DIR}/CI/include/build_support_macos.sh"
+
+    GIT_BRANCH=$(/usr/bin/git rev-parse --abbrev-ref HEAD)
+    GIT_HASH=$(/usr/bin/git rev-parse --short HEAD)
+    GIT_TAG=$(/usr/bin/git describe --tags --abbrev=0 2&>/dev/null || true)
+
+    check_macos_version
+    check_archs
+
+    if [ "${ARCH}" = "arm64" ]; then
+        FILE_NAME="${PRODUCT_NAME}-${GIT_TAG:-${PRODUCT_VERSION}}-${GIT_HASH}-macOS-Apple.pkg"
+    elif [ "${ARCH}" = "x86_64" ]; then
+        FILE_NAME="${PRODUCT_NAME}-${GIT_TAG:-${PRODUCT_VERSION}}-${GIT_HASH}-macOS-Intel.pkg"
+    else
+        FILE_NAME="${PRODUCT_NAME}-${GIT_TAG:-${PRODUCT_VERSION}}-${GIT_HASH}-macOS-Universal.pkg"
+    fi
+
+    check_curl
+    package_obs_plugin
+
+    if [ "${NOTARIZE}" ]; then
+        notarize_obs_plugin
+    fi
+}
+
+print_usage() {
+    echo -e "Usage: ${0}\n" \
+            "-h, --help                     : Print this help\n" \
+            "-q, --quiet                    : Suppress most build process output\n" \
+            "-v, --verbose                  : Enable more verbose build process output\n" \
+            "-a, --architecture             : Specify build architecture (default: x86_64, alternative: arm64)\n" \
+            "-c, --codesign                 : Codesign OBS and all libraries (default: ad-hoc only)\n" \
+            "-n, --notarize                 : Notarize OBS (default: off)\n" \
+            "--build-dir                    : Specify alternative build directory (default: build)\n"
+}
+
+package-plugin-main() {
+    if [ -z "${_RUN_OBS_BUILD_SCRIPT}" ]; then
+        while true; do
+            case "${1}" in
+                -h | --help ) print_usage; exit 0 ;;
+                -q | --quiet ) export QUIET=TRUE; shift ;;
+                -v | --verbose ) export VERBOSE=TRUE; shift ;;
+                -a | --architecture ) ARCH="${2}"; shift 2 ;;
+                -c | --codesign ) CODESIGN=TRUE; shift ;;
+                -n | --notarize ) NOTARIZE=TRUE; CODESIGN=TRUE; shift ;;
+                -s | --standalone ) STANDALONE=TRUE; shift ;;
+                --build-dir ) BUILD_DIR="${2}"; shift 2 ;;
+                -- ) shift; break ;;
+                * ) break ;;
+            esac
+        done
+
+        package-plugin-standalone
+    fi
+}
+
+package-plugin-main $*

+ 11 - 0
CI/utility/check-format.sh

@@ -0,0 +1,11 @@
+#!/bin/bash
+dirty=$(git ls-files --modified)
+
+set +x
+if [[ $dirty ]]; then
+	echo "================================="
+    echo "Files were not formatted properly"
+    echo "$dirty"
+    echo "================================="
+    exit 1
+fi

+ 60 - 0
CI/utility/formatcode.sh

@@ -0,0 +1,60 @@
+#!/usr/bin/env bash
+# Original source https://github.com/Project-OSRM/osrm-backend/blob/master/scripts/format.sh
+
+set -o errexit
+set -o pipefail
+set -o nounset
+
+if [ ${#} -eq 1 ]; then
+    VERBOSITY="--verbose"
+else
+    VERBOSITY=""
+fi
+
+# Runs the Clang Formatter in parallel on the code base.
+# Return codes:
+#  - 1 there are files to be formatted
+#  - 0 everything looks fine
+
+# Get CPU count
+OS=$(uname)
+NPROC=1
+if [[ ${OS} = "Linux" ]] ; then
+    NPROC=$(nproc)
+elif [[ ${OS} = "Darwin" ]] ; then
+    NPROC=$(sysctl -n hw.physicalcpu)
+fi
+
+# Discover clang-format
+if type clang-format-12 2> /dev/null ; then
+    CLANG_FORMAT=clang-format-12
+elif type clang-format 2> /dev/null ; then
+    # Clang format found, but need to check version
+    CLANG_FORMAT=clang-format
+    V=$(clang-format --version)
+    if [[ $V != *"version 12.0"* ]]; then
+        echo "clang-format is not 12.0 (returned ${V})"
+        exit 1
+    fi
+else
+    echo "No appropriate clang-format found (expected clang-format-12.0.0, or clang-format)"
+    exit 1
+fi
+
+find . -type d \( \
+    -path ./\*build -o \
+    -path ./cmake -o \
+    -path ./deps -o \
+    -path ./plugins/decklink/\*/decklink-sdk -o \
+    -path ./plugins/enc-amf -o \
+    -path ./plugins/mac-syphon/syphon-framework -o \
+    -path ./plugins/obs-outputs/ftl-sdk -o \
+    -path ./plugins/obs-vst \
+\) -prune -false -type f -o \
+    -name '*.h' -or \
+    -name '*.hpp' -or \
+    -name '*.m' -or \
+    -name '*.m,' -or \
+    -name '*.c' -or \
+    -name '*.cpp' \
+ | xargs -L100 -P ${NPROC} ${CLANG_FORMAT} ${VERBOSITY} -i -style=file -fallback-style=none

+ 158 - 0
CI/windows/01_install_dependencies.ps1

@@ -0,0 +1,158 @@
+Param(
+    [Switch]$Help = $(if (Test-Path variable:Help) { $Help }),
+    [Switch]$Quiet = $(if (Test-Path variable:Quiet) { $Quiet }),
+    [Switch]$Verbose = $(if (Test-Path variable:Verbose) { $Verbose }),
+    [Switch]$NoChoco = $(if (Test-Path variable:NoChoco) { $true } else { $false }),
+    [String]$BuildArch = $(if (Test-Path variable:BuildArch) { "${BuildArch}" } else { (Get-CimInstance CIM_OperatingSystem).OSArchitecture }),
+    [String]$ProductName = $(if (Test-Path variable:ProductName) { "${ProductName}" } else { "obs-plugin" })
+)
+
+##############################################################################
+# Windows dependency management function
+##############################################################################
+#
+# This script file can be included in build scripts for Windows or run
+# directly
+#
+##############################################################################
+
+$ErrorActionPreference = "Stop"
+
+Function Install-obs-deps {
+    Param(
+        [Parameter(Mandatory=$true)]
+        [String]$Version
+    )
+
+    Write-Status "Setup for pre-built Windows OBS dependencies v${Version}"
+    Ensure-Directory $DepsBuildDir
+
+    if (!(Test-Path $DepsBuildDir/dependencies${Version})) {
+        Write-Status "Setting up pre-built Windows OBS dependencies v${Version}"
+
+        Write-Step "Download..."
+        $ProgressPreference = $(if ($Quiet.isPresent) { "SilentlyContinue" } else { "Continue" })
+        Invoke-WebRequest -Uri "https://cdn-fastly.obsproject.com/downloads/dependencies${Version}.zip" -UseBasicParsing -OutFile "dependencies${Version}.zip"
+        $ProgressPreference = 'Continue'
+
+        Write-Step "Unpack..."
+
+        Expand-Archive -Path "dependencies${Version}.zip"
+    } else {
+        Write-Step "Found existing pre-built dependencies..."
+
+    }
+}
+
+function Install-qt-deps {
+    Param(
+        [Parameter(Mandatory=$true)]
+        [String]$Version
+    )
+
+    Write-Status "Setup for pre-built dependency Qt v${Version}"
+    Ensure-Directory $DepsBuildDir
+
+    if (!(Test-Path $DepsBuildDir/Qt_${Version})) {
+        Write-Status "Setting up OBS dependency Qt v${Version}"
+
+        Write-Step "Download..."
+        $ProgressPreference = $(if ($Quiet.isPresent) { 'SilentlyContinue' } else { 'Continue' })
+        Invoke-WebRequest -Uri "https://cdn-fastly.obsproject.com/downloads/Qt_${Version}.7z" -UseBasicParsing -OutFile "Qt_${Version}.7z"
+        $ProgressPreference = 'Continue'
+        
+        Write-Step "Unpack..."
+
+        # TODO: Replace with zip and properly package Qt to share directory with other deps
+        & 7z x Qt_${Version}.7z
+        & mv ${Version} "Qt_${Version}"
+    } else {
+        Write-Step "Found existing pre-built Qt..."
+    }
+}
+
+function Install-obs-studio {
+    Param(
+        [parameter(Mandatory=$true)]
+        [string]$Version
+    )
+
+    $CheckoutRef = "$(if (!(Test-Path variable:OBSBranch)) { ${OBSBranch} } else { "tags/${OBSVersion}" })"
+
+    Write-Status "Setup for OBS Studio v${CheckoutRef}"
+    Ensure-Directory ${ObsBuildDir}
+
+    if (!(Test-Path "${ObsBuildDir}/.git")) {
+        & git clone --recursive https://github.com/obsproject/obs-studio "${pwd}"
+        & git fetch origin --tags
+        & git checkout ${CheckoutRef} -b obs-plugin-build
+    } else {
+        $BranchExists = &git show-ref --verify --quiet refs/heads/obs-plugin-build
+
+        if ($BranchExists -Eq $false) {
+            & git checkout ${CheckoutRef} -b obs-plugin-build
+        } else {
+            & git checkout obs-plugin-build
+        }
+    }
+}
+
+function Install-Dependencies {
+    if(!($NoChoco.isPresent)) {
+        Install-Windows-Dependencies
+    }
+
+    $BuildDependencies = @(
+        @('obs-deps', $WindowsDepsVersion),
+        @('qt-deps', $WindowsQtVersion),
+        @('obs-studio', $OBSVersion)
+    )
+
+    Foreach($Dependency in ${BuildDependencies}) {
+        $DependencyName = $Dependency[0]
+        $DependencyVersion = $Dependency[1]
+
+        $FunctionName = "Install-${DependencyName}"
+        & $FunctionName -Version $DependencyVersion
+    }
+
+    Ensure-Directory ${CheckoutDir}
+}
+
+function Install-Dependencies-Standalone {
+    $CheckoutDir = git rev-parse --show-toplevel
+
+    if (Test-Path ${CheckoutDir}/CI/include/build_environment.ps1) {
+        . ${CheckoutDir}/CI/include/build_environment.ps1
+    }
+
+    $DepsBuildDir = "${CheckoutDir}/../obs-build-dependencies"
+    $ObsBuildDir = "${CheckoutDir}/../obs-studio"
+
+    . ${CheckoutDir}/CI/include/build_support_windows.ps1
+
+    Write-Status "Setting up plugin build dependencies"
+    Install-Dependencies
+}
+
+function Print-Usage {
+    $Lines = @(
+        "Usage: ${MyInvocation.MyCommand.Name}",
+        "-Help                    : Print this help",
+        "-Quiet                   : Suppress most build process output",
+        "-Verbose                 : Enable more verbose build process output",
+        "-NoChoco                 : Skip automatic dependency installation via Chocolatey - Default: on"
+        "-BuildArch               : Build architecture to use (32bit or 64bit) - Default: local architecture"
+    )
+
+    $Lines | Write-Host
+}
+
+if(!(Test-Path variable:_RunObsBuildScript)) {
+    if ($Help.isPresent) {
+        Print-Usage
+        exit 0
+    }
+
+    Install-Dependencies-Standalone
+}

+ 102 - 0
CI/windows/02_build_obs_libs.ps1

@@ -0,0 +1,102 @@
+Param(
+    [Switch]$Help = $(if (Test-Path variable:Help) { $Help }),
+    [Switch]$Quiet = $(if (Test-Path variable:Quiet) { $Quiet }),
+    [Switch]$Verbose = $(if (Test-Path variable:Verbose) { $Verbose }),
+    [String]$ProductName = $(if (Test-Path variable:ProductName) { "${ProductName}" } else { "obs-plugin" }),
+    [String]$BuildDirectory = $(if (Test-Path variable:BuildDirectory) { "${BuildDirectory}" } else { "build" }),
+    [String]$BuildArch = $(if (Test-Path variable:BuildArch) { "${BuildArch}" } else { (Get-WmiObject Win32_OperatingSystem).OSArchitecture}),
+    [String]$BuildConfiguration = $(if (Test-Path variable:BuildConfiguration) { "${BuildConfiguration}" } else { "RelWithDebInfo" })
+)
+
+##############################################################################
+# Windows libobs library build function
+##############################################################################
+#
+# This script file can be included in build scripts for Windows or run
+# directly
+#
+##############################################################################
+
+$ErrorActionPreference = "Stop"
+
+function Build-OBS-Libs {
+    Param(
+        [String]$BuildDirectory = $(if (Test-Path variable:BuildDirectory) { "${BuildDirectory}" }),
+        [String]$BuildArch = $(if (Test-Path variable:BuildArch) { "${BuildArch}" }),
+        [String]$BuildConfiguration = $(if (Test-Path variable:BuildConfiguration) { "${BuildConfiguration}" })
+    )
+
+    Write-Status "Build libobs and obs-frontend-api"
+
+    Ensure-Directory ${ObsBuildDir}
+
+    if ($BuildArch -eq "64-bit") {
+        $QtDirectory = "${CheckoutDir}/../obs-build-dependencies/Qt_${WindowsQtVersion}/msvc2019_64"
+        $DepsDirectory = "${CheckoutDir}/../obs-build-dependencies/dependencies${WindowsDepsVersion}/win64"
+        $Env:CMAKE_PREFIX_PATH="${QtDirectory};${DepsDirectory}/bin;${DepsDirectory}"
+
+        cmake -S . -B "plugin_${BuildDirectory}64" -G "Visual Studio 16 2019" `
+            -DCMAKE_SYSTEM_VERSION="${CmakeSystemVersion}" `
+            -DCMAKE_GENERATOR_PLATFORM=x64 `
+            -DENABLE_PLUGINS=OFF `
+            -DENABLE_UI=ON `
+            -DENABLE_SCRIPTING=OFF `
+            "$(if (Test-Path Variable:$Quiet) { "-Wno-deprecated -Wno-dev --log-level=ERROR" })"
+
+        cmake --build "plugin_${BuildDirectory}64" -t obs-frontend-api --config ${BuildConfiguration}
+    } else {
+        $QtDirectory = "${CheckoutDir}/../obs-build-dependencies/Qt_${WindowsQtVersion}/msvc2019"
+        $DepsDirectory = "${CheckoutDir}/../obs-build-dependencies/dependencies${WindowsDepsVersion}/win32"
+        $Env:CMAKE_PREFIX_PATH="${QtDirectory};${DepsDirectory}/bin;${DepsDirectory}"
+
+        cmake -S . -B "plugin_${BuildDirectory}32" -G "Visual Studio 16 2019" `
+            -DCMAKE_SYSTEM_VERSION="${CmakeSystemVersion}" `
+            -DCMAKE_GENERATOR_PLATFORM=Win32 `
+            -DENABLE_PLUGINS=OFF `
+            -DENABLE_UI=ON `
+            -DENABLE_SCRIPTING=OFF `
+            "$(if (Test-Path Variable:$Quiet) { "-Wno-deprecated -Wno-dev --log-level=ERROR" })"
+
+        cmake --build "plugin_${BuildDirectory}32" -t obs-frontend-api --config ${BuildConfiguration}
+    }
+
+    Ensure-Directory ${CheckoutDir}
+}
+
+
+function Build-OBS-Libs-Standalone {
+    $CheckoutDir = git rev-parse --show-toplevel
+
+    if (Test-Path ${CheckoutDir}/CI/include/build_environment.ps1) {
+        . ${CheckoutDir}/CI/include/build_environment.ps1
+    }
+
+    $ObsBuildDir = "${CheckoutDir}/../obs-studio"
+
+    . ${CheckoutDir}/CI/include/build_support_windows.ps1
+
+    Build-OBS-Libs
+}
+
+function Print-Usage {
+    $Lines = @(
+        "Usage: ${MyInvocation.MyCommand.Name}",
+        "-Help                    : Print this help",
+        "-Quiet                   : Suppress most build process output",
+        "-Verbose                 : Enable more verbose build process output",
+        "-BuildDirectory          : Directory to use for builds - Default: build64 on 64-bit systems, build32 on 32-bit systems",
+        "-BuildArch               : Build architecture to use (32bit or 64bit) - Default: local architecture",
+        "-BuildConfiguration      : Build configuration to use - Default: RelWithDebInfo"
+    )
+
+    $Lines | Write-Host
+}
+
+if(!(Test-Path variable:_RunObsBuildScript)) {
+    if($Help.isPresent) {
+        Print-Usage
+        exit 0
+    }
+
+    Build-OBS-Libs-Standalone
+}

+ 92 - 0
CI/windows/03_build_plugin.ps1

@@ -0,0 +1,92 @@
+Param(
+    [Switch]$Help = $(if (Test-Path variable:Help) { $Help }),
+    [Switch]$Quiet = $(if (Test-Path variable:Quiet) { $Quiet }),
+    [Switch]$Verbose = $(if (Test-Path variable:Verbose) { $Verbose }),
+    [String]$ProductName = $(if (Test-Path variable:ProductName) { "${ProductName}" } else { "obs-plugin" }),
+    [String]$BuildDirectory = $(if (Test-Path variable:BuildDirectory) { "${BuildDirectory}" } else { "build" }),
+    [String]$BuildArch = $(if (Test-Path variable:BuildArch) { "${BuildArch}" } else { (Get-WmiObject Win32_OperatingSystem).OSArchitecture}),
+    [String]$BuildConfiguration = $(if (Test-Path variable:BuildConfiguration) { "${BuildConfiguration}" } else { "RelWithDebInfo" })
+)
+
+##############################################################################
+# Windows libobs plugin build function
+##############################################################################
+#
+# This script file can be included in build scripts for Windows or run
+# directly
+#
+##############################################################################
+
+$ErrorActionPreference = "Stop"
+
+function Build-OBS-Plugin {
+    Param(
+        [String]$BuildDirectory = $(if (Test-Path variable:BuildDirectory) { "${BuildDirectory}" }),
+        [String]$BuildArch = $(if (Test-Path variable:BuildArch) { "${BuildArch}" }),
+        [String]$BuildConfiguration = $(if (Test-Path variable:BuildConfiguration) { "${BuildConfiguration}" })
+    )
+
+    Write-Status "Build plugin ${ProductName}"
+    Ensure-Directory ${CheckoutDir}
+
+    if ($BuildArch -eq "64-bit") {
+        $QtFolder = "${CheckoutDir}/../obs-build-dependencies/Qt_${WindowsQtVersion}/msvc2019_64"
+        $DepsFolder = "${CheckoutDir}/../obs-build-dependencies/dependencies${WindowsDepsVersion}/win64"
+        $Env:CMAKE_PREFIX_PATH="${QtFolder};${DepsFolder}/bin;${DepsFolder}"
+
+        cmake -S . -B "${BuildDirectory}64" -G "Visual Studio 16 2019" `
+            -DCMAKE_GENERATOR_PLATFORM=x64 `
+            -DCMAKE_SYSTEM_VERSION="${CmakeSystemVersion}" `
+            "$(if (Test-Path Variable:$Quiet) { "-Wno-deprecated -Wno-dev --log-level=ERROR" })"
+
+        cmake --build "${BuildDirectory}64" --config ${BuildConfiguration}
+    } else {
+        $QtFolder = "${CheckoutDir}/../obs-build-dependencies/Qt_${WindowsQtVersion}/msvc2019"
+        $DepsFolder = "${CheckoutDir}/../obs-build-dependencies/dependencies${WindowsDepsVersion}/win32"
+        $Env:CMAKE_PREFIX_PATH="${QtFolder};${DepsFolder}/bin;${DepsFolder}"
+
+        cmake -S . -B "${BuildDirectory}32" -G "Visual Studio 16 2019" `
+            -DCMAKE_GENERATOR_PLATFORM=Win32 `
+            -DCMAKE_SYSTEM_VERSION="${CmakeSystemVersion}" `
+            "$(if (Test-Path Variable:$Quiet) { "-Wno-deprecated -Wno-dev --log-level=ERROR" })"
+
+        cmake --build "${BuildDirectory}32" --config ${BuildConfiguration}
+    }
+
+    Ensure-Directory ${CheckoutDir}
+}
+
+function Build-Plugin-Standalone {
+    $CheckoutDir = git rev-parse --show-toplevel
+
+    if (Test-Path ${CheckoutDir}/CI/include/build_environment.ps1) {
+        . ${CheckoutDir}/CI/include/build_environment.ps1
+    }
+
+    . ${CheckoutDir}/CI/include/build_support_windows.ps1
+
+    Build-OBS-Plugin
+}
+
+function Print-Usage {
+    $Lines = @(
+        "Usage: ${MyInvocation.MyCommand.Name}",
+        "-Help                    : Print this help",
+        "-Quiet                   : Suppress most build process output",
+        "-Verbose                 : Enable more verbose build process output",
+        "-BuildDirectory          : Directory to use for builds - Default: build64 on 64-bit systems, build32 on 32-bit systems",
+        "-BuildArch               : Build architecture to use (32bit or 64bit) - Default: local architecture",
+        "-BuildConfiguration      : Build configuration to use - Default: RelWithDebInfo"
+    )
+
+    $Lines | Write-Host
+}
+
+if(!(Test-Path variable:_RunObsBuildScript)) {
+    if($Help.isPresent) {
+        Print-Usage
+        exit 0
+    }
+
+    Build-Plugin-Standalone
+ }

+ 141 - 0
CI/windows/04_package_plugin.ps1

@@ -0,0 +1,141 @@
+Param(
+    [Switch]$Help = $(if (Test-Path variable:Help) { $Help }),
+    [Switch]$Quiet = $(if (Test-Path variable:Quiet) { $Quiet }),
+    [Switch]$Verbose = $(if (Test-Path variable:Verbose) { $Verbose }),
+    [Switch]$BuildInstaller = $(if ($BuildInstaller.isPresent) { $true }),
+    [String]$ProductName = $(if (Test-Path variable:ProductName) { "${ProductName}" } else { "obs-plugin" }),
+    [Switch]$CombinedArchs = $(if ($CombinedArchs.isPresent) { $true }),
+    [String]$BuildDirectory = $(if (Test-Path variable:BuildDirectory) { "${BuildDirectory}" } else { "build" }),
+    [String]$BuildArch = $(if (Test-Path variable:BuildArch) { "${BuildArch}" } else { (Get-WmiObject Win32_OperatingSystem).OSArchitecture}),
+    [String]$BuildConfiguration = $(if (Test-Path variable:BuildConfiguration) { "${BuildConfiguration}" } else { "RelWithDebInfo" })
+)
+
+##############################################################################
+# Windows libobs plugin package function
+##############################################################################
+#
+# This script file can be included in build scripts for Windows or run
+# directly with the -Standalone switch
+#
+##############################################################################
+
+$ErrorActionPreference = "Stop"
+
+function Package-OBS-Plugin {
+    Param(
+        [String]$BuildDirectory = $(if (Test-Path variable:BuildDirectory) { "${BuildDirectory}" }),
+        [String]$BuildArch = $(if (Test-Path variable:BuildArch) { "${BuildArch}" }),
+        [String]$BuildConfiguration = $(if (Test-Path variable:BuildConfiguration) { "${BuildConfiguration}" })
+    )
+
+    Write-Status "Package plugin ${ProductName}"
+    Ensure-Directory ${CheckoutDir}
+
+    if ($CombinedArchs.isPresent) {
+        if (!(Test-Path ${CheckoutDir}/release/obs-plugins/64bit)) {
+            cmake --build ${BuildDirectory}64 --config ${BuildConfiguration} -t install
+        }
+
+        if (!(Test-Path ${CheckoutDir}/release/obs-plugins/32bit)) {
+            cmake --build ${BuildDirectory}32 --config ${BuildConfiguration} -t install
+        }
+
+        $CompressVars = @{
+            Path = "${CheckoutDir}/release/*"
+            CompressionLevel = "Optimal"
+            DestinationPath = "${FileName}-Windows.zip"
+        }
+
+        Write-Step "Creating zip archive..."
+
+        Compress-Archive -Force @CompressVars
+        if(($BuildInstaller.isPresent) -And (Test-CommandExists "iscc")) {
+            Write-Step "Creating installer..."
+            & iscc ${CheckoutDir}/installer/installer-Windows.generated.iss /O. /F"${FileName}-Windows-Installer"
+        }
+    } elseif ($BuildArch -eq "64-bit") {
+        cmake --build ${BuildDirectory}64 --config ${BuildConfiguration} -t install
+
+        $CompressVars = @{
+            Path = "${CheckoutDir}/release/*"
+            CompressionLevel = "Optimal"
+            DestinationPath = "${FileName}-Win64.zip"
+        }
+
+        Write-Step "Creating zip archive..."
+
+        Compress-Archive -Force @CompressVars
+
+        if(($BuildInstaller.isPresent) -And (Test-CommandExists "iscc")) {
+            Write-Step "Creating installer..."
+            & iscc ${CheckoutDir}/installer/installer-Windows.generated.iss /O. /F"${FileName}-Win64-Installer"
+        }
+    } elseif ($BuildArch -eq "32-bit") {
+        cmake --build ${BuildDirectory}32 --config ${BuildConfiguration} -t install
+
+        $CompressVars = @{
+            Path = "${CheckoutDir}/release/*"
+            CompressionLevel = "Optimal"
+            DestinationPath = "${FileName}-Win32.zip"
+        }
+
+        Write-Step "Creating zip archive..."
+
+        Compress-Archive -Force @CompressVars
+
+        if(($BuildInstaller.isPresent) -And (Test-CommandExists "iscc")) {
+            Write-Step "Creating installer..."
+            & iscc ${CheckoutDir}/installer/installer-Windows.generated.iss /O. /F"${FileName}-Win32-Installer"
+        }
+    }
+}
+
+function Package-Plugin-Standalone {
+    $CheckoutDir = git rev-parse --show-toplevel
+
+    if (Test-Path ${CheckoutDir}/CI/include/build_environment.ps1) {
+        . ${CheckoutDir}/CI/include/build_environment.ps1
+    }
+
+    . ${CheckoutDir}/CI/include/build_support_windows.ps1
+
+    Ensure-Directory ${CheckoutDir}
+    $GitBranch = git rev-parse --abbrev-ref HEAD
+    $GitHash = git rev-parse --short HEAD
+    $ErrorActionPreference = "SilentlyContiue"
+    $GitTag = git describe --tags --abbrev=0
+    $ErrorActionPreference = "Stop"
+
+    if ($GitTag -eq $null) {
+        $GitTag=$ProductVersion
+    }
+
+    $FileName = "${ProductName}-${GitTag}-${GitHash}"
+
+    Package-OBS-Plugin
+}
+
+function Print-Usage {
+    $Lines = @(
+        "Usage: ${MyInvocation.MyCommand.Name}",
+        "-Help                    : Print this help",
+        "-Quiet                   : Suppress most build process output",
+        "-Verbose                 : Enable more verbose build process output",
+        "-CombinedArchs           : Create combined architecture package",
+        "-BuildDirectory          : Directory to use for builds - Default: build64 on 64-bit systems, build32 on 32-bit systems",
+        "-BuildArch               : Build architecture to use (32bit or 64bit) - Default: local architecture",
+        "-BuildConfiguration      : Build configuration to use - Default: RelWithDebInfo"
+    )
+
+    $Lines | Write-Host
+}
+
+
+if(!(Test-Path variable:_RunObsBuildScript)) {
+    if($Help.isPresent) {
+        Print-Usage
+        exit 0
+    }
+
+    Package-Plugin-Standalone
+}

+ 81 - 149
CMakeLists.txt

@@ -1,8 +1,9 @@
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required(VERSION 3.16)
 
 # Change obs-plugintemplate to your plugin's name in a machine-readable format
 # (e.g.: obs-myawesomeplugin) and set 
 project(obs-plugintemplate VERSION 1.0.0)
+add_library(${CMAKE_PROJECT_NAME} MODULE)
 
 # Replace `Your Name Here` with the name (yours or your organization's) you want
 # to see as the author of the plugin (in the plugin's metadata itself and in the installers)
@@ -13,181 +14,112 @@ set(PLUGIN_AUTHOR "Your Name Here")
 set(MACOS_BUNDLEID "com.example.obs-plugintemplate")
 
 # Replace `me@contoso.com` with the maintainer email address you want to put in Linux packages
-set(LINUX_MAINTAINER_EMAIL "me@contoso.com")
+set(LINUX_MAINTAINER_EMAIL "me@mymailhost.com")
 
-# TAKE NOTE: No need to edit things past this point
+# Add your custom source files here - header files are optional and only required for visibility
+# e.g. in Xcode or Visual Studio
+target_sources(${CMAKE_PROJECT_NAME}
+	PRIVATE
+		src/plugin-main.c)
 
-set(CMAKE_PREFIX_PATH "${QTDIR}")
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTOUIC ON)
+# /!\ TAKE NOTE: No need to edit things past this point /!\
 
-# In case you need C++
-set(CMAKE_CXX_STANDARD 11)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
+find_package(libobs REQUIRED)
+find_package(obs-frontend-api REQUIRED)
+include(external/ObsPluginHelpers.cmake)
+find_package(Qt5Core REQUIRED)
+find_package(Qt5Widgets REQUIRED)
 
-if (WIN32 OR APPLE)
-include(external/FindLibObs.cmake)
-endif()
-
-find_package(LibObs REQUIRED)
-find_package(Qt5 REQUIRED COMPONENTS Core Widgets)
-
-configure_file(
-    src/plugin-macros.h.in
-    ../src/plugin-macros.generated.h
-)
-configure_file(
-    installer/installer-macOS.pkgproj.in
-    ../installer/installer-macOS.generated.pkgproj
-)
-configure_file(
-    installer/installer-Windows.iss.in
-    ../installer/installer-Windows.generated.iss
-)
 
 configure_file(
-    ci/ci_includes.sh.in
-    ../ci/ci_includes.generated.sh
-)
-configure_file(
-    ci/ci_includes.cmd.in
-    ../ci/ci_includes.generated.cmd
-)
-
-set(PLUGIN_SOURCES
-	src/plugin-main.c)
+	src/plugin-macros.h.in
+	${CMAKE_SOURCE_DIR}/src/plugin-macros.generated.h)
 
-set(PLUGIN_HEADERS
-	src/plugin-macros.generated.h)
+target_sources(${CMAKE_PROJECT_NAME}
+	PRIVATE
+		src/plugin-macros.generated.h)
 
 # --- Platform-independent build settings ---
-add_library(${CMAKE_PROJECT_NAME} MODULE ${PLUGIN_SOURCES} ${PLUGIN_HEADERS})
 
-include_directories(
-	"${LIBOBS_INCLUDE_DIR}/../UI/obs-frontend-api"
-	${Qt5Core_INCLUDES}
-	${Qt5Widgets_INCLUDES}
-)
+target_include_directories(${CMAKE_PROJECT_NAME}
+	PRIVATE ${CMAKE_SOURCE_DIR}/src)
 
 target_link_libraries(${CMAKE_PROJECT_NAME}
-	libobs
-	Qt5::Core
-	Qt5::Widgets
-)
+	PRIVATE
+		OBS::libobs
+		OBS::obs-frontend-api
+		Qt5::Core
+		Qt5::Widgets)
+
+set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES
+	AUTOMOC ON
+	AUTOUIC ON
+	AUTORCC ON)
+
+target_compile_features(${CMAKE_PROJECT_NAME}
+	PRIVATE
+		cxx_std_17)
 
 # --- End of section ---
 
 # --- Windows-specific build settings and tasks ---
-if(WIN32)
-	if(NOT DEFINED OBS_FRONTEND_LIB)
-		set(OBS_FRONTEND_LIB "OBS_FRONTEND_LIB-NOTFOUND" CACHE FILEPATH "OBS frontend library")
-		message(FATAL_ERROR "Could not find OBS Frontend API\'s library !")
+if(OS_WINDOWS)
+	configure_file(
+		installer/installer-Windows.iss.in
+		${CMAKE_SOURCE_DIR}/installer/installer-Windows.generated.iss)
+
+	configure_file(
+		CI/include/build_environment.ps1.in
+		${CMAKE_SOURCE_DIR}/CI/include/build_environment.ps1)
+
+	if(MSVC)
+		target_compile_options(${CMAKE_PROJECT_NAME}
+			PRIVATE
+				/MP
+				/d2FH4-)
 	endif()
+# --- End of section ---
 
-    # Enable Multicore Builds and disable FH4 (to not depend on VCRUNTIME140_1.DLL when building with VS2019)
-    if (MSVC)
-        add_definitions(/MP /d2FH4-)
-    endif()
-
-	if(CMAKE_SIZEOF_VOID_P EQUAL 8)
-		set(ARCH_NAME "64bit")
-		set(OBS_BUILDDIR_ARCH "build64")
-	else()
-		set(ARCH_NAME "32bit")
-		set(OBS_BUILDDIR_ARCH "build32")
-	endif()
+# -- macOS specific build settings and tasks --
+elseif(OS_MACOS)
+	configure_file(
+		bundle/installer-macOS.pkgproj.in
+		${CMAKE_SOURCE_DIR}/bundle/installer-macOS.generated.pkgproj)
 
-	include_directories(
-		"${LIBOBS_INCLUDE_DIR}/../${OBS_BUILDDIR_ARCH}/UI"
+	configure_file(
+		CI/include/build_environment.sh.in
+		${CMAKE_SOURCE_DIR}/CI/include/build_environment.sh
 	)
 
-	target_link_libraries(${CMAKE_PROJECT_NAME}
-		"${OBS_FRONTEND_LIB}"
-    )
-
-	# --- Release package helper ---
-	# The "release" folder has a structure similar OBS' one on Windows
-	set(RELEASE_DIR "${PROJECT_SOURCE_DIR}/release")
-
-    add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD
-        # If config is Release or RelWithDebInfo, package release files
-        COMMAND if $<OR:$<CONFIG:Release>,$<CONFIG:RelWithDebInfo>>==1 (
-            "${CMAKE_COMMAND}" -E make_directory
-                "${RELEASE_DIR}/data/obs-plugins/${CMAKE_PROJECT_NAME}"
-                "${RELEASE_DIR}/obs-plugins/${ARCH_NAME}"
-        )
-
-        COMMAND if $<OR:$<CONFIG:Release>,$<CONFIG:RelWithDebInfo>>==1 (
-            "${CMAKE_COMMAND}" -E copy_directory
-                "${PROJECT_SOURCE_DIR}/data"
-                "${RELEASE_DIR}/data/obs-plugins/${CMAKE_PROJECT_NAME}"
-        )
-
-        COMMAND if $<OR:$<CONFIG:Release>,$<CONFIG:RelWithDebInfo>>==1 (
-            "${CMAKE_COMMAND}" -E copy
-                "$<TARGET_FILE:${CMAKE_PROJECT_NAME}>"
-                "${RELEASE_DIR}/obs-plugins/${ARCH_NAME}"
-        )
-
-        # If config is RelWithDebInfo, copy the pdb file
-        COMMAND if $<CONFIG:RelWithDebInfo>==1 (
-            "${CMAKE_COMMAND}" -E copy
-                "$<TARGET_PDB_FILE:${CMAKE_PROJECT_NAME}>"
-                "${RELEASE_DIR}/obs-plugins/${ARCH_NAME}"
-        )
-
-        # Copy to obs-studio dev environment for immediate testing
-        COMMAND if $<CONFIG:Debug>==1 (
-            "${CMAKE_COMMAND}" -E copy
-                "$<TARGET_FILE:${CMAKE_PROJECT_NAME}>"
-                "${LIBOBS_INCLUDE_DIR}/../${OBS_BUILDDIR_ARCH}/rundir/$<CONFIG>/obs-plugins/${ARCH_NAME}"
-        )
-
-        COMMAND if $<CONFIG:Debug>==1 (
-            "${CMAKE_COMMAND}" -E copy
-                "$<TARGET_PDB_FILE:${CMAKE_PROJECT_NAME}>"
-                "${LIBOBS_INCLUDE_DIR}/../${OBS_BUILDDIR_ARCH}/rundir/$<CONFIG>/obs-plugins/${ARCH_NAME}"
-        )
-
-        COMMAND if $<CONFIG:Debug>==1 (
-            "${CMAKE_COMMAND}" -E make_directory
-                "${LIBOBS_INCLUDE_DIR}/../${OBS_BUILDDIR_ARCH}/rundir/$<CONFIG>/data/obs-plugins/${CMAKE_PROJECT_NAME}"
-        )
-
-        COMMAND if $<CONFIG:Debug>==1 (
-            "${CMAKE_COMMAND}" -E copy_directory
-                "${PROJECT_SOURCE_DIR}/data"
-                "${LIBOBS_INCLUDE_DIR}/../${OBS_BUILDDIR_ARCH}/rundir/$<CONFIG>/data/obs-plugins/${CMAKE_PROJECT_NAME}"
-        )
-    )
-	# --- End of sub-section ---
+	set(MACOSX_PLUGIN_GUI_IDENTIFIER "${MACOS_BUNDLEID}")
+	set(MACOSX_PLUGIN_BUNDLE_VERSION "${CMAKE_PROJECT_VERSION}")
+	set(MACOSX_PLUGIN_SHORT_VERSION_STRING "1")
 
-endif()
-# --- End of section ---
-
-# --- Linux-specific build settings and tasks ---
-if(UNIX AND NOT APPLE)
-    include(GNUInstallDirs)
+	target_compile_options(${CMAKE_PROJECT_NAME}
+		PRIVATE
+			-Wall
+			-Wextra
+			-Werror-implicit-function-declaration
+			-stdlib=libc++
+			-fvisibility=default)
 
 	set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES PREFIX "")
-	target_link_libraries(${CMAKE_PROJECT_NAME} obs-frontend-api)
+# --- End of section ---
 
-	file(GLOB locale_files data/locale/*.ini)
+# --- Linux-specific build settings and tasks ---
+else()
+	configure_file(
+		CI/include/build_environment.sh.in
+		${CMAKE_SOURCE_DIR}/CI/include/build_environment.sh
+	)
 
-	install(TARGETS ${CMAKE_PROJECT_NAME}
-		LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/obs-plugins")
+	target_compile_options(${CMAKE_PROJECT_NAME}
+		PRIVATE
+			-Wall
+			-Wextra)
 
-	install(FILES ${locale_files}
-		DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/obs/obs-plugins/${CMAKE_PROJECT_NAME}/locale")
+	set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES PREFIX "")
 endif()
 # --- End of section ---
 
-# -- OS X specific build settings and tasks --
-if(APPLE)
-	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -fvisibility=default")
-
-	set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES PREFIX "")
-	target_link_libraries(${CMAKE_PROJECT_NAME} "${OBS_FRONTEND_LIB}")
-endif()
-# -- End of section --
+setup_plugin_target(${CMAKE_PROJECT_NAME})

+ 12 - 14
README.md

@@ -31,31 +31,29 @@ set(LINUX_MAINTAINER_EMAIL "me@contoso.com")
 
 ## CI / Build Bot
 
-The CI scripts are made for Azure Pipelines. The sections below detail some of the common tasks possible with that CI configuration.
+The contained build scripts are used by the local main build script as well as by CI - every sub-script can be run individually as well - by default a workflow for Github Actions is provided, allowing your plugin to use CI right from your Github repository.
 
 ### Retrieving build artifacts
 
-Each build produces installers and packages that you can use for testing and releases. These artifacts can be found a Build's page on Azure Pipelines.
+Each build produces installers and packages that you can use for testing and releases. These artifacts can be found on the action result page via the "Actions" tab in your Github repository.
 
 #### Building a Release
 
-Simply create and push a tag, and Azure Pipelines will run the pipeline in Release Mode. This mode uses the tag as its version number instead of the git ref in normal mode.
+Simply create and push a tag and Github Actions will run the pipeline in Release Mode. This mode uses the tag as its version number instead of the git ref in normal mode.
 
 ### Signing and Notarizing on macOS
 
-On macOS, Release Mode builds will be signed and sent to Apple for notarization if `macosSignAndNotarize` is set to `True` at the top of the `azure-pipelines.yml` file. **You'll need a paid Apple Developer Account for this.**
-
-In addition to enabling `macosSignAndNotarize`, you'll need to setup a few more things for Signing and Notarizing to work:
+On macOS, Release Mode builds can be signed and sent to Apple for notarization if the necessary codesigning credentials are added as secrets to your repository. **You'll need a paid Apple Developer Account for this.**
 
 - On your Apple Developer dashboard, go to "Certificates, IDs & Profiles" and create two signing certificates:
     - One of the "Developer ID Application" type. It will be used to sign the plugin's binaries
     - One of the "Developer ID Installer" type. It will be used to sign the plugin's installer
 - Using the Keychain app on macOS, export these two certificates and keys into a .p12 file **protected with a strong password**
-- Add that `Certificates.P12` file as a [Secure File in Azure Pipelines](https://docs.microsoft.com/en-us/azure/devops/pipelines/library/secure-files?view=azure-devops) and make sure it is named `Certificates.p12`
-- Add the following secrets in your pipeline settings:
-    - `secrets.macOS.certificatesImportPassword`: Password of the .p12 file generated earlier
-    - `secrets.macOS.codeSigningIdentity`: Name of the "Developer ID Application" signing certificate generated earlier
-    - `secrets.macOS.installerSigningIdentity`: Name of "Developer ID Installer" signing certificate generated earlier
-    - `secrets.macOS.notarization.username`: Your Apple Developer Account's username
-    - `secrets.macOS.notarization.password`: Your Apple Developer Account's password
-    - `secrets.macOS.notarization.providerShortName`: Identifier (`Provider Short Name`, as Apple calls it) of the Developer Team to which the signing certificates belong. 
+- Encode the .p12 file into its base64 representation by running `base64 YOUR_P12_FILE`
+- Add the following secrets in your Github repository settings:
+    - `MACOS_SIGNING_APPLICATION_IDENTITY`: Name of the "Developer ID Application" signing certificate generated earlier
+    - `MACOS_SIGNING_INSTALLER_IDENTITY`: Name of "Developer ID Installer" signing certificate generated earlier
+    - `MACOS_SIGNING_CERT`: Base64-encoded string generated above
+    - `MACOS_SIGNING_CERT_PASSWORD`: Password used to generate the .p12 certificate
+    - `MACOS_NOTARIZATION_USERNAME`: Your Apple Developer account's username
+    - `MACOS_NOTARIZATION_PASSWORD`: Your Apple Developer account's password (use a generated "app password" for this)

+ 0 - 166
azure-pipelines.yml

@@ -1,166 +0,0 @@
-variables:
-  macosSignAndNotarize: false
-  isReleaseMode: ${{ and(eq(variables['isReleaseMode'], true), startsWith(variables['Build.SourceBranch'], 'refs/tags/')) }}
-
-trigger:
-  branches:
-    include:
-      - master
-  tags:
-    include:
-      - '*'
-
-jobs:
-- job: 'Build_Windows'
-  pool:
-    vmImage: 'windows-2019'
-  variables:
-    build_config: RelWithDebInfo
-    DepsBasePath: 'D:\obsdependencies'
-    DepsPath32: '$(DepsBasePath)\win32'
-    DepsPath64: '$(DepsBasePath)\win64'
-    QtBaseDir: 'D:\QtDep'
-    QTDIR32: '$(QtBaseDir)\5.10.1\msvc2017'
-    QTDIR64: '$(QtBaseDir)\5.10.1\msvc2017_64'
-    OBSPath: 'D:\obs-studio'
-  steps:
-    - checkout: self
-      submodules: true
-
-    - script: ./ci/windows/install-qt-win.cmd
-      displayName: 'Install Qt'
-      env:
-        QtBaseDir: $(QtBaseDir)
-
-    - task: Cache@2
-      displayName: Restore cached OBS Studio dependencies
-      inputs:
-        key: 'obsdeps | "$(Agent.OS)"'
-        restoreKeys: |
-          obsdeps | "$(Agent.OS)"
-        path: $(DepsBasePath)
-
-    - script: ./ci/windows/download-obs-deps.cmd
-      displayName: 'Download OBS Studio dependencies'
-
-    - task: Cache@2
-      displayName: Restore cached OBS Studio builds
-      inputs:
-        key: 'obs | "$(Agent.OS)"'
-        restoreKeys: |
-          obs | "$(Agent.OS)"
-        path: $(OBSPath)
-
-    - script: ./ci/windows/prepare-obs-windows.cmd
-      displayName: 'Checkout & CMake OBS Studio'
-      env:
-        build_config: $(build_config)
-        DepsPath32: $(DepsPath32)
-        DepsPath64: $(DepsPath64)
-        QTDIR32: $(QTDIR32)
-        QTDIR64: $(QTDIR64)
-        OBSPath: $(OBSPath)
-
-    - task: MSBuild@1
-      displayName: 'Build OBS Studio 32-bit'
-      inputs:
-        msbuildArguments: '/m /p:Configuration=$(build_config)'
-        solution: '$(OBSPath)\build32\obs-studio.sln'
-
-    - task: MSBuild@1
-      displayName: 'Build OBS Studio 64-bit'
-      inputs:
-        msbuildArguments: '/m /p:Configuration=$(build_config)'
-        solution: '$(OBSPath)\build64\obs-studio.sln'
-
-    - script: ./ci/windows/prepare-windows.cmd
-      displayName: 'CMake Plugin'
-      env:
-        build_config: $(build_config)
-        QTDIR32: $(QTDIR32)
-        QTDIR64: $(QTDIR64)
-        OBSPath: $(OBSPath)
-
-    - task: MSBuild@1
-      displayName: 'Build Plugin 32-bit'
-      inputs:
-        msbuildArguments: '/m /p:Configuration=$(build_config)'
-        solution: '.\build32\main.sln'
-
-    - task: MSBuild@1
-      displayName: 'Build Plugin 64-bit'
-      inputs:
-        msbuildArguments: '/m /p:Configuration=$(build_config)'
-        solution: '.\build64\main.sln'
-
-    - script: ./ci/windows/package-windows.cmd
-      displayName: 'Package Plugin'
-
-    - task: PublishBuildArtifacts@1
-      displayName: 'Upload package artifacts'
-      inputs:
-        pathtoPublish: './package'
-        artifactName: 'windows_build'
-
-- job: 'Build_Linux'
-  pool:
-    vmImage: 'ubuntu-18.04'
-  variables:
-      BUILD_REASON: $(Build.Reason)
-      BRANCH_SHORT_NAME: $(Build.SourceBranchName)
-      BRANCH_FULL_NAME: $(Build.SourceBranch)
-  steps:
-    - checkout: self
-      submodules: true
-
-    - script: ./ci/linux/install-dependencies-ubuntu.sh
-      displayName: 'Install dependencies'
-
-    - script: ./ci/linux/build-ubuntu.sh
-      displayName: 'Build Plugin'
-
-    - script: ./ci/linux/package-ubuntu.sh
-      displayName: 'Package Plugin'
-
-    - task: PublishBuildArtifacts@1
-      inputs:
-        pathtoPublish: './package'
-        artifactName: 'deb_build'
-
-- job: 'Build_macOS'
-  pool:
-    vmImage: 'macos-10.14'
-  steps:
-    - checkout: self
-      submodules: true
-
-    - script: ./ci/macos/install-dependencies-macos.sh
-      displayName: 'Install dependencies'
-
-    - script: ./ci/macos/install-build-obs-macos.sh
-      displayName: 'Build OBS'
-
-    - script: ./ci/macos/build-macos.sh
-      displayName: 'Build Plugin'
-
-    - task: InstallAppleCertificate@1
-      displayName: 'Install release signing certificates'
-      condition: eq(variables['isReleaseMode'], true)
-      inputs:
-        certSecureFile: 'Certificates.p12'
-        certPwd: $(secrets.macOS.certificatesImportPassword)
-
-    - script: ./ci/macos/package-macos.sh
-      displayName: 'Package Plugin'
-      env:
-        RELEASE_MODE: $(isReleaseMode)
-        CODE_SIGNING_IDENTITY: $(secrets.macOS.codeSigningIdentity)
-        INSTALLER_SIGNING_IDENTITY: $(secrets.macOS.installerSigningIdentity)
-        AC_USERNAME: $(secrets.macOS.notarization.username)
-        AC_PASSWORD: $(secrets.macOS.notarization.password)
-        AC_PROVIDER_SHORTNAME: $(secrets.macOS.notarization.providerShortName)
-
-    - task: PublishBuildArtifacts@1
-      inputs:
-        pathtoPublish: './release'
-        artifactName: 'macos_build'

+ 947 - 0
bundle/installer-macOS.pkgproj.in

@@ -0,0 +1,947 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>PACKAGES</key>
+	<array>
+		<dict>
+			<key>MUST-CLOSE-APPLICATION-ITEMS</key>
+			<array/>
+			<key>MUST-CLOSE-APPLICATIONS</key>
+			<false/>
+			<key>PACKAGE_FILES</key>
+			<dict>
+				<key>DEFAULT_INSTALL_LOCATION</key>
+				<string>/</string>
+				<key>HIERARCHY</key>
+				<dict>
+					<key>CHILDREN</key>
+					<array>
+						<dict>
+							<key>CHILDREN</key>
+							<array/>
+							<key>GID</key>
+							<integer>80</integer>
+							<key>PATH</key>
+							<string>Applications</string>
+							<key>PATH_TYPE</key>
+							<integer>0</integer>
+							<key>PERMISSIONS</key>
+							<integer>509</integer>
+							<key>TYPE</key>
+							<integer>1</integer>
+							<key>UID</key>
+							<integer>0</integer>
+						</dict>
+						<dict>
+							<key>CHILDREN</key>
+							<array>
+								<dict>
+									<key>CHILDREN</key>
+									<array>
+										<dict>
+											<key>CHILDREN</key>
+											<array>
+												<dict>
+													<key>CHILDREN</key>
+													<array>
+														<dict>
+															<key>BUNDLE_CAN_DOWNGRADE</key>
+															<false/>
+															<key>BUNDLE_POSTINSTALL_PATH</key>
+															<dict>
+																<key>PATH_TYPE</key>
+																<integer>0</integer>
+															</dict>
+															<key>BUNDLE_PREINSTALL_PATH</key>
+															<dict>
+																<key>PATH_TYPE</key>
+																<integer>0</integer>
+															</dict>
+															<key>CHILDREN</key>
+															<array/>
+															<key>GID</key>
+															<integer>80</integer>
+															<key>PATH</key>
+															<string>../@RELATIVE_INSTALL_PATH@/@CMAKE_PROJECT_NAME@.plugin</string>
+															<key>PATH_TYPE</key>
+															<integer>1</integer>
+															<key>PERMISSIONS</key>
+															<integer>493</integer>
+															<key>TYPE</key>
+															<integer>3</integer>
+															<key>UID</key>
+															<integer>0</integer>
+														</dict>
+													</array>
+													<key>GID</key>
+													<integer>80</integer>
+													<key>PATH</key>
+													<string>plugins</string>
+													<key>PATH_TYPE</key>
+													<integer>2</integer>
+													<key>PERMISSIONS</key>
+													<integer>509</integer>
+													<key>TYPE</key>
+													<integer>2</integer>
+													<key>UID</key>
+													<integer>0</integer>
+												</dict>
+											</array>
+											<key>GID</key>
+											<integer>80</integer>
+											<key>PATH</key>
+											<string>obs-studio</string>
+											<key>PATH_TYPE</key>
+											<integer>2</integer>
+											<key>PERMISSIONS</key>
+											<integer>509</integer>
+											<key>TYPE</key>
+											<integer>2</integer>
+											<key>UID</key>
+											<integer>0</integer>
+										</dict>
+									</array>
+									<key>GID</key>
+									<integer>80</integer>
+									<key>PATH</key>
+									<string>Application Support</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Automator</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Documentation</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Extensions</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Filesystems</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Frameworks</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Input Methods</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Internet Plug-Ins</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>LaunchAgents</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>LaunchDaemons</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>PreferencePanes</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Preferences</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>80</integer>
+									<key>PATH</key>
+									<string>Printers</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>PrivilegedHelperTools</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>1005</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>QuickLook</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>QuickTime</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Screen Savers</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Scripts</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Services</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Widgets</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>493</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+							</array>
+							<key>GID</key>
+							<integer>0</integer>
+							<key>PATH</key>
+							<string>Library</string>
+							<key>PATH_TYPE</key>
+							<integer>0</integer>
+							<key>PERMISSIONS</key>
+							<integer>493</integer>
+							<key>TYPE</key>
+							<integer>1</integer>
+							<key>UID</key>
+							<integer>0</integer>
+						</dict>
+						<dict>
+							<key>CHILDREN</key>
+							<array>
+								<dict>
+									<key>CHILDREN</key>
+									<array/>
+									<key>GID</key>
+									<integer>0</integer>
+									<key>PATH</key>
+									<string>Shared</string>
+									<key>PATH_TYPE</key>
+									<integer>0</integer>
+									<key>PERMISSIONS</key>
+									<integer>1023</integer>
+									<key>TYPE</key>
+									<integer>1</integer>
+									<key>UID</key>
+									<integer>0</integer>
+								</dict>
+							</array>
+							<key>GID</key>
+							<integer>80</integer>
+							<key>PATH</key>
+							<string>Users</string>
+							<key>PATH_TYPE</key>
+							<integer>0</integer>
+							<key>PERMISSIONS</key>
+							<integer>493</integer>
+							<key>TYPE</key>
+							<integer>1</integer>
+							<key>UID</key>
+							<integer>0</integer>
+						</dict>
+					</array>
+					<key>GID</key>
+					<integer>0</integer>
+					<key>PATH</key>
+					<string>/</string>
+					<key>PATH_TYPE</key>
+					<integer>0</integer>
+					<key>PERMISSIONS</key>
+					<integer>493</integer>
+					<key>TYPE</key>
+					<integer>1</integer>
+					<key>UID</key>
+					<integer>0</integer>
+				</dict>
+				<key>PAYLOAD_TYPE</key>
+				<integer>0</integer>
+				<key>PRESERVE_EXTENDED_ATTRIBUTES</key>
+				<false/>
+				<key>SHOW_INVISIBLE</key>
+				<false/>
+				<key>SPLIT_FORKS</key>
+				<true/>
+				<key>TREAT_MISSING_FILES_AS_WARNING</key>
+				<false/>
+				<key>VERSION</key>
+				<integer>5</integer>
+			</dict>
+			<key>PACKAGE_SCRIPTS</key>
+			<dict>
+				<key>POSTINSTALL_PATH</key>
+				<dict>
+					<key>PATH_TYPE</key>
+					<integer>0</integer>
+				</dict>
+				<key>PREINSTALL_PATH</key>
+				<dict>
+					<key>PATH_TYPE</key>
+					<integer>0</integer>
+				</dict>
+				<key>RESOURCES</key>
+				<array/>
+			</dict>
+			<key>PACKAGE_SETTINGS</key>
+			<dict>
+				<key>AUTHENTICATION</key>
+				<integer>0</integer>
+				<key>CONCLUSION_ACTION</key>
+				<integer>0</integer>
+				<key>FOLLOW_SYMBOLIC_LINKS</key>
+				<false/>
+				<key>IDENTIFIER</key>
+				<string>@MACOS_BUNDLEID@</string>
+				<key>LOCATION</key>
+				<integer>0</integer>
+				<key>NAME</key>
+				<string>@CMAKE_PROJECT_NAME@</string>
+				<key>OVERWRITE_PERMISSIONS</key>
+				<false/>
+				<key>PAYLOAD_SIZE</key>
+				<integer>-1</integer>
+				<key>REFERENCE_PATH</key>
+				<string></string>
+				<key>RELOCATABLE</key>
+				<false/>
+				<key>USE_HFS+_COMPRESSION</key>
+				<false/>
+				<key>VERSION</key>
+				<string>@CMAKE_PROJECT_VERSION@</string>
+			</dict>
+			<key>TYPE</key>
+			<integer>0</integer>
+			<key>UUID</key>
+			<string>0B7A74BC-65CF-4FF1-AC34-5C743E8A48F5</string>
+		</dict>
+	</array>
+	<key>PROJECT</key>
+	<dict>
+		<key>PROJECT_COMMENTS</key>
+		<dict>
+			<key>NOTES</key>
+			<data>
+			</data>
+		</dict>
+		<key>PROJECT_PRESENTATION</key>
+		<dict>
+			<key>BACKGROUND</key>
+			<dict>
+				<key>APPAREANCES</key>
+				<dict>
+					<key>DARK_AQUA</key>
+					<dict/>
+					<key>LIGHT_AQUA</key>
+					<dict/>
+				</dict>
+				<key>SHARED_SETTINGS_FOR_ALL_APPAREANCES</key>
+				<true/>
+			</dict>
+			<key>INSTALLATION TYPE</key>
+			<dict>
+				<key>HIERARCHIES</key>
+				<dict>
+					<key>INSTALLER</key>
+					<dict>
+						<key>LIST</key>
+						<array>
+							<dict>
+								<key>CHILDREN</key>
+								<array/>
+								<key>DESCRIPTION</key>
+								<array/>
+								<key>OPTIONS</key>
+								<dict>
+									<key>HIDDEN</key>
+									<false/>
+									<key>STATE</key>
+									<integer>1</integer>
+								</dict>
+								<key>PACKAGE_UUID</key>
+								<string>0B7A74BC-65CF-4FF1-AC34-5C743E8A48F5</string>
+								<key>TITLE</key>
+								<array/>
+								<key>TYPE</key>
+								<integer>0</integer>
+								<key>UUID</key>
+								<string>52B6084A-F58D-45C3-BE37-76AD45F16072</string>
+							</dict>
+						</array>
+						<key>REMOVED</key>
+						<dict/>
+					</dict>
+				</dict>
+				<key>MODE</key>
+				<integer>0</integer>
+			</dict>
+			<key>INSTALLATION_STEPS</key>
+			<array>
+				<dict>
+					<key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
+					<string>ICPresentationViewIntroductionController</string>
+					<key>INSTALLER_PLUGIN</key>
+					<string>Introduction</string>
+					<key>LIST_TITLE_KEY</key>
+					<string>InstallerSectionTitle</string>
+				</dict>
+				<dict>
+					<key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
+					<string>ICPresentationViewReadMeController</string>
+					<key>INSTALLER_PLUGIN</key>
+					<string>ReadMe</string>
+					<key>LIST_TITLE_KEY</key>
+					<string>InstallerSectionTitle</string>
+				</dict>
+				<dict>
+					<key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
+					<string>ICPresentationViewLicenseController</string>
+					<key>INSTALLER_PLUGIN</key>
+					<string>License</string>
+					<key>LIST_TITLE_KEY</key>
+					<string>InstallerSectionTitle</string>
+				</dict>
+				<dict>
+					<key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
+					<string>ICPresentationViewDestinationSelectController</string>
+					<key>INSTALLER_PLUGIN</key>
+					<string>TargetSelect</string>
+					<key>LIST_TITLE_KEY</key>
+					<string>InstallerSectionTitle</string>
+				</dict>
+				<dict>
+					<key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
+					<string>ICPresentationViewInstallationTypeController</string>
+					<key>INSTALLER_PLUGIN</key>
+					<string>PackageSelection</string>
+					<key>LIST_TITLE_KEY</key>
+					<string>InstallerSectionTitle</string>
+				</dict>
+				<dict>
+					<key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
+					<string>ICPresentationViewInstallationController</string>
+					<key>INSTALLER_PLUGIN</key>
+					<string>Install</string>
+					<key>LIST_TITLE_KEY</key>
+					<string>InstallerSectionTitle</string>
+				</dict>
+				<dict>
+					<key>ICPRESENTATION_CHAPTER_VIEW_CONTROLLER_CLASS</key>
+					<string>ICPresentationViewSummaryController</string>
+					<key>INSTALLER_PLUGIN</key>
+					<string>Summary</string>
+					<key>LIST_TITLE_KEY</key>
+					<string>InstallerSectionTitle</string>
+				</dict>
+			</array>
+			<key>INTRODUCTION</key>
+			<dict>
+				<key>LOCALIZATIONS</key>
+				<array/>
+			</dict>
+			<key>LICENSE</key>
+			<dict>
+				<key>LOCALIZATIONS</key>
+				<array/>
+				<key>MODE</key>
+				<integer>0</integer>
+			</dict>
+			<key>README</key>
+			<dict>
+				<key>LOCALIZATIONS</key>
+				<array/>
+			</dict>
+			<key>SUMMARY</key>
+			<dict>
+				<key>LOCALIZATIONS</key>
+				<array/>
+			</dict>
+			<key>TITLE</key>
+			<dict>
+				<key>LOCALIZATIONS</key>
+				<array/>
+			</dict>
+		</dict>
+		<key>PROJECT_REQUIREMENTS</key>
+		<dict>
+			<key>LIST</key>
+			<array>
+				<dict>
+					<key>BEHAVIOR</key>
+					<integer>3</integer>
+					<key>DICTIONARY</key>
+					<dict>
+						<key>IC_REQUIREMENT_FILES_CONDITION</key>
+						<integer>0</integer>
+						<key>IC_REQUIREMENT_FILES_DISK_TYPE</key>
+						<integer>0</integer>
+						<key>IC_REQUIREMENT_FILES_LIST</key>
+						<array>
+							<string>/Applications/OBS.app</string>
+						</array>
+						<key>IC_REQUIREMENT_FILES_SELECTOR</key>
+						<integer>0</integer>
+					</dict>
+					<key>IC_REQUIREMENT_CHECK_TYPE</key>
+					<integer>1</integer>
+					<key>IDENTIFIER</key>
+					<string>fr.whitebox.Packages.requirement.files</string>
+					<key>MESSAGE</key>
+					<array/>
+					<key>NAME</key>
+					<string>Files</string>
+					<key>STATE</key>
+					<true/>
+				</dict>
+				<dict>
+					<key>BEHAVIOR</key>
+					<integer>3</integer>
+					<key>DICTIONARY</key>
+					<dict>
+						<key>IC_REQUIREMENT_OS_DISK_TYPE</key>
+						<integer>1</integer>
+						<key>IC_REQUIREMENT_OS_DISTRIBUTION_TYPE</key>
+						<integer>0</integer>
+						<key>IC_REQUIREMENT_OS_MINIMUM_VERSION</key>
+						<integer>101300</integer>
+					</dict>
+					<key>IC_REQUIREMENT_CHECK_TYPE</key>
+					<integer>0</integer>
+					<key>IDENTIFIER</key>
+					<string>fr.whitebox.Packages.requirement.os</string>
+					<key>MESSAGE</key>
+					<array/>
+					<key>NAME</key>
+					<string>Operating System</string>
+					<key>STATE</key>
+					<true/>
+				</dict>
+			</array>
+			<key>RESOURCES</key>
+			<array/>
+			<key>ROOT_VOLUME_ONLY</key>
+			<true/>
+		</dict>
+		<key>PROJECT_SETTINGS</key>
+		<dict>
+			<key>ADVANCED_OPTIONS</key>
+			<dict>
+				<key>installer-script.domains:enable_currentUserHome</key>
+				<integer>1</integer>
+			</dict>
+			<key>BUILD_FORMAT</key>
+			<integer>0</integer>
+			<key>BUILD_PATH</key>
+			<dict>
+				<key>PATH</key>
+				<string>../@RELATIVE_BUILD_PATH@</string>
+				<key>PATH_TYPE</key>
+				<integer>1</integer>
+			</dict>
+			<key>EXCLUDED_FILES</key>
+			<array>
+				<dict>
+					<key>PATTERNS_ARRAY</key>
+					<array>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>.DS_Store</string>
+							<key>TYPE</key>
+							<integer>0</integer>
+						</dict>
+					</array>
+					<key>PROTECTED</key>
+					<true/>
+					<key>PROXY_NAME</key>
+					<string>Remove .DS_Store files</string>
+					<key>PROXY_TOOLTIP</key>
+					<string>Remove ".DS_Store" files created by the Finder.</string>
+					<key>STATE</key>
+					<true/>
+				</dict>
+				<dict>
+					<key>PATTERNS_ARRAY</key>
+					<array>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>.pbdevelopment</string>
+							<key>TYPE</key>
+							<integer>0</integer>
+						</dict>
+					</array>
+					<key>PROTECTED</key>
+					<true/>
+					<key>PROXY_NAME</key>
+					<string>Remove .pbdevelopment files</string>
+					<key>PROXY_TOOLTIP</key>
+					<string>Remove ".pbdevelopment" files created by ProjectBuilder or Xcode.</string>
+					<key>STATE</key>
+					<true/>
+				</dict>
+				<dict>
+					<key>PATTERNS_ARRAY</key>
+					<array>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>CVS</string>
+							<key>TYPE</key>
+							<integer>1</integer>
+						</dict>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>.cvsignore</string>
+							<key>TYPE</key>
+							<integer>0</integer>
+						</dict>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>.cvspass</string>
+							<key>TYPE</key>
+							<integer>0</integer>
+						</dict>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>.svn</string>
+							<key>TYPE</key>
+							<integer>1</integer>
+						</dict>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>.git</string>
+							<key>TYPE</key>
+							<integer>1</integer>
+						</dict>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>.gitignore</string>
+							<key>TYPE</key>
+							<integer>0</integer>
+						</dict>
+					</array>
+					<key>PROTECTED</key>
+					<true/>
+					<key>PROXY_NAME</key>
+					<string>Remove SCM metadata</string>
+					<key>PROXY_TOOLTIP</key>
+					<string>Remove helper files and folders used by the CVS, SVN or Git Source Code Management systems.</string>
+					<key>STATE</key>
+					<true/>
+				</dict>
+				<dict>
+					<key>PATTERNS_ARRAY</key>
+					<array>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>classes.nib</string>
+							<key>TYPE</key>
+							<integer>0</integer>
+						</dict>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>designable.db</string>
+							<key>TYPE</key>
+							<integer>0</integer>
+						</dict>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>info.nib</string>
+							<key>TYPE</key>
+							<integer>0</integer>
+						</dict>
+					</array>
+					<key>PROTECTED</key>
+					<true/>
+					<key>PROXY_NAME</key>
+					<string>Optimize nib files</string>
+					<key>PROXY_TOOLTIP</key>
+					<string>Remove "classes.nib", "info.nib" and "designable.nib" files within .nib bundles.</string>
+					<key>STATE</key>
+					<true/>
+				</dict>
+				<dict>
+					<key>PATTERNS_ARRAY</key>
+					<array>
+						<dict>
+							<key>REGULAR_EXPRESSION</key>
+							<false/>
+							<key>STRING</key>
+							<string>Resources Disabled</string>
+							<key>TYPE</key>
+							<integer>1</integer>
+						</dict>
+					</array>
+					<key>PROTECTED</key>
+					<true/>
+					<key>PROXY_NAME</key>
+					<string>Remove Resources Disabled folders</string>
+					<key>PROXY_TOOLTIP</key>
+					<string>Remove "Resources Disabled" folders.</string>
+					<key>STATE</key>
+					<true/>
+				</dict>
+				<dict>
+					<key>SEPARATOR</key>
+					<true/>
+				</dict>
+			</array>
+			<key>NAME</key>
+			<string>@CMAKE_PROJECT_NAME@</string>
+			<key>PAYLOAD_ONLY</key>
+			<false/>
+			<key>TREAT_MISSING_PRESENTATION_DOCUMENTS_AS_WARNING</key>
+			<false/>
+		</dict>
+	</dict>
+	<key>TYPE</key>
+	<integer>0</integer>
+	<key>VERSION</key>
+	<integer>2</integer>
+</dict>
+</plist>

+ 26 - 0
bundle/macOS/Plugin-Info.plist.in

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleName</key>
+	<string>${MACOSX_PLUGIN_BUNDLE_NAME}</string>
+	<key>CFBundleIdentifier</key>
+	<string>${MACOSX_PLUGIN_GUI_IDENTIFIER}</string>
+	<key>CFBundleVersion</key>
+	<string>${MACOSX_PLUGIN_BUNDLE_VERSION}</string>
+	<key>CFBundleShortVersionString</key>
+	<string>${MACOSX_PLUGIN_SHORT_VERSION_STRING}</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleExecutable</key>
+	<string>${MACOSX_PLUGIN_EXECUTABLE_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>${MACOSX_PLUGIN_BUNDLE_TYPE}</string>
+	<key>CFBundleSupportedPlatforms</key>
+	<array>
+		<string>MacOSX</string>
+	</array>
+	<key>LSMinimumSystemVersion</key>
+	<string>10.13</string>
+</dict>
+</plist>

+ 17 - 0
bundle/macOS/entitlements.plist

@@ -0,0 +1,17 @@
+<!--?xml version="1.0" encoding="UTF-8"?-->
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+    <dict>
+        <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
+        <true/>
+        <key>com.apple.security.device.camera</key>
+        <true/>
+        <key>com.apple.security.device.audio-input</key>
+        <true/>
+        <key>com.apple.security.cs.disable-library-validation</key>
+        <true/>
+        <!-- Allows @executable_path to load libaries from within the .app bundle. -->
+        <key>com.apple.security.cs.allow-dyld-environment-variables</key>
+        <true/>
+    </dict>
+</plist>

+ 0 - 2
ci/ci_includes.cmd.in

@@ -1,2 +0,0 @@
-set PluginName=@CMAKE_PROJECT_NAME@
-set PluginVersion=@CMAKE_PROJECT_VERSION@

+ 0 - 4
ci/ci_includes.sh.in

@@ -1,4 +0,0 @@
-PLUGIN_NAME="@CMAKE_PROJECT_NAME@"
-PLUGIN_VERSION="@CMAKE_PROJECT_VERSION@"
-MACOS_BUNDLEID="@MACOS_BUNDLEID@"
-LINUX_MAINTAINER_EMAIL="@LINUX_MAINTAINER_EMAIL@"

+ 0 - 6
ci/linux/build-ubuntu.sh

@@ -1,6 +0,0 @@
-#!/bin/sh
-set -ex
-
-mkdir build && cd build
-cmake -DCMAKE_INSTALL_PREFIX=/usr ..
-make -j4

+ 0 - 19
ci/linux/install-dependencies-ubuntu.sh

@@ -1,19 +0,0 @@
-#!/bin/sh
-set -ex
-
-sudo add-apt-repository -y ppa:obsproject/obs-studio
-sudo apt-get -qq update
-
-sudo apt-get install -y \
-	libc-dev-bin \
-	libc6-dev git \
-	build-essential \
-	checkinstall \
-	cmake \
-	obs-studio \
-	qtbase5-dev
-
-# Dirty hack
-sudo wget -O /usr/include/obs/obs-frontend-api.h https://raw.githubusercontent.com/obsproject/obs-studio/25.0.0/UI/obs-frontend-api/obs-frontend-api.h
-
-sudo ldconfig

+ 0 - 25
ci/linux/package-ubuntu.sh

@@ -1,25 +0,0 @@
-#!/bin/bash
-
-set -e
-
-script_dir=$(dirname "$0")
-source "$script_dir/../ci_includes.generated.sh"
-
-export GIT_HASH=$(git rev-parse --short HEAD)
-export PKG_VERSION="1-$GIT_HASH-$BRANCH_SHORT_NAME-git"
-
-if [[ "$BRANCH_FULL_NAME" =~ "^refs/tags/" ]]; then
-	export PKG_VERSION="$BRANCH_SHORT_NAME"
-fi
-
-cd ./build
-
-PAGER="cat" sudo checkinstall -y --type=debian --fstrans=no --nodoc \
-	--backup=no --deldoc=yes --install=no \
-	--pkgname="$PLUGIN_NAME" --pkgversion="$PKG_VERSION" \
-	--pkglicense="GPLv2.0" --maintainer="$LINUX_MAINTAINER_EMAIL" \
-	--pkggroup="video" \
-	--requires="obs-studio \(\>= 25.0.7\), libqt5core5a, libqt5widgets5, qt5-image-formats-plugins" \
-	--pakdir="../package"
-
-sudo chmod ao+r ../package/*

+ 0 - 28
ci/macos/build-macos.sh

@@ -1,28 +0,0 @@
-#!/bin/sh
-
-OSTYPE=$(uname)
-
-if [ "${OSTYPE}" != "Darwin" ]; then
-    echo "[Error] macOS build script can be run on Darwin-type OS only."
-    exit 1
-fi
-
-HAS_CMAKE=$(type cmake 2>/dev/null)
-
-if [ "${HAS_CMAKE}" = "" ]; then
-    echo "[Error] CMake not installed - please run 'install-dependencies-macos.sh' first."
-    exit 1
-fi
-
-#export QT_PREFIX="$(find /usr/local/Cellar/qt5 -d 1 | tail -n 1)"
-
-echo "=> Building plugin for macOS."
-mkdir -p build && cd build
-cmake .. \
-	-DQTDIR=/usr/local/opt/qt \
-	-DLIBOBS_INCLUDE_DIR=../../obs-studio/libobs \
-	-DLIBOBS_LIB=../../obs-studio/libobs \
-	-DOBS_FRONTEND_LIB="$(pwd)/../../obs-studio/build/UI/obs-frontend-api/libobs-frontend-api.dylib" \
-	-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-	-DCMAKE_INSTALL_PREFIX=/usr \
-&& make -j4

+ 0 - 43
ci/macos/install-build-obs-macos.sh

@@ -1,43 +0,0 @@
-#!/bin/sh
-
-OSTYPE=$(uname)
-
-if [ "${OSTYPE}" != "Darwin" ]; then
-    echo "[Error] macOS obs-studio build script can be run on Darwin-type OS only."
-    exit 1
-fi
-
-HAS_CMAKE=$(type cmake 2>/dev/null)
-HAS_GIT=$(type git 2>/dev/null)
-
-if [ "${HAS_CMAKE}" = "" ]; then
-    echo "[Error] CMake not installed - please run 'install-dependencies-macos.sh' first."
-    exit 1
-fi
-
-if [ "${HAS_GIT}" = "" ]; then
-    echo "[Error] Git not installed - please install Xcode developer tools or via Homebrew."
-    exit 1
-fi
-
-echo "=> Downloading and unpacking OBS dependencies"
-wget --quiet --retry-connrefused --waitretry=1 https://obs-nightly.s3.amazonaws.com/osx-deps-2018-08-09.tar.gz
-tar -xf ./osx-deps-2018-08-09.tar.gz -C /tmp
-
-# Build obs-studio
-cd ..
-echo "=> Cloning obs-studio from GitHub.."
-git clone https://github.com/obsproject/obs-studio
-cd obs-studio
-OBSLatestTag=$(git describe --tags --abbrev=0)
-git checkout $OBSLatestTag
-mkdir build && cd build
-echo "=> Building obs-studio.."
-cmake .. \
-	-DBUILD_CAPTIONS=true \
-	-DCMAKE_OSX_DEPLOYMENT_TARGET=10.11 \
-	-DDISABLE_PLUGINS=true \
-    -DENABLE_SCRIPTING=0 \
-	-DDepsPath=/tmp/obsdeps \
-	-DCMAKE_PREFIX_PATH=/usr/local/opt/qt/lib/cmake \
-&& make -j4

+ 0 - 62
ci/macos/install-dependencies-macos.sh

@@ -1,62 +0,0 @@
-#!/bin/sh
-
-
-
-OSTYPE=$(uname)
-
-if [ "${OSTYPE}" != "Darwin" ]; then
-    echo "[Error] macOS install dependencies script can be run on Darwin-type OS only."
-    exit 1
-fi
-
-HAS_BREW=$(type brew 2>/dev/null)
-
-if [ "${HAS_BREW}" = "" ]; then
-    echo "[Error] Please install Homebrew (https://www.brew.sh/) to build this plugin on macOS."
-    exit 1
-fi
-
-# OBS Studio deps
-echo "=> Updating Homebrew.."
-brew update >/dev/null
-
-echo "[=> Checking installed Homebrew formulas.."
-BREW_PACKAGES=$(brew list)
-BREW_DEPENDENCIES="jack speexdsp ccache swig mbedtls"
-
-for DEPENDENCY in ${BREW_DEPENDENCIES}; do
-    if echo "${BREW_PACKAGES}" | grep -q "^${DEPENDENCY}\$"; then
-        echo "=> Upgrading OBS-Studio dependency '${DEPENDENCY}'.."
-        brew upgrade ${DEPENDENCY} 2>/dev/null
-    else
-        echo "=> Installing OBS-Studio dependency '${DEPENDENCY}'.."
-        brew install ${DEPENDENCY} 2>/dev/null
-    fi
-done
-
-# qtwebsockets deps
-echo "=> Installing plugin dependency 'QT 5.10.1'.."
-# =!= NOTICE =!=
-# When building QT5 from sources on macOS 10.13+, use local qt5 formula:
-# brew install ./CI/macos/qt.rb
-# Pouring from the bottle is much quicker though, so use bottle for now.
-# =!= NOTICE =!=
-
-brew install https://gist.githubusercontent.com/DDRBoxman/b3956fab6073335a4bf151db0dcbd4ad/raw/ed1342a8a86793ea8c10d8b4d712a654da121ace/qt.rb
-
-# Pin this version of QT5 to avoid `brew upgrade`
-# upgrading it to incompatible version
-brew pin qt
-
-# Fetch and install Packages app
-# =!= NOTICE =!=
-# Installs a LaunchDaemon under /Library/LaunchDaemons/fr.whitebox.packages.build.dispatcher.plist
-# =!= NOTICE =!=
-
-HAS_PACKAGES=$(type packagesbuild 2>/dev/null)
-
-if [ "${HAS_PACKAGES}" = "" ]; then
-    echo "=> Installing Packaging app (might require password due to 'sudo').."
-    curl -o './Packages.pkg' --retry-connrefused -s --retry-delay 1 'https://s3-us-west-2.amazonaws.com/obs-nightly/Packages.pkg'
-    sudo installer -pkg ./Packages.pkg -target /
-fi

+ 0 - 93
ci/macos/package-macos.sh

@@ -1,93 +0,0 @@
-#!/bin/bash
-
-set -e
-
-script_dir=$(dirname "$0")
-source "$script_dir/../ci_includes.generated.sh"
-
-OSTYPE=$(uname)
-
-if [ "${OSTYPE}" != "Darwin" ]; then
-    echo "[Error] macOS package script can be run on Darwin-type OS only."
-    exit 1
-fi
-
-echo "=> Preparing package build"
-export QT_CELLAR_PREFIX="$(/usr/bin/find /usr/local/Cellar/qt -d 1 | sort -t '.' -k 1,1n -k 2,2n -k 3,3n | tail -n 1)"
-
-GIT_HASH=$(git rev-parse --short HEAD)
-GIT_BRANCH_OR_TAG=$(git name-rev --name-only HEAD | awk -F/ '{print $NF}')
-
-PKG_VERSION="$GIT_HASH-$GIT_BRANCH_OR_TAG"
-
-FILENAME_UNSIGNED="$PLUGIN_NAME-$PKG_VERSION-Unsigned.pkg"
-FILENAME="$PLUGIN_NAME-$PKG_VERSION.pkg"
-
-echo "=> Modifying $PLUGIN_NAME.so"
-install_name_tool \
-	-change /usr/local/opt/qt/lib/QtWidgets.framework/Versions/5/QtWidgets \
-		@executable_path/../Frameworks/QtWidgets.framework/Versions/5/QtWidgets \
-	-change /usr/local/opt/qt/lib/QtGui.framework/Versions/5/QtGui \
-		@executable_path/../Frameworks/QtGui.framework/Versions/5/QtGui \
-	-change /usr/local/opt/qt/lib/QtCore.framework/Versions/5/QtCore \
-		@executable_path/../Frameworks/QtCore.framework/Versions/5/QtCore \
-	./build/$PLUGIN_NAME.so
-
-# Check if replacement worked
-echo "=> Dependencies for $PLUGIN_NAME"
-otool -L ./build/$PLUGIN_NAME.so
-
-if [[ "$RELEASE_MODE" == "True" ]]; then
-	echo "=> Signing plugin binary: $PLUGIN_NAME.so"
-	codesign --sign "$CODE_SIGNING_IDENTITY" ./build/$PLUGIN_NAME.so
-else
-	echo "=> Skipped plugin codesigning"
-fi
-
-echo "=> Actual package build"
-packagesbuild ./installer/installer-macOS.generated.pkgproj
-
-echo "=> Renaming $PLUGIN_NAME.pkg to $FILENAME"
-mv ./release/$PLUGIN_NAME.pkg ./release/$FILENAME_UNSIGNED
-
-if [[ "$RELEASE_MODE" == "True" ]]; then
-	echo "=> Signing installer: $FILENAME"
-	productsign \
-		--sign "$INSTALLER_SIGNING_IDENTITY" \
-		./release/$FILENAME_UNSIGNED \
-		./release/$FILENAME
-	rm ./release/$FILENAME_UNSIGNED
-
-	echo "=> Submitting installer $FILENAME for notarization"
-	zip -r ./release/$FILENAME.zip ./release/$FILENAME
-	UPLOAD_RESULT=$(xcrun altool \
-		--notarize-app \
-		--primary-bundle-id "$MACOS_BUNDLEID" \
-		--username "$AC_USERNAME" \
-		--password "$AC_PASSWORD" \
-		--asc-provider "$AC_PROVIDER_SHORTNAME" \
-		--file "./release/$FILENAME.zip")
-	rm ./release/$FILENAME.zip
-
-	REQUEST_UUID=$(echo $UPLOAD_RESULT | awk -F ' = ' '/RequestUUID/ {print $2}')
-	echo "Request UUID: $REQUEST_UUID"
-
-	echo "=> Wait for notarization result"
-	# Pieces of code borrowed from rednoah/notarized-app
-	while sleep 30 && date; do
-		CHECK_RESULT=$(xcrun altool \
-			--notarization-info "$REQUEST_UUID" \
-			--username "$AC_USERNAME" \
-			--password "$AC_PASSWORD" \
-			--asc-provider "$AC_PROVIDER_SHORTNAME")
-		echo $CHECK_RESULT
-
-		if ! grep -q "Status: in progress" <<< "$CHECK_RESULT"; then
-			echo "=> Staple ticket to installer: $FILENAME"
-			xcrun stapler staple ./release/$FILENAME
-			break
-		fi
-	done
-else
-	echo "=> Skipped installer codesigning and notarization"
-fi

+ 0 - 163
ci/macos/qt.rb

@@ -1,163 +0,0 @@
-# Patches for Qt must be at the very least submitted to Qt's Gerrit codereview
-# rather than their bug-report Jira. The latter is rarely reviewed by Qt.
-class Qt < Formula
-	desc "Cross-platform application and UI framework"
-	homepage "https://www.qt.io/"
-	url "https://download.qt.io/archive/qt/5.10/5.10.1/single/qt-everywhere-src-5.10.1.tar.xz"
-	mirror "https://mirrorservice.org/sites/download.qt-project.org/official_releases/qt/5.10/5.10.1/single/qt-everywhere-src-5.10.1.tar.xz"
-	sha256 "05ffba7b811b854ed558abf2be2ddbd3bb6ddd0b60ea4b5da75d277ac15e740a"
-	head "https://code.qt.io/qt/qt5.git", :branch => "5.10.1", :shallow => false
-
-	bottle do
-		sha256 "8b4bad005596a5f8790150fe455db998ac2406f4e0f04140d6656205d844d266" => :high_sierra
-		sha256 "9c488554935fb573554a4e36d36d3c81e47245b7fefc4b61edef894e67ba1740" => :sierra
-		sha256 "c0407afba5951df6cc4c6f6c1c315972bd41c99cecb4e029919c4c15ab6f7bdc" => :el_capitan
-	end
-
-	keg_only "Qt 5 has CMake issues when linked"
-
-	option "with-docs", "Build documentation"
-	option "with-examples", "Build examples"
-
-	deprecated_option "with-mysql" => "with-mysql-client"
-
-	# OS X 10.7 Lion is still supported in Qt 5.5, but is no longer a reference
-	# configuration and thus untested in practice. Builds on OS X 10.7 have been
-	# reported to fail: <https://github.com/Homebrew/homebrew/issues/45284>.
-	depends_on :macos => :mountain_lion
-
-	depends_on "pkg-config" => :build
-	depends_on :xcode => :build
-	depends_on "mysql-client" => :optional
-	depends_on "postgresql" => :optional
-
-	# Restore `.pc` files for framework-based build of Qt 5 on OS X. This
-	# partially reverts <https://codereview.qt-project.org/#/c/140954/> merged
-	# between the 5.5.1 and 5.6.0 releases. (Remove this as soon as feasible!)
-	#
-	# Core formulae known to fail without this patch (as of 2016-10-15):
-	#   * gnuplot  (with `--with-qt` option)
-	#   * mkvtoolnix (with `--with-qt` option, silent build failure)
-	#   * poppler    (with `--with-qt` option)
-	patch do
-		url "https://raw.githubusercontent.com/Homebrew/formula-patches/e8fe6567/qt5/restore-pc-files.patch"
-		sha256 "48ff18be2f4050de7288bddbae7f47e949512ac4bcd126c2f504be2ac701158b"
-	end
-
-	# Fix compile error on macOS 10.13 around QFixed:
-	# https://github.com/Homebrew/homebrew-core/issues/27095
-	# https://bugreports.qt.io/browse/QTBUG-67545
-	patch do
-		url "https://raw.githubusercontent.com/z00m1n/formula-patches/0de0e229/qt/QTBUG-67545.patch"
-		sha256 "4a115097c7582c7dce4207f5500d13feb8c990eb8a05a43f41953985976ebe6c"
-	end
-
-	# Fix compile error on macOS 10.13 caused by qtlocation dependency
-	# mapbox-gl-native using Boost 1.62.0 does not build with C++ 17:
-	# https://github.com/Homebrew/homebrew-core/issues/27095
-	# https://bugreports.qt.io/browse/QTBUG-67810
-	patch do
-		url "https://raw.githubusercontent.com/z00m1n/formula-patches/a1a1f0dd/qt/QTBUG-67810.patch"
-		sha256 "8ee0bf71df1043f08ebae3aa35036be29c4d9ebff8a27e3b0411a6bd635e9382"
-	end
-
-	def install
-		args = %W[
-			-verbose
-			-prefix #{prefix}
-			-release
-			-opensource -confirm-license
-			-system-zlib
-			-qt-libpng
-			-qt-libjpeg
-			-qt-freetype
-			-qt-pcre
-			-nomake tests
-			-no-rpath
-			-pkg-config
-			-dbus-runtime
-			-no-assimp
-		]
-
-		args << "-nomake" << "examples" if build.without? "examples"
-
-		if build.with? "mysql-client"
-			args << "-plugin-sql-mysql"
-			(buildpath/"brew_shim/mysql_config").write <<~EOS
-				#!/bin/sh
-				if [ x"$1" = x"--libs" ]; then
-					mysql_config --libs | sed "s/-lssl -lcrypto//"
-				else
-					exec mysql_config "$@"
-				fi
-			EOS
-			chmod 0755, "brew_shim/mysql_config"
-			args << "-mysql_config" << buildpath/"brew_shim/mysql_config"
-		end
-
-		args << "-plugin-sql-psql" if build.with? "postgresql"
-
-		system "./configure", *args
-		system "make"
-		ENV.deparallelize
-		system "make", "install"
-
-		if build.with? "docs"
-			system "make", "docs"
-			system "make", "install_docs"
-		end
-
-		# Some config scripts will only find Qt in a "Frameworks" folder
-		frameworks.install_symlink Dir["#{lib}/*.framework"]
-
-		# The pkg-config files installed suggest that headers can be found in the
-		# `include` directory. Make this so by creating symlinks from `include` to
-		# the Frameworks' Headers folders.
-		Pathname.glob("#{lib}/*.framework/Headers") do |path|
-			include.install_symlink path => path.parent.basename(".framework")
-		end
-
-		# Move `*.app` bundles into `libexec` to expose them to `brew linkapps` and
-		# because we don't like having them in `bin`.
-		# (Note: This move breaks invocation of Assistant via the Help menu
-		# of both Designer and Linguist as that relies on Assistant being in `bin`.)
-		libexec.mkpath
-		Pathname.glob("#{bin}/*.app") { |app| mv app, libexec }
-	end
-
-	def caveats; <<~EOS
-		We agreed to the Qt opensource license for you.
-		If this is unacceptable you should uninstall.
-		EOS
-	end
-
-	test do
-		(testpath/"hello.pro").write <<~EOS
-			QT       += core
-			QT       -= gui
-			TARGET = hello
-			CONFIG   += console
-			CONFIG   -= app_bundle
-			TEMPLATE = app
-			SOURCES += main.cpp
-		EOS
-
-		(testpath/"main.cpp").write <<~EOS
-			#include <QCoreApplication>
-			#include <QDebug>
-
-			int main(int argc, char *argv[])
-			{
-				QCoreApplication a(argc, argv);
-				qDebug() << "Hello World!";
-				return 0;
-			}
-		EOS
-
-		system bin/"qmake", testpath/"hello.pro"
-		system "make"
-		assert_predicate testpath/"hello", :exist?
-		assert_predicate testpath/"main.o", :exist?
-		system "./hello"
-	end
-end

+ 0 - 6
ci/windows/download-obs-deps.cmd

@@ -1,6 +0,0 @@
-if not exist %DepsBasePath% (
-    curl -o %DepsBasePath%.zip -kLO https://obsproject.com/downloads/dependencies2017.zip -f --retry 5 -C -
-    7z x %DepsBasePath%.zip -o%DepsBasePath%
-) else (
-    echo "OBS dependencies are already there. Download skipped."
-)

+ 0 - 8
ci/windows/install-qt-win.cmd

@@ -1,8 +0,0 @@
-if not exist %QtBaseDir% (
-	curl -kLO https://cdn-fastly.obsproject.com/downloads/Qt_5.10.1.7z -f --retry 5 -z Qt_5.10.1.7z
-    7z x Qt_5.10.1.7z -o%QtBaseDir%
-) else (
-	echo "Qt is already installed. Download skipped."
-)
-
-dir %QtBaseDir%

+ 0 - 14
ci/windows/package-windows.cmd

@@ -1,14 +0,0 @@
-call "%~dp0..\ci_includes.generated.cmd"
-
-mkdir package
-cd package
-
-git rev-parse --short HEAD > package-version.txt
-set /p PackageVersion=<package-version.txt
-del package-version.txt
-
-REM Package ZIP archive
-7z a "%PluginName%-%PackageVersion%-Windows.zip" "..\release\*"
-
-REM Build installer
-iscc ..\installer\installer-Windows.generated.iss /O. /F"%PluginName%-%PackageVersion%-Windows-Installer"

+ 0 - 36
ci/windows/prepare-obs-windows.cmd

@@ -1,36 +0,0 @@
-@echo off
-SETLOCAL EnableDelayedExpansion
-
-REM If obs-studio directory does not exist, clone the git repo
-if not exist %OBSPath% (
-	echo obs-studio directory does not exist
-	git clone https://github.com/obsproject/obs-studio %OBSPath%
-	cd /D %OBSPath%\
-	git describe --tags --abbrev=0 --exclude="*-rc*" > "%OBSPath%\obs-studio-latest-tag.txt"
-    set /p OBSLatestTag=<"%OBSPath%\obs-studio-latest-tag.txt"
-)
-
-REM Prepare OBS Studio builds
-
-echo Running CMake...
-cd /D %OBSPath%
-echo   git checkout %OBSLatestTag%
-git checkout %OBSLatestTag%
-echo:
-
-if not exist build32 mkdir build32
-if not exist build64 mkdir build64
-
-echo   Running cmake for obs-studio %OBSLatestTag% 32-bit...
-cd build32
-cmake -G "Visual Studio 16 2019" -A Win32 -DCMAKE_SYSTEM_VERSION=10.0 -DQTDIR="%QTDIR32%" -DDepsPath="%DepsPath32%" -DBUILD_CAPTIONS=true -DDISABLE_PLUGINS=true -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true ..
-echo:
-echo:
-
-echo   Running cmake for obs-studio %OBSLatestTag% 64-bit...
-cd ..\build64
-cmake -G "Visual Studio 16 2019" -A x64 -DCMAKE_SYSTEM_VERSION=10.0 -DQTDIR="%QTDIR64%" -DDepsPath="%DepsPath64%" -DBUILD_CAPTIONS=true -DDISABLE_PLUGINS=true -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true ..
-echo:
-echo:
-
-dir "%OBSPath%\libobs"

+ 0 - 15
ci/windows/prepare-windows.cmd

@@ -1,15 +0,0 @@
-mkdir build32
-mkdir build64
-
-cd build32
-cmake -G "Visual Studio 16 2019" -A Win32 -DCMAKE_SYSTEM_VERSION=10.0 -DQTDIR="%QTDIR32%" -DLibObs_DIR="%OBSPath%\build32\libobs" -DLIBOBS_INCLUDE_DIR="%OBSPath%\libobs" -DLIBOBS_LIB="%OBSPath%\build32\libobs\%build_config%\obs.lib" -DOBS_FRONTEND_LIB="%OBSPath%\build32\UI\obs-frontend-api\%build_config%\obs-frontend-api.lib" ..
-cd ..\build64
-cmake -G "Visual Studio 16 2019" -A x64 -DCMAKE_SYSTEM_VERSION=10.0 -DQTDIR="%QTDIR64%" -DLibObs_DIR="%OBSPath%\build64\libobs" -DLIBOBS_INCLUDE_DIR="%OBSPath%\libobs" -DLIBOBS_LIB="%OBSPath%\build64\libobs\%build_config%\obs.lib" -DOBS_FRONTEND_LIB="%OBSPath%\build64\UI\obs-frontend-api\%build_config%\obs-frontend-api.lib" ..
-
-REM Import the generated includes to get the plugin's name
-call "%~dp0..\ci_includes.generated.cmd"
-
-REM Rename the solution files to something CI can pick up 
-cd ..
-ren "build32\%PluginName%.sln" "main.sln"
-ren "build64\%PluginName%.sln" "main.sln"

+ 0 - 107
external/FindLibObs.cmake

@@ -1,107 +0,0 @@
-# This module can be copied and used by external plugins for OBS
-#
-# Once done these will be defined:
-#
-#  LIBOBS_FOUND
-#  LIBOBS_INCLUDE_DIRS
-#  LIBOBS_LIBRARIES
-
-find_package(PkgConfig QUIET)
-if (PKG_CONFIG_FOUND)
-	pkg_check_modules(_OBS QUIET obs libobs)
-endif()
-
-if(CMAKE_SIZEOF_VOID_P EQUAL 8)
-	set(_lib_suffix 64)
-else()
-	set(_lib_suffix 32)
-endif()
-
-if(DEFINED CMAKE_BUILD_TYPE)
-	if(CMAKE_BUILD_TYPE STREQUAL "Debug")
-		set(_build_type_base "debug")
-	else()
-		set(_build_type_base "release")
-	endif()
-endif()
-
-find_path(LIBOBS_INCLUDE_DIR
-	NAMES obs.h
-	HINTS
-		ENV obsPath${_lib_suffix}
-		ENV obsPath
-		${obsPath}
-	PATHS
-		/usr/include /usr/local/include /opt/local/include /sw/include
-	PATH_SUFFIXES
-		libobs
-	)
-
-function(find_obs_lib base_name repo_build_path lib_name)
-	string(TOUPPER "${base_name}" base_name_u)
-
-	if(DEFINED _build_type_base)
-		set(_build_type_${repo_build_path} "${_build_type_base}/${repo_build_path}")
-		set(_build_type_${repo_build_path}${_lib_suffix} "${_build_type_base}${_lib_suffix}/${repo_build_path}")
-	endif()
-
-	find_library(${base_name_u}_LIB
-		NAMES ${_${base_name_u}_LIBRARIES} ${lib_name} lib${lib_name}
-		HINTS
-			ENV obsPath${_lib_suffix}
-			ENV obsPath
-			${obsPath}
-			${_${base_name_u}_LIBRARY_DIRS}
-		PATHS
-			/usr/lib /usr/local/lib /opt/local/lib /sw/lib
-		PATH_SUFFIXES
-			lib${_lib_suffix} lib
-			libs${_lib_suffix} libs
-			bin${_lib_suffix} bin
-			../lib${_lib_suffix} ../lib
-			../libs${_lib_suffix} ../libs
-			../bin${_lib_suffix} ../bin
-			# base repo non-msvc-specific search paths
-			${_build_type_${repo_build_path}}
-			${_build_type_${repo_build_path}${_lib_suffix}}
-			build/${repo_build_path}
-			build${_lib_suffix}/${repo_build_path}
-			# base repo msvc-specific search paths on windows
-			build${_lib_suffix}/${repo_build_path}/Debug
-			build${_lib_suffix}/${repo_build_path}/RelWithDebInfo
-			build/${repo_build_path}/Debug
-			build/${repo_build_path}/RelWithDebInfo
-		)
-endfunction()
-
-find_obs_lib(LIBOBS libobs obs)
-
-if(MSVC)
-	find_obs_lib(W32_PTHREADS deps/w32-pthreads w32-pthreads)
-endif()
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(Libobs DEFAULT_MSG LIBOBS_LIB LIBOBS_INCLUDE_DIR)
-mark_as_advanced(LIBOBS_INCLUDE_DIR LIBOBS_LIB)
-
-if(LIBOBS_FOUND)
-	if(MSVC)
-		if (NOT DEFINED W32_PTHREADS_LIB)
-			message(FATAL_ERROR "Could not find the w32-pthreads library" )
-		endif()
-
-		set(W32_PTHREADS_INCLUDE_DIR ${LIBOBS_INCLUDE_DIR}/../deps/w32-pthreads)
-	endif()
-
-	set(LIBOBS_INCLUDE_DIRS ${LIBOBS_INCLUDE_DIR} ${W32_PTHREADS_INCLUDE_DIR})
-	set(LIBOBS_LIBRARIES ${LIBOBS_LIB} ${W32_PTHREADS_LIB})
-	include(${LIBOBS_INCLUDE_DIR}/../cmake/external/ObsPluginHelpers.cmake)
-
-	# allows external plugins to easily use/share common dependencies that are often included with libobs (such as FFmpeg)
-	if(NOT DEFINED INCLUDED_LIBOBS_CMAKE_MODULES)
-		set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${LIBOBS_INCLUDE_DIR}/../cmake/Modules/")
-		set(INCLUDED_LIBOBS_CMAKE_MODULES true)
-	endif()
-else()
-	message(FATAL_ERROR "Could not find the libobs library" )
-endif()

+ 274 - 0
external/ObsPluginHelpers.cmake

@@ -0,0 +1,274 @@
+if(POLICY CMP0087)
+	cmake_policy(SET CMP0087 NEW)
+endif()
+
+set(OBS_STANDALONE_PLUGIN_DIR "${CMAKE_SOURCE_DIR}/release")
+set(INCLUDED_LIBOBS_CMAKE_MODULES ON)
+
+include(GNUInstallDirs)
+if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
+	set(OS_MACOS ON)
+	set(OS_POSIX ON)
+elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Linux|FreeBSD|OpenBSD")
+	set(OS_POSIX ON)
+	string(TOUPPER "${CMAKE_SYSTEM_NAME}" _SYSTEM_NAME_U)
+	set(OS_${_SYSTEM_NAME_U} ON)
+elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
+	set(OS_WINDOWS ON)
+	set(OS_POSIX OFF)
+endif()
+
+# Old-Style plugin detected, find "modern" libobs variant instead and set
+# global include directories to fix "bad" plugin behaviour
+if(DEFINED LIBOBS_INCLUDE_DIR AND NOT TARGET OBS::libobs)
+	message(DEPRECATION "You are using an outdated method of adding 'libobs' to your project. Refer to the updated wiki on how to build and export 'libobs' and use it in your plugin projects.")
+	find_package(libobs REQUIRED)
+	if(TARGET OBS::libobs)
+		set_target_properties(OBS::libobs PROPERTIES IMPORTED_GLOBAL TRUE)
+		message(STATUS "OBS: Using modern libobs target")
+
+		add_library(libobs ALIAS OBS::libobs)
+		if(OS_WINDOWS)
+			add_library(w32-pthreads ALIAS OBS::w32-pthreads)
+		endif()
+	endif()
+endif()
+
+if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND (OS_WINDOWS OR OS_MACOS))
+	set(CMAKE_INSTALL_PREFIX "${OBS_STANDALONE_PLUGIN_DIR}" CACHE STRING "Directory to install OBS plugin after building" FORCE)
+endif()
+
+if(NOT CMAKE_BUILD_TYPE)
+	set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
+		"OBS build type [Release, RelWithDebInfo, Debug, MinSizeRel]" FORCE)
+	set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Release RelWithDebInfo Debug MinSizeRel)
+endif()
+
+file(RELATIVE_PATH RELATIVE_INSTALL_PATH "${CMAKE_SOURCE_DIR}" "${CMAKE_INSTALL_PREFIX}")
+file(RELATIVE_PATH RELATIVE_BUILD_PATH "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}")
+
+# Set-up OS-specific environment and helper functions
+if(OS_MACOS)
+	if(NOT CMAKE_OSX_ARCHITECTURES)
+		set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE STRING "OBS plugin build architecture for macOS - x86_64 required at least" FORCE)
+	endif()
+
+	if(NOT CMAKE_OSX_DEPLOYMENT_TARGET)
+		set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13" CACHE STRING "OBS plugin deployment target for macOS - 10.13+ required" FORCE)
+	endif()
+
+	if(NOT DEFINED OBS_CODESIGN_LINKER)
+		set(OBS_CODESIGN_LINKER ON CACHE BOOL "Enable linker code-signing on macOS (v11+ required" FORCE)
+	endif()
+
+	if(NOT DEFINED OBS_BUNDLE_CODESIGN_IDENTITY)
+		set(OBS_BUNDLE_CODESIGN_IDENTITY "-" CACHE STRING "Codesign identity for macOS" FORCE)
+	endif()
+
+	# Xcode configuration
+	if(XCODE)
+		# Tell Xcode to pretend the linker signed binaries so that
+		# editing with install_name_tool preserves ad-hoc signatures.
+		# See CMake Issue 21854.
+		# This option is supported by codesign on macOS 11 or higher.
+		set(CMAKE_XCODE_GENERATE_SCHEME ON)
+		if(OBS_CODESIGN_LINKER)
+			set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS "-o linker-signed")
+		endif()
+	endif()
+
+	# Set default options for bundling on macOS
+	set(CMAKE_MACOSX_RPATH ON)
+	set(CMAKE_SKIP_BUILD_RPATH OFF)
+	set(CMAKE_BUILD_WITH_INSTALL_RPATH OFF)
+	set(CMAKE_INSTALL_RPATH "@executable_path/../Frameworks/")
+	set(CMAKE_INSTALL_RPATH_USE_LINK_PATH OFF)
+
+	function(setup_plugin_target target)
+		if(NOT DEFINED MACOSX_PLUGIN_GUI_IDENTIFIER)
+			message(FATAL_ERROR "No 'MACOSX_PLUGIN_GUI_IDENTIFIER' set, but is required to build plugin bundles on macOS - example: 'com.yourname.pluginname'")
+		endif()
+
+		if(NOT DEFINED MACOSX_PLUGIN_BUNDLE_VERSION)
+			message(FATAL_ERROR "No 'MACOSX_PLUGIN_BUNDLE_VERSION' set, but is required to build plugin bundles on macOS - example: '25'")
+		endif()
+
+		if(NOT DEFINED MACOSX_PLUGIN_SHORT_VERSION_STRING)
+			message(FATAL_ERROR "No 'MACOSX_PLUGIN_SHORT_VERSION_STRING' set, but is required to build plugin bundles on macOS - example: '1.0.2'")
+		endif()
+
+		set(MACOSX_PLUGIN_BUNDLE_NAME "${target}" PARENT_SCOPE)
+		set(MACOSX_PLUGIN_BUNDLE_VERSION "${MACOSX_BUNDLE_BUNDLE_VERSION}" PARENT_SCOPE)
+		set(MACOSX_PLUGIN_SHORT_VERSION_STRING "${MACOSX_BUNDLE_SHORT_VERSION_STRING}" PARENT_SCOPE)
+		set(MACOSX_PLUGIN_EXECUTABLE_NAME "${target}" PARENT_SCOPE)
+		set(MACOSX_PLUGIN_BUNDLE_TYPE "BNDL" PARENT_SCOPE)
+
+		install(TARGETS ${target}
+			LIBRARY DESTINATION "."
+				COMPONENT obs_plugins
+				NAMELINK_COMPONENT ${target}_Development)
+
+		install(CODE
+			"execute_process(COMMAND /bin/sh -c \"install_name_tool \\
+			-change ${CMAKE_PREFIX_PATH}/lib/QtWidgets.framework/Versions/5/QtWidgets @rpath/QtWidgets.framework/Versions/5/QtWidgets \\
+			-change ${CMAKE_PREFIX_PATH}/lib/QtCore.framework/Versions/5/QtCore @rpath/QtCore.framework/Versions/5/QtCore \\
+			-change ${CMAKE_PREFIX_PATH}/lib/QtGui.framework/Versions/5/QtGui @rpath/QtGui.framework/Versions/5/QtGui \\
+			${CMAKE_INSTALL_PREFIX}/${target}.plugin/Contents/MacOS/${target}\")")
+
+		if(NOT XCODE)
+			install(CODE
+				"execute_process(COMMAND /bin/sh -c \"/usr/bin/codesign --force --sign \\\"${OBS_BUNDLE_CODESIGN_IDENTITY}\\\" --options runtime --entitlements ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../bundle/macOS/entitlements.plist ${CMAKE_INSTALL_PREFIX}/${target}.plugin\")")
+		endif()
+
+		set_target_properties(${target} PROPERTIES
+			BUNDLE ON
+			BUNDLE_EXTENSION "plugin"
+			OUTPUT_NAME ${target}
+			MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../bundle/macOS/Plugin-Info.plist.in"
+			XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${MACOSX_PLUGIN_GUI_IDENTIFIER}"
+			XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${OBS_BUNDLE_CODESIGN_IDENTITY}"
+			XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../bundle/macOS/entitlements.plist")
+
+		add_custom_command(TARGET ${target} POST_BUILD
+			COMMAND /bin/sh -c "codesign --force --sign \"-\" $<$<BOOL:${OBS_CODESIGN_LINKER}>:--options linker-signed >\"$<TARGET_BUNDLE_DIR:${target}>\""
+			COMMENT "Codesigning ${target}"
+			VERBATIM)
+
+		install_bundle_resources(${target})
+	endfunction()
+
+	function(install_bundle_resources target)
+		if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/data")
+			file(GLOB_RECURSE _DATA_FILES "${CMAKE_CURRENT_SOURCE_DIR}/data/*")
+			foreach(_DATA_FILE IN LISTS _DATA_FILES)
+				file(RELATIVE_PATH _RELATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/data/ ${_DATA_FILE})
+				get_filename_component(_RELATIVE_PATH "${_RELATIVE_PATH}" PATH)
+				target_sources(${target}
+					PRIVATE ${_DATA_FILE})
+				set_source_files_properties(${_DATA_FILE} PROPERTIES
+					MACOSX_PACKAGE_LOCATION "Resources/${_RELATIVE_PATH}")
+				string(REPLACE "\\" "\\\\" _GROUP_NAME "${_RELATIVE_PATH}")
+				source_group("Resources\\${_GROUP_NAME}" FILES ${_DATA_FILE})
+			endforeach()
+		endif()
+	endfunction()
+else()
+	if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+		set(_ARCH_SUFFIX 64)
+	else()
+		set(_ARCH_SUFFIX 32)
+	endif()
+	set(OBS_OUTPUT_DIR "${CMAKE_BINARY_DIR}/rundir")
+
+	if(OS_POSIX)
+		IF(NOT LINUX_PORTABLE)
+			set(OBS_LIBRARY_DESTINATION "${CMAKE_INSTALL_LIBDIR}")
+			set(OBS_PLUGIN_DESTINATION "${OBS_LIBRARY_DESTINATION}/obs-plugins")
+			set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
+			set(OBS_DATA_DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/obs")
+		else()
+			set(OBS_LIBRARY_DESTINATION "bin/${_ARCH_SUFFIX}bit")
+			set(OBS_PLUGIN_DESTINATION "obs-plugins/${_ARCH_SUFFIX}bit")
+			set(CMAKE_INSTALL_RPATH "$ORIGIN/" "${CMAKE_INSTALL_PREFIX}/${OBS_LIBRARY_DESTINATION}")
+			set(OBS_DATA_DESTINATION "data")
+		endif()
+
+		if(OS_LINUX)
+			set(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}")
+			set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${LINUX_MAINTAINER_EMAIL}")
+			set(CPACK_PACKAGE_VERSION "${CMAKE_PROJECT_VERSION}")
+
+			set(CPACK_GENERATOR "DEB")
+			set(CPACK_DEBIAN_PACKAGE_DEPENDS
+				"obs-studio (>= 27.0.0), libqt5core5a (>= 5.9.0~beta), \
+				libqt5gui5 (>= 5.3.0), libqt5widgets5 (>= 5.7.0)")
+
+			if(NOT LINUX_PORTABLE)
+				set(CPACK_SET_DESTDIR ON)
+			endif()
+			include(CPack)
+		endif()
+	else()
+		set(OBS_LIBRARY_DESTINATION "bin/${_ARCH_SUFFIX}bit")
+		set(OBS_LIBRARY32_DESTINATION "bin/32bit")
+		set(OBS_LIBRARY64_DESTINATION "bin/64bit")
+		set(OBS_PLUGIN_DESTINATION "obs-plugins/${_ARCH_SUFFIX}bit")
+		set(OBS_PLUGIN32_DESTINATION "obs-plugins/32bit")
+		set(OBS_PLUGIN64_DESTINATION "obs-plugins/64bit")
+
+		set(OBS_DATA_DESTINATION "data")
+	endif()
+
+	function(setup_plugin_target target)
+		set_target_properties(${target} PROPERTIES
+			PREFIX "")
+
+		install(TARGETS ${target}
+			RUNTIME DESTINATION "${OBS_PLUGIN_DESTINATION}"
+				COMPONENT ${target}_Runtime
+			LIBRARY DESTINATION "${OBS_PLUGIN_DESTINATION}"
+				COMPONENT ${target}_Runtime
+				NAMELINK_COMPONENT ${target}_Development)
+
+		add_custom_command(TARGET ${target} POST_BUILD
+			COMMAND "${CMAKE_COMMAND}" -E copy
+				"$<TARGET_FILE:${target}>"
+				"${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_PLUGIN_DESTINATION}/$<TARGET_FILE_NAME:${target}>"
+			VERBATIM)
+
+		if(OS_WINDOWS)
+			add_custom_command(TARGET ${target} POST_BUILD
+				COMMAND "${CMAKE_COMMAND}" -E "$<IF:$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>,copy,true>"
+					"$<TARGET_PDB_FILE:${target}>"
+					"${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_PLUGIN_DESTINATION}/"
+				VERBATIM)
+		endif()
+
+		if(MSVC)
+			target_link_options(${target}
+				PRIVATE
+					"LINKER:/OPT:REF"
+					"$<$<NOT:$<EQUAL:${CMAKE_SIZEOF_VOID_P},8>>:LINKER\:/SAFESEH\:NO>"
+					"$<$<CONFIG:DEBUG>:LINKER\:/INCREMENTAL:NO>"
+					"$<$<CONFIG:RELWITHDEBINFO>:LINKER\:/INCREMENTAL:NO>")
+		endif()
+
+		setup_target_resources("${target}" "obs-plugins/${target}")
+
+		if(OS_WINDOWS AND DEFINED OBS_BUILD_DIR)
+			setup_target_for_testing(${target})
+		endif()
+	endfunction()
+
+	function(setup_target_resources target destination)
+		if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/data")
+			install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/data/"
+				DESTINATION "${OBS_DATA_DESTINATION}/${destination}"
+				USE_SOURCE_PERMISSIONS)
+
+			add_custom_command(TARGET ${target} POST_BUILD
+				COMMAND "${CMAKE_COMMAND}" -E copy_directory
+					"${CMAKE_CURRENT_SOURCE_DIR}/data"
+					"${OBS_OUTPUT_DIR}/$<CONFIG>/${OBS_DATA_DESTINATION}/${destination}"
+				VERBATIM)
+		endif()
+	endfunction()
+
+	if(OS_WINDOWS)
+		function(setup_target_for_testing target)
+			add_custom_command(TARGET ${target} POST_BUILD
+				COMMAND "${CMAKE_COMMAND}" -E copy
+					"$<TARGET_FILE:${target}>"
+					"${OBS_BUILD_DIR}/rundir/$<CONFIG>/${OBS_PLUGIN_DESTINATION}/$<TARGET_FILE_NAME:${target}>"
+				COMMAND "${CMAKE_COMMAND}" -E "$<IF:$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>,copy,true>"
+					"$<TARGET_PDB_FILE:${target}>"
+					"${OBS_BUILD_DIR}/rundir/$<CONFIG>/${OBS_PLUGIN_DESTINATION}/$<TARGET_FILE_NAME:${target}>"
+				COMMAND "${CMAKE_COMMAND}" -E make_directory
+					"${OBS_BUILD_DIR}/rundir/$<CONFIG>/${OBS_DATA_DESTINATION}/obs-plugins/${target}"
+				COMMAND "${CMAKE_COMMAND}" -E copy_directory
+					"${CMAKE_CURRENT_SOURCE_DIR}/data"
+					"${OBS_BUILD_DIR}/rundir/$<CONFIG>/${OBS_DATA_DESTINATION}/obs-plugins/${target}"
+				VERBATIM)
+		endfunction()
+	endif()
+endif()

+ 1 - 1
installer/installer-Windows.iss.in

@@ -55,7 +55,7 @@ var
 begin
   // initialize default path, which will be returned when the following registry
   // key queries fail due to missing keys or for some different reason
-  Result := '{pf}\obs-studio';
+  Result := '{autopf}\obs-studio';
   // query the first registry value; if this succeeds, return the obtained value
   if RegQueryStringValue(HKLM32, 'SOFTWARE\OBS Studio', '', InstallPath) then
     Result := InstallPath

+ 0 - 726
installer/installer-macOS.pkgproj.in

@@ -1,726 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>PROJECT</key>
-	<dict>
-		<key>PACKAGE_FILES</key>
-		<dict>
-			<key>DEFAULT_INSTALL_LOCATION</key>
-			<string>/</string>
-			<key>HIERARCHY</key>
-			<dict>
-				<key>CHILDREN</key>
-				<array>
-					<dict>
-						<key>CHILDREN</key>
-						<array>
-							<dict>
-								<key>CHILDREN</key>
-								<array>
-									<dict>
-										<key>CHILDREN</key>
-										<array>
-											<dict>
-												<key>CHILDREN</key>
-												<array>
-													<dict>
-														<key>CHILDREN</key>
-														<array>
-															<dict>
-																<key>CHILDREN</key>
-																<array>
-																	<dict>
-																		<key>CHILDREN</key>
-																		<array/>
-																		<key>GID</key>
-																		<integer>80</integer>
-																		<key>PATH</key>
-																		<string>../build/@CMAKE_PROJECT_NAME@.so</string>
-																		<key>PATH_TYPE</key>
-																		<integer>1</integer>
-																		<key>PERMISSIONS</key>
-																		<integer>493</integer>
-																		<key>TYPE</key>
-																		<integer>3</integer>
-																		<key>UID</key>
-																		<integer>0</integer>
-																	</dict>
-																</array>
-																<key>GID</key>
-																<integer>80</integer>
-																<key>PATH</key>
-																<string>bin</string>
-																<key>PATH_TYPE</key>
-																<integer>0</integer>
-																<key>PERMISSIONS</key>
-																<integer>493</integer>
-																<key>TYPE</key>
-																<integer>2</integer>
-																<key>UID</key>
-																<integer>0</integer>
-															</dict>
-															<dict>
-																<key>CHILDREN</key>
-																<array/>
-																<key>GID</key>
-																<integer>80</integer>
-																<key>PATH</key>
-																<string>../data</string>
-																<key>PATH_TYPE</key>
-																<integer>1</integer>
-																<key>PERMISSIONS</key>
-																<integer>493</integer>
-																<key>TYPE</key>
-																<integer>3</integer>
-																<key>UID</key>
-																<integer>0</integer>
-															</dict>
-														</array>
-														<key>GID</key>
-														<integer>80</integer>
-														<key>PATH</key>
-														<string>@CMAKE_PROJECT_NAME@</string>
-														<key>PATH_TYPE</key>
-														<integer>0</integer>
-														<key>PERMISSIONS</key>
-														<integer>493</integer>
-														<key>TYPE</key>
-														<integer>2</integer>
-														<key>UID</key>
-														<integer>0</integer>
-													</dict>
-												</array>
-												<key>GID</key>
-												<integer>80</integer>
-												<key>PATH</key>
-												<string>plugins</string>
-												<key>PATH_TYPE</key>
-												<integer>0</integer>
-												<key>PERMISSIONS</key>
-												<integer>493</integer>
-												<key>TYPE</key>
-												<integer>2</integer>
-												<key>UID</key>
-												<integer>0</integer>
-											</dict>
-										</array>
-										<key>GID</key>
-										<integer>80</integer>
-										<key>PATH</key>
-										<string>obs-studio</string>
-										<key>PATH_TYPE</key>
-										<integer>0</integer>
-										<key>PERMISSIONS</key>
-										<integer>493</integer>
-										<key>TYPE</key>
-										<integer>2</integer>
-										<key>UID</key>
-										<integer>0</integer>
-									</dict>
-								</array>
-								<key>GID</key>
-								<integer>80</integer>
-								<key>PATH</key>
-								<string>Application Support</string>
-								<key>PATH_TYPE</key>
-								<integer>0</integer>
-								<key>PERMISSIONS</key>
-								<integer>493</integer>
-								<key>TYPE</key>
-								<integer>1</integer>
-								<key>UID</key>
-								<integer>0</integer>
-							</dict>
-							<dict>
-								<key>CHILDREN</key>
-								<array/>
-								<key>GID</key>
-								<integer>0</integer>
-								<key>PATH</key>
-								<string>Automator</string>
-								<key>PATH_TYPE</key>
-								<integer>0</integer>
-								<key>PERMISSIONS</key>
-								<integer>493</integer>
-								<key>TYPE</key>
-								<integer>1</integer>
-								<key>UID</key>
-								<integer>0</integer>
-							</dict>
-							<dict>
-								<key>CHILDREN</key>
-								<array/>
-								<key>GID</key>
-								<integer>0</integer>
-								<key>PATH</key>
-								<string>Documentation</string>
-								<key>PATH_TYPE</key>
-								<integer>0</integer>
-								<key>PERMISSIONS</key>
-								<integer>493</integer>
-								<key>TYPE</key>
-								<integer>1</integer>
-								<key>UID</key>
-								<integer>0</integer>
-							</dict>
-							<dict>
-								<key>CHILDREN</key>
-								<array/>
-								<key>GID</key>
-								<integer>0</integer>
-								<key>PATH</key>
-								<string>Extensions</string>
-								<key>PATH_TYPE</key>
-								<integer>0</integer>
-								<key>PERMISSIONS</key>
-								<integer>493</integer>
-								<key>TYPE</key>
-								<integer>1</integer>
-								<key>UID</key>
-								<integer>0</integer>
-							</dict>
-							<dict>
-								<key>CHILDREN</key>
-								<array/>
-								<key>GID</key>
-								<integer>0</integer>
-								<key>PATH</key>
-								<string>Filesystems</string>
-								<key>PATH_TYPE</key>
-								<integer>0</integer>
-								<key>PERMISSIONS</key>
-								<integer>493</integer>
-								<key>TYPE</key>
-								<integer>1</integer>
-								<key>UID</key>
-								<integer>0</integer>
-							</dict>
-							<dict>
-								<key>CHILDREN</key>
-								<array/>
-								<key>GID</key>
-								<integer>0</integer>
-								<key>PATH</key>
-								<string>Frameworks</string>
-								<key>PATH_TYPE</key>
-								<integer>0</integer>
-								<key>PERMISSIONS</key>
-								<integer>493</integer>
-								<key>TYPE</key>
-								<integer>1</integer>
-								<key>UID</key>
-								<integer>0</integer>
-							</dict>
-							<dict>
-								<key>CHILDREN</key>
-								<array/>
-								<key>GID</key>
-								<integer>0</integer>
-								<key>PATH</key>
-								<string>Input Methods</string>
-								<key>PATH_TYPE</key>
-								<integer>0</integer>
-								<key>PERMISSIONS</key>
-								<integer>493</integer>
-								<key>TYPE</key>
-								<integer>1</integer>
-								<key>UID</key>
-								<integer>0</integer>
-							</dict>
-							<dict>
-								<key>CHILDREN</key>
-								<array/>
-								<key>GID</key>
-								<integer>0</integer>
-								<key>PATH</key>
-								<string>Internet Plug-Ins</string>
-								<key>PATH_TYPE</key>
-								<integer>0</integer>
-								<key>PERMISSIONS</key>
-								<integer>493</integer>
-								<key>TYPE</key>
-								<integer>1</integer>
-								<key>UID</key>
-								<integer>0</integer>
-							</dict>
-							<dict>
-								<key>CHILDREN</key>
-								<array/>
-								<key>GID</key>
-								<integer>0</integer>
-								<key>PATH</key>
-								<string>LaunchAgents</string>
-								<key>PATH_TYPE</key>
-								<integer>0</integer>
-								<key>PERMISSIONS</key>
-								<integer>493</integer>
-								<key>TYPE</key>
-								<integer>1</integer>
-								<key>UID</key>
-								<integer>0</integer>
-							</dict>
-							<dict>
-								<key>CHILDREN</key>
-								<array/>
-								<key>GID</key>
-								<integer>0</integer>
-								<key>PATH</key>
-								<string>LaunchDaemons</string>
-								<key>PATH_TYPE</key>
-								<integer>0</integer>
-								<key>PERMISSIONS</key>
-								<integer>493</integer>
-								<key>TYPE</key>
-								<integer>1</integer>
-								<key>UID</key>
-								<integer>0</integer>
-							</dict>
-							<dict>
-								<key>CHILDREN</key>
-								<array/>
-								<key>GID</key>
-								<integer>0</integer>
-								<key>PATH</key>
-								<string>PreferencePanes</string>
-								<key>PATH_TYPE</key>
-								<integer>0</integer>
-								<key>PERMISSIONS</key>
-								<integer>493</integer>
-								<key>TYPE</key>
-								<integer>1</integer>
-								<key>UID</key>
-								<integer>0</integer>
-							</dict>
-							<dict>
-								<key>CHILDREN</key>
-								<array/>
-								<key>GID</key>
-								<integer>0</integer>
-								<key>PATH</key>
-								<string>Preferences</string>
-								<key>PATH_TYPE</key>
-								<integer>0</integer>
-								<key>PERMISSIONS</key>
-								<integer>493</integer>
-								<key>TYPE</key>
-								<integer>1</integer>
-								<key>UID</key>
-								<integer>0</integer>
-							</dict>
-							<dict>
-								<key>CHILDREN</key>
-								<array/>
-								<key>GID</key>
-								<integer>80</integer>
-								<key>PATH</key>
-								<string>Printers</string>
-								<key>PATH_TYPE</key>
-								<integer>0</integer>
-								<key>PERMISSIONS</key>
-								<integer>493</integer>
-								<key>TYPE</key>
-								<integer>1</integer>
-								<key>UID</key>
-								<integer>0</integer>
-							</dict>
-							<dict>
-								<key>CHILDREN</key>
-								<array/>
-								<key>GID</key>
-								<integer>0</integer>
-								<key>PATH</key>
-								<string>PrivilegedHelperTools</string>
-								<key>PATH_TYPE</key>
-								<integer>0</integer>
-								<key>PERMISSIONS</key>
-								<integer>493</integer>
-								<key>TYPE</key>
-								<integer>1</integer>
-								<key>UID</key>
-								<integer>0</integer>
-							</dict>
-							<dict>
-								<key>CHILDREN</key>
-								<array/>
-								<key>GID</key>
-								<integer>0</integer>
-								<key>PATH</key>
-								<string>QuickLook</string>
-								<key>PATH_TYPE</key>
-								<integer>0</integer>
-								<key>PERMISSIONS</key>
-								<integer>493</integer>
-								<key>TYPE</key>
-								<integer>1</integer>
-								<key>UID</key>
-								<integer>0</integer>
-							</dict>
-							<dict>
-								<key>CHILDREN</key>
-								<array/>
-								<key>GID</key>
-								<integer>0</integer>
-								<key>PATH</key>
-								<string>QuickTime</string>
-								<key>PATH_TYPE</key>
-								<integer>0</integer>
-								<key>PERMISSIONS</key>
-								<integer>493</integer>
-								<key>TYPE</key>
-								<integer>1</integer>
-								<key>UID</key>
-								<integer>0</integer>
-							</dict>
-							<dict>
-								<key>CHILDREN</key>
-								<array/>
-								<key>GID</key>
-								<integer>0</integer>
-								<key>PATH</key>
-								<string>Screen Savers</string>
-								<key>PATH_TYPE</key>
-								<integer>0</integer>
-								<key>PERMISSIONS</key>
-								<integer>493</integer>
-								<key>TYPE</key>
-								<integer>1</integer>
-								<key>UID</key>
-								<integer>0</integer>
-							</dict>
-							<dict>
-								<key>CHILDREN</key>
-								<array/>
-								<key>GID</key>
-								<integer>0</integer>
-								<key>PATH</key>
-								<string>Scripts</string>
-								<key>PATH_TYPE</key>
-								<integer>0</integer>
-								<key>PERMISSIONS</key>
-								<integer>493</integer>
-								<key>TYPE</key>
-								<integer>1</integer>
-								<key>UID</key>
-								<integer>0</integer>
-							</dict>
-							<dict>
-								<key>CHILDREN</key>
-								<array/>
-								<key>GID</key>
-								<integer>0</integer>
-								<key>PATH</key>
-								<string>Services</string>
-								<key>PATH_TYPE</key>
-								<integer>0</integer>
-								<key>PERMISSIONS</key>
-								<integer>493</integer>
-								<key>TYPE</key>
-								<integer>1</integer>
-								<key>UID</key>
-								<integer>0</integer>
-							</dict>
-							<dict>
-								<key>CHILDREN</key>
-								<array/>
-								<key>GID</key>
-								<integer>0</integer>
-								<key>PATH</key>
-								<string>Widgets</string>
-								<key>PATH_TYPE</key>
-								<integer>0</integer>
-								<key>PERMISSIONS</key>
-								<integer>493</integer>
-								<key>TYPE</key>
-								<integer>1</integer>
-								<key>UID</key>
-								<integer>0</integer>
-							</dict>
-						</array>
-						<key>GID</key>
-						<integer>0</integer>
-						<key>PATH</key>
-						<string>Library</string>
-						<key>PATH_TYPE</key>
-						<integer>0</integer>
-						<key>PERMISSIONS</key>
-						<integer>493</integer>
-						<key>TYPE</key>
-						<integer>1</integer>
-						<key>UID</key>
-						<integer>0</integer>
-					</dict>
-					<dict>
-						<key>CHILDREN</key>
-						<array>
-							<dict>
-								<key>CHILDREN</key>
-								<array/>
-								<key>GID</key>
-								<integer>0</integer>
-								<key>PATH</key>
-								<string>Shared</string>
-								<key>PATH_TYPE</key>
-								<integer>0</integer>
-								<key>PERMISSIONS</key>
-								<integer>1023</integer>
-								<key>TYPE</key>
-								<integer>1</integer>
-								<key>UID</key>
-								<integer>0</integer>
-							</dict>
-						</array>
-						<key>GID</key>
-						<integer>80</integer>
-						<key>PATH</key>
-						<string>Users</string>
-						<key>PATH_TYPE</key>
-						<integer>0</integer>
-						<key>PERMISSIONS</key>
-						<integer>493</integer>
-						<key>TYPE</key>
-						<integer>1</integer>
-						<key>UID</key>
-						<integer>0</integer>
-					</dict>
-				</array>
-				<key>GID</key>
-				<integer>0</integer>
-				<key>PATH</key>
-				<string>/</string>
-				<key>PATH_TYPE</key>
-				<integer>0</integer>
-				<key>PERMISSIONS</key>
-				<integer>493</integer>
-				<key>TYPE</key>
-				<integer>1</integer>
-				<key>UID</key>
-				<integer>0</integer>
-			</dict>
-			<key>PAYLOAD_TYPE</key>
-			<integer>0</integer>
-			<key>VERSION</key>
-			<integer>4</integer>
-		</dict>
-		<key>PACKAGE_SCRIPTS</key>
-		<dict>
-			<key>RESOURCES</key>
-			<array/>
-		</dict>
-		<key>PACKAGE_SETTINGS</key>
-		<dict>
-			<key>AUTHENTICATION</key>
-			<integer>1</integer>
-			<key>CONCLUSION_ACTION</key>
-			<integer>0</integer>
-			<key>IDENTIFIER</key>
-			<string>@MACOS_BUNDLEID@</string>
-			<key>OVERWRITE_PERMISSIONS</key>
-			<false/>
-			<key>VERSION</key>
-			<string>@CMAKE_PROJECT_VERSION@</string>
-		</dict>
-		<key>PROJECT_COMMENTS</key>
-		<dict>
-			<key>NOTES</key>
-			<data>
-			PCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBIVE1M
-			IDQuMDEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbDQv
-			c3RyaWN0LmR0ZCI+CjxodG1sPgo8aGVhZD4KPG1ldGEgaHR0cC1l
-			cXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7
-			IGNoYXJzZXQ9VVRGLTgiPgo8bWV0YSBodHRwLWVxdWl2PSJDb250
-			ZW50LVN0eWxlLVR5cGUiIGNvbnRlbnQ9InRleHQvY3NzIj4KPHRp
-			dGxlPjwvdGl0bGU+CjxtZXRhIG5hbWU9IkdlbmVyYXRvciIgY29u
-			dGVudD0iQ29jb2EgSFRNTCBXcml0ZXIiPgo8bWV0YSBuYW1lPSJD
-			b2NvYVZlcnNpb24iIGNvbnRlbnQ9IjE0MDQuMTMiPgo8c3R5bGUg
-			dHlwZT0idGV4dC9jc3MiPgo8L3N0eWxlPgo8L2hlYWQ+Cjxib2R5
-			Pgo8L2JvZHk+CjwvaHRtbD4K
-			</data>
-		</dict>
-		<key>PROJECT_SETTINGS</key>
-		<dict>
-			<key>BUILD_PATH</key>
-			<dict>
-				<key>PATH</key>
-				<string>../release</string>
-				<key>PATH_TYPE</key>
-				<integer>1</integer>
-			</dict>
-			<key>EXCLUDED_FILES</key>
-			<array>
-				<dict>
-					<key>PATTERNS_ARRAY</key>
-					<array>
-						<dict>
-							<key>REGULAR_EXPRESSION</key>
-							<false/>
-							<key>STRING</key>
-							<string>.DS_Store</string>
-							<key>TYPE</key>
-							<integer>0</integer>
-						</dict>
-					</array>
-					<key>PROTECTED</key>
-					<true/>
-					<key>PROXY_NAME</key>
-					<string>Remove .DS_Store files</string>
-					<key>PROXY_TOOLTIP</key>
-					<string>Remove ".DS_Store" files created by the Finder.</string>
-					<key>STATE</key>
-					<true/>
-				</dict>
-				<dict>
-					<key>PATTERNS_ARRAY</key>
-					<array>
-						<dict>
-							<key>REGULAR_EXPRESSION</key>
-							<false/>
-							<key>STRING</key>
-							<string>.pbdevelopment</string>
-							<key>TYPE</key>
-							<integer>0</integer>
-						</dict>
-					</array>
-					<key>PROTECTED</key>
-					<true/>
-					<key>PROXY_NAME</key>
-					<string>Remove .pbdevelopment files</string>
-					<key>PROXY_TOOLTIP</key>
-					<string>Remove ".pbdevelopment" files created by ProjectBuilder or Xcode.</string>
-					<key>STATE</key>
-					<true/>
-				</dict>
-				<dict>
-					<key>PATTERNS_ARRAY</key>
-					<array>
-						<dict>
-							<key>REGULAR_EXPRESSION</key>
-							<false/>
-							<key>STRING</key>
-							<string>CVS</string>
-							<key>TYPE</key>
-							<integer>1</integer>
-						</dict>
-						<dict>
-							<key>REGULAR_EXPRESSION</key>
-							<false/>
-							<key>STRING</key>
-							<string>.cvsignore</string>
-							<key>TYPE</key>
-							<integer>0</integer>
-						</dict>
-						<dict>
-							<key>REGULAR_EXPRESSION</key>
-							<false/>
-							<key>STRING</key>
-							<string>.cvspass</string>
-							<key>TYPE</key>
-							<integer>0</integer>
-						</dict>
-						<dict>
-							<key>REGULAR_EXPRESSION</key>
-							<false/>
-							<key>STRING</key>
-							<string>.svn</string>
-							<key>TYPE</key>
-							<integer>1</integer>
-						</dict>
-						<dict>
-							<key>REGULAR_EXPRESSION</key>
-							<false/>
-							<key>STRING</key>
-							<string>.git</string>
-							<key>TYPE</key>
-							<integer>1</integer>
-						</dict>
-						<dict>
-							<key>REGULAR_EXPRESSION</key>
-							<false/>
-							<key>STRING</key>
-							<string>.gitignore</string>
-							<key>TYPE</key>
-							<integer>0</integer>
-						</dict>
-					</array>
-					<key>PROTECTED</key>
-					<true/>
-					<key>PROXY_NAME</key>
-					<string>Remove SCM metadata</string>
-					<key>PROXY_TOOLTIP</key>
-					<string>Remove helper files and folders used by the CVS, SVN or Git Source Code Management systems.</string>
-					<key>STATE</key>
-					<true/>
-				</dict>
-				<dict>
-					<key>PATTERNS_ARRAY</key>
-					<array>
-						<dict>
-							<key>REGULAR_EXPRESSION</key>
-							<false/>
-							<key>STRING</key>
-							<string>classes.nib</string>
-							<key>TYPE</key>
-							<integer>0</integer>
-						</dict>
-						<dict>
-							<key>REGULAR_EXPRESSION</key>
-							<false/>
-							<key>STRING</key>
-							<string>designable.db</string>
-							<key>TYPE</key>
-							<integer>0</integer>
-						</dict>
-						<dict>
-							<key>REGULAR_EXPRESSION</key>
-							<false/>
-							<key>STRING</key>
-							<string>info.nib</string>
-							<key>TYPE</key>
-							<integer>0</integer>
-						</dict>
-					</array>
-					<key>PROTECTED</key>
-					<true/>
-					<key>PROXY_NAME</key>
-					<string>Optimize nib files</string>
-					<key>PROXY_TOOLTIP</key>
-					<string>Remove "classes.nib", "info.nib" and "designable.nib" files within .nib bundles.</string>
-					<key>STATE</key>
-					<true/>
-				</dict>
-				<dict>
-					<key>PATTERNS_ARRAY</key>
-					<array>
-						<dict>
-							<key>REGULAR_EXPRESSION</key>
-							<false/>
-							<key>STRING</key>
-							<string>Resources Disabled</string>
-							<key>TYPE</key>
-							<integer>1</integer>
-						</dict>
-					</array>
-					<key>PROTECTED</key>
-					<true/>
-					<key>PROXY_NAME</key>
-					<string>Remove Resources Disabled folders</string>
-					<key>PROXY_TOOLTIP</key>
-					<string>Remove "Resources Disabled" folders.</string>
-					<key>STATE</key>
-					<true/>
-				</dict>
-				<dict>
-					<key>SEPARATOR</key>
-					<true/>
-				</dict>
-			</array>
-			<key>NAME</key>
-			<string>@CMAKE_PROJECT_NAME@</string>
-		</dict>
-	</dict>
-	<key>TYPE</key>
-	<integer>1</integer>
-	<key>VERSION</key>
-	<integer>2</integer>
-</dict>
-</plist>