Эх сурвалжийг харах

Merge pull request #19 from PatTheMav/build-script-fixes

Fix build scripts
Patrick Heyer 3 жил өмнө
parent
commit
077615678b
82 өөрчлөгдсөн 2832 нэмэгдсэн , 2841 устгасан
  1. 107 0
      .clang-format
  2. 14 0
      .cmake-format.json
  3. 66 0
      .github/actions/build-plugin/action.yml
  4. 89 0
      .github/actions/package-plugin/action.yml
  5. 6 0
      .github/scripts/.Brewfile
  6. 3 0
      .github/scripts/.Wingetfile
  7. 182 0
      .github/scripts/.build.zsh
  8. 196 0
      .github/scripts/.package.zsh
  9. 84 0
      .github/scripts/Build-Windows.ps1
  10. 92 0
      .github/scripts/Package-Windows.ps1
  11. 13 0
      .github/scripts/build-linux.sh
  12. 1 0
      .github/scripts/build-linux.zsh
  13. 1 0
      .github/scripts/build-macos.zsh
  14. 1 1
      .github/scripts/check-changes.sh
  15. 51 0
      .github/scripts/check-cmake.sh
  16. 1 1
      .github/scripts/check-format.sh
  17. 13 0
      .github/scripts/package-linux.sh
  18. 1 0
      .github/scripts/package-linux.zsh
  19. 1 0
      .github/scripts/package-macos.zsh
  20. 25 0
      .github/scripts/utils.pwsh/Check-Git.ps1
  21. 29 0
      .github/scripts/utils.pwsh/Ensure-Location.ps1
  22. 70 0
      .github/scripts/utils.pwsh/Expand-ArchiveExt.ps1
  23. 60 0
      .github/scripts/utils.pwsh/Install-BuildDependencies.ps1
  24. 40 0
      .github/scripts/utils.pwsh/Invoke-External.ps1
  25. 117 0
      .github/scripts/utils.pwsh/Invoke-GitCheckout.ps1
  26. 123 0
      .github/scripts/utils.pwsh/Logger.ps1
  27. 110 0
      .github/scripts/utils.pwsh/Setup-Host.ps1
  28. 77 0
      .github/scripts/utils.pwsh/Setup-Obs.ps1
  29. 1 0
      .github/scripts/utils.zsh/check_linux
  30. 18 0
      .github/scripts/utils.zsh/check_macos
  31. 51 0
      .github/scripts/utils.zsh/check_packages
  32. 9 0
      .github/scripts/utils.zsh/check_xcnotary
  33. 3 0
      .github/scripts/utils.zsh/log_debug
  34. 3 0
      .github/scripts/utils.zsh/log_error
  35. 7 0
      .github/scripts/utils.zsh/log_info
  36. 7 0
      .github/scripts/utils.zsh/log_output
  37. 7 0
      .github/scripts/utils.zsh/log_status
  38. 5 0
      .github/scripts/utils.zsh/log_warning
  39. 1 0
      .github/scripts/utils.zsh/mkcd
  40. 7 0
      .github/scripts/utils.zsh/read_codesign
  41. 7 0
      .github/scripts/utils.zsh/read_codesign_installer
  42. 31 0
      .github/scripts/utils.zsh/read_codesign_pass
  43. 7 0
      .github/scripts/utils.zsh/read_codesign_user
  44. 17 0
      .github/scripts/utils.zsh/set_loglevel
  45. 44 0
      .github/scripts/utils.zsh/setup_linux
  46. 104 0
      .github/scripts/utils.zsh/setup_macos
  47. 105 0
      .github/scripts/utils.zsh/setup_obs
  48. 256 276
      .github/workflows/main.yml
  49. 2 2
      .gitignore
  50. 0 103
      CI/build-linux.sh
  51. 0 129
      CI/build-macos.sh
  52. 0 132
      CI/build-windows.ps1
  53. 0 2
      CI/include/Brewfile
  54. 0 1
      CI/include/Xcnotary
  55. 0 2
      CI/include/build_environment.ps1.in
  56. 0 3
      CI/include/build_environment.sh.in
  57. 0 229
      CI/include/build_support.sh
  58. 0 33
      CI/include/build_support_linux.sh
  59. 0 149
      CI/include/build_support_macos.sh
  60. 0 139
      CI/include/build_support_windows.ps1
  61. 0 127
      CI/linux/01_install_dependencies.sh
  62. 0 73
      CI/linux/02_build_obs_libs.sh
  63. 0 66
      CI/linux/03_build_plugin.sh
  64. 0 68
      CI/linux/04_package_plugin.sh
  65. 0 120
      CI/macos/01_install_dependencies.sh
  66. 0 79
      CI/macos/02_build_obs_libs.sh
  67. 0 85
      CI/macos/03_build_plugin.sh
  68. 0 150
      CI/macos/04_package_plugin.sh
  69. 0 158
      CI/windows/01_install_dependencies.ps1
  70. 0 102
      CI/windows/02_build_obs_libs.ps1
  71. 0 92
      CI/windows/03_build_plugin.ps1
  72. 0 141
      CI/windows/04_package_plugin.ps1
  73. 52 86
      CMakeLists.txt
  74. 11 15
      README.md
  75. 56 0
      buildspec.json
  76. 444 0
      cmake/ObsPluginHelpers.cmake
  77. 0 0
      cmake/bundle/macos/Plugin-Info.plist.in
  78. 0 0
      cmake/bundle/macos/entitlements.plist
  79. 0 0
      cmake/bundle/macos/installer-macOS.pkgproj.in
  80. 0 0
      cmake/bundle/windows/installer-Windows.iss.in
  81. 0 274
      external/ObsPluginHelpers.cmake
  82. 4 3
      src/plugin-main.c

+ 107 - 0
.clang-format

@@ -0,0 +1,107 @@
+# please use clang-format version 8 or later
+
+Standard: Cpp11
+AccessModifierOffset: -8
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Left
+AlignOperands: true
+AlignTrailingComments: true
+#AllowAllArgumentsOnNextLine: false  # requires clang-format 9
+#AllowAllConstructorInitializersOnNextLine: false  # requires clang-format 9
+AllowAllParametersOfDeclarationOnNextLine: false
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: Inline
+AllowShortIfStatementsOnASingleLine: false
+#AllowShortLambdasOnASingleLine: Inline  # requires clang-format 9
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+  AfterClass: false
+  AfterControlStatement: false
+  AfterEnum: false
+  AfterFunction: true
+  AfterNamespace: false
+  AfterObjCDeclaration: false
+  AfterStruct: false
+  AfterUnion: false
+  AfterExternBlock: false
+  BeforeCatch: false
+  BeforeElse: false
+  IndentBraces: false
+  SplitEmptyFunction: true
+  SplitEmptyRecord: true
+  SplitEmptyNamespace: true
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: BeforeColon
+BreakStringLiterals: false  # apparently unpredictable
+ColumnLimit: 80
+CompactNamespaces: false
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 8
+ContinuationIndentWidth: 8
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat: false
+FixNamespaceComments: false
+ForEachMacros: 
+  - 'json_object_foreach'
+  - 'json_object_foreach_safe'
+  - 'json_array_foreach'
+IncludeBlocks: Preserve
+IndentCaseLabels: false
+IndentPPDirectives: None
+IndentWidth: 8
+IndentWrappedFunctionNames: false
+KeepEmptyLinesAtTheStartOfBlocks: true
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+#ObjCBinPackProtocolList: Auto  # requires clang-format 7
+ObjCBlockIndentWidth: 8
+ObjCSpaceAfterProperty: true
+ObjCSpaceBeforeProtocolList: true
+
+PenaltyBreakAssignment: 10
+PenaltyBreakBeforeFirstCallParameter: 30
+PenaltyBreakComment: 10
+PenaltyBreakFirstLessLess: 0
+PenaltyBreakString: 10
+PenaltyExcessCharacter: 100
+PenaltyReturnTypeOnItsOwnLine: 60
+
+PointerAlignment: Right
+ReflowComments: false
+SortIncludes: false
+SortUsingDeclarations: false
+SpaceAfterCStyleCast: false
+#SpaceAfterLogicalNot: false  # requires clang-format 9
+SpaceAfterTemplateKeyword: false
+SpaceBeforeAssignmentOperators: true
+#SpaceBeforeCtorInitializerColon: true  # requires clang-format 7
+#SpaceBeforeInheritanceColon: true  # requires clang-format 7
+SpaceBeforeParens: ControlStatements
+#SpaceBeforeRangeBasedForLoopColon: true  # requires clang-format 7
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: false
+SpacesInCStyleCastParentheses: false
+SpacesInContainerLiterals: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+#StatementMacros:  # requires clang-format 8
+#  - 'Q_OBJECT'
+TabWidth: 8
+#TypenameMacros:  # requires clang-format 9
+#  - 'DARRAY'
+UseTab: ForContinuationAndIndentation
+---
+Language: ObjC

+ 14 - 0
.cmake-format.json

@@ -0,0 +1,14 @@
+{
+    "additional_commands": {
+      "find_qt": {
+        "flags": [],
+        "kwargs": {
+          "VERSION": "+",
+          "COMPONENTS": "+",
+          "COMPONENTS_WIN": "+",
+          "COMPONENTS_MACOS": "+",
+          "COMPONENTS_LINUX": "+"
+        }
+      }
+    }
+}

+ 66 - 0
.github/actions/build-plugin/action.yml

@@ -0,0 +1,66 @@
+name: 'Setup and build plugin'
+description: 'Builds the plugin for specified architecture and build config.'
+inputs:
+  target:
+    description: 'Build target for dependencies'
+    required: true
+  config:
+    description: 'Build configuration'
+    required: false
+    default: 'Release'
+  codesign:
+    description: 'Enable codesigning (macOS only)'
+    required: false
+    default: 'false'
+  codesignIdent:
+    description: 'Developer ID for application codesigning (macOS only)'
+    required: false
+    default: '-'
+  visualStudio:
+    description: 'Visual Studio version (Windows only)'
+    required: false
+    default: 'Visual Studio 16 2019'
+  workingDirectory:
+    description: 'Working directory for packaging'
+    required: false
+    default: ${{ github.workspace }}
+runs:
+  using: 'composite'
+  steps:
+    - name: Run macOS Build
+      if: ${{ runner.os == 'macOS' }}
+      shell: zsh {0}
+      env:
+        CODESIGN_IDENT: ${{ inputs.codesignIdent }}
+      run: |
+        build_args=(
+          -c ${{ inputs.config }}
+          -t macos-${{ inputs.target }}
+        )
+
+        if [[ '${{ inputs.codesign }}' == 'true' ]] build_args+=(-s)
+
+        ${{ inputs.workingDirectory }}/.github/scripts/build-macos.zsh ${build_args}
+
+    - name: Run Linux Build
+      if: ${{ runner.os == 'Linux' }}
+      shell: bash
+      run: |
+        build_args=(
+          -c ${{ inputs.config }}
+          -t linux-${{ inputs.target }}
+        )
+
+        ${{ inputs.workingDirectory }}/.github/scripts/build-linux.sh ${build_args[@]}
+
+    - name: Run Windows Build
+      if: ${{ runner.os == 'Windows' }}
+      shell: pwsh
+      run: |
+        $BuildArgs = @{
+          Target = '${{ inputs.target }}'
+          Configuration = '${{ inputs.config }}'
+          CMakeGenerator = '${{ inputs.visualStudio }}'
+        }
+
+        ${{ inputs.workingDirectory }}/.github/scripts/Build-Windows.ps1 @BuildArgs

+ 89 - 0
.github/actions/package-plugin/action.yml

@@ -0,0 +1,89 @@
+name: 'Package plugin'
+description: 'Packages the plugin for specified architecture and build config.'
+inputs:
+  target:
+    description: 'Build target for dependencies'
+    required: true
+  config:
+    description: 'Build configuration'
+    required: false
+    default: 'Release'
+  codesign:
+    description: 'Enable codesigning (macOS only)'
+    required: false
+    default: 'false'
+  notarize:
+    description: 'Enable notarization (macOS only)'
+    required: false
+    default: 'false'
+  codesignIdent:
+    description: 'Developer ID for application codesigning (macOS only)'
+    required: false
+    default: '-'
+  installerIdent:
+    description: 'Developer ID for installer package codesigning (macOS only)'
+    required: false
+    default: ''
+  codesignUser:
+    description: 'Apple ID username for notarization (macOS only)'
+    required: false
+    default: ''
+  codesignPass:
+    description: 'Apple ID password for notarization (macOS only)'
+    required: false
+    default: ''
+  createInstaller:
+    description: 'Create InnoSetup installer (Windows only)'
+    required: false
+    default: 'false'
+  workingDirectory:
+    description: 'Working directory for packaging'
+    required: false
+    default: ${{ github.workspace }}
+runs:
+  using: 'composite'
+  steps:
+    - name: Run macOS packaging
+      if: ${{ runner.os == 'macOS' }}
+      shell: zsh {0}
+      env:
+        CODESIGN_IDENT: ${{ inputs.codesignIdent }}
+        CODESIGN_IDENT_INSTALLER: ${{ inputs.installerIdent }}
+        CODESIGN_IDENT_USER: ${{ inputs.codesignUser }}
+        CODESIGN_IDENT_PASS: ${{ inputs.codesignPass }}
+      run: |
+        package_args=(
+          -c ${{ inputs.config }}
+          -t macos-${{ inputs.target }}
+        )
+
+        if [[ '${{ inputs.codesign }}' == 'true' ]] package_args+=(-s)
+        if [[ '${{ inputs.notarize }}' == 'true' ]] package_args+=(-n)
+
+        ${{ inputs.workingDirectory }}/.github/scripts/package-macos.zsh ${package_args}
+
+    - name: Run Linux packaging
+      if: ${{ runner.os == 'Linux' }}
+      shell: bash
+      run: |
+        package_args=(
+          -c ${{ inputs.config }}
+          -t linux-${{ inputs.target }}
+        )
+
+        ${{ inputs.workingDirectory }}/.github/scripts/package-linux.sh ${package_args[@]}
+
+    - name: Run Windows packaging
+      if: ${{ runner.os == 'Windows' }}
+      shell: pwsh
+      run: |
+        $PackageArgs = @{
+          Target = '${{ inputs.target }}'
+          Configuration = '${{ inputs.config }}'
+        }
+
+        if ( '${{ inputs.createInstaller }}' -eq 'true' ) {
+          $PackageArgs += @{BuildInstaller = $true}
+        }
+
+        ${{ inputs.workingDirectory }}/.github/scripts/Package-Windows.ps1 @PackageArgs

+ 6 - 0
.github/scripts/.Brewfile

@@ -0,0 +1,6 @@
+brew "ccache"
+brew "coreutils"
+brew "cmake"
+brew "git"
+brew "jq"
+brew "ninja"

+ 3 - 0
.github/scripts/.Wingetfile

@@ -0,0 +1,3 @@
+package '7zip.7zip', path: '7-zip', bin: '7z'
+package 'cmake', path: 'Cmake\bin', bin: 'cmake'
+package 'innosetup', path: 'Inno Setup 6', bin: 'iscc'

+ 182 - 0
.github/scripts/.build.zsh

@@ -0,0 +1,182 @@
+#!/usr/bin/env zsh
+
+builtin emulate -L zsh
+setopt EXTENDED_GLOB
+setopt PUSHD_SILENT
+setopt ERR_EXIT
+setopt ERR_RETURN
+setopt NO_UNSET
+setopt PIPE_FAIL
+setopt NO_AUTO_PUSHD
+setopt NO_PUSHD_IGNORE_DUPS
+setopt FUNCTION_ARGZERO
+
+## Enable for script debugging
+#setopt WARN_CREATE_GLOBAL
+#setopt WARN_NESTED_VAR
+#setopt XTRACE
+
+autoload -Uz is-at-least && if ! is-at-least 5.2; then
+  print -u2 -PR "%F{1}${funcstack[1]##*/}:%f Running on Zsh version %B${ZSH_VERSION}%b, but Zsh %B5.2%b is the minimum supported version. Upgrade Zsh to fix this issue."
+  exit 1
+fi
+
+_trap_error() {
+  print -u2 -PR '%F{1}    ✖︎ script execution error%f'
+  print -PR -e "
+    Callstack:
+    ${(j:\n     :)funcfiletrace}
+  "
+  exit 2
+}
+
+build() {
+  if (( ! ${+SCRIPT_HOME} )) typeset -g SCRIPT_HOME=${ZSH_ARGZERO:A:h}
+  local host_os=${${(s:-:)ZSH_ARGZERO:t:r}[2]}
+  local target="${host_os}-${CPUTYPE}"
+  local project_root=${SCRIPT_HOME:A:h:h}
+  local buildspec_file="${project_root}/buildspec.json"
+  trap '_trap_error' ZERR
+
+  fpath=("${SCRIPT_HOME}/utils.zsh" ${fpath})
+  autoload -Uz log_info log_error log_output set_loglevel check_${host_os} setup_${host_os} setup_obs
+
+  local -i _verbosity=1
+  local -r _version='0.0.1'
+  local -r -a _valid_targets=(
+    macos-x86_64
+    macos-arm64
+    macos-universal
+    linux-x86_64
+  )
+  local -r -a _valid_configs=(Debug RelWithDebInfo Release MinSizeRel)
+  local -r _usage="
+Usage: %B${functrace[1]%:*}%b <option> [<options>]
+
+%BOptions%b:
+
+%F{yellow} Build configuration options%f
+ -----------------------------------------------------------------------------
+  %B-t | --target%b                     Specify target - default: %B%F{green}${host_os}-${CPUTYPE}%f%b
+  %B-c | --config%b                     Build configuration - default: %B%F{green}RelWithDebInfo%f%b
+  %B-s | --codesign%b                   Enable codesigning (macOS only)
+
+%F{yellow} Output options%f
+ -----------------------------------------------------------------------------
+  %B-q | --quiet%b                      Quiet (error output only)
+  %B-v | --verbose%b                    Verbose (more detailed output)
+
+%F{yellow} General options%f
+ -----------------------------------------------------------------------------
+  %B-h | --help%b                       Print this usage help
+  %B-V | --version%b                    Print script version information"
+
+  local -a args
+  while (( # )) {
+    case ${1} {
+      -t|--target|-c|--config)
+        if (( # == 1 )) || [[ ${2:0:1} == '-' ]] {
+          log_error "Missing value for option %B${1}%b"
+          log_output ${_usage}
+          exit 2
+        }
+        ;;
+    }
+    case ${1} {
+      --)
+        shift
+        args+=($@)
+        break
+        ;;
+      -t|--target)
+        if (( ! ${_valid_targets[(Ie)${2}]} )) {
+          log_error "Invalid value %B${2}%b for option %B${1}%b"
+          log_output ${_usage}
+          exit 2
+        }
+        target=${2}
+        shift 2
+        ;;
+      -c|--config)
+        if (( ! ${_valid_configs[(Ie)${2}]} )) {
+          log_error "Invalid value %B${2}%b for option %B${1}%b"
+          log_output ${_usage}
+          exit 2
+        }
+        BUILD_CONFIG=${2}
+        shift 2
+        ;;
+      -s|--codesign) CODESIGN=1; shift ;;
+      -q|--quiet) (( _verbosity -= 1 )) || true; shift ;;
+      -v|--verbose) (( _verbosity += 1 )); shift ;;
+      -h|--help) log_output ${_usage}; exit 0 ;;
+      -V|--version) print -Pr "${_version}"; exit 0 ;;
+      *) log_error "Unknown option: %B${1}%b"; log_output ${_usage}; exit 2 ;;
+    }
+  }
+
+  set -- ${(@)args}
+  set_loglevel ${_verbosity}
+
+  check_${host_os}
+  setup_${host_os}
+
+  read -r product_name product_version <<< \
+    "$(jq -r '. | {name, version} | join(" ")' ${project_root}/buildspec.json)"
+
+  case ${host_os} {
+    macos-*)
+      sed -i '' \
+        "s/project(\(.*\) VERSION \(.*\))/project(${product_name} VERSION ${product_version})/" \
+        "${project_root}"/CMakeLists.txt
+      ;;
+    linux-*)
+      sed -i'' \
+        "s/project(\(.*\) VERSION \(.*\))/project(${product_name} VERSION ${product_version})/"\
+        "${project_root}"/CMakeLists.txt
+      ;;
+  }
+
+  setup_obs
+
+  pushd ${project_root}
+  log_info "Configuring ${product_name}..."
+
+  local -a cmake_args=(
+    -DCMAKE_BUILD_TYPE=${BUILD_CONFIG:-RelWithDebInfo}
+    -DCMAKE_PREFIX_PATH="${project_root:h}/obs-build-dependencies/obs-plugin-deps"
+  )
+
+  if (( _loglevel == 0 )) cmake_args+=(-Wno_deprecated -Wno-dev --log-level=ERROR)
+
+  case ${target} {
+    macos-*)
+      autoload -Uz read_codesign
+      if (( ${+CODESIGN} )) {
+        read_codesign
+      }
+
+      cmake_args+=(
+        -DCMAKE_OSX_ARCHITECTURES=${${target##*-}//universal/x86_64;arm64}
+        -DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET:-10.15}
+        -DOBS_BUNDLE_CODESIGN_IDENTITY="${CODESIGN_IDENT:--}"
+        -DCMAKE_FRAMEWORK_PATH="${project_root:h}/obs-build-dependencies/obs-plugin-deps/Frameworks"
+      )
+      ;;
+    linux-*) ;;
+  }
+
+  cmake -S . -B build_${target} -G Ninja ${cmake_args}
+
+  local -a cmake_args=()
+  if (( _loglevel > 1 )) cmake_args+=(--verbose)
+
+  log_info "Building ${product_name}"
+  cmake --build build_${target} --config ${BUILD_CONFIG:-RelWithDebInfo} ${cmake_args}
+
+  log_info "Install ${product_name}"
+  cmake --install build_${target} --config ${BUILD_CONFIG:-RelWithDebInfo} --prefix "${project_root}"/release ${cmake_args}
+  popd
+}
+
+build "${@}"

+ 196 - 0
.github/scripts/.package.zsh

@@ -0,0 +1,196 @@
+#!/usr/bin/env zsh
+
+builtin emulate -L zsh
+setopt EXTENDED_GLOB
+setopt PUSHD_SILENT
+setopt ERR_EXIT
+setopt ERR_RETURN
+setopt NO_UNSET
+setopt PIPE_FAIL
+setopt NO_AUTO_PUSHD
+setopt NO_PUSHD_IGNORE_DUPS
+setopt FUNCTION_ARGZERO
+
+## Enable for script debugging
+#setopt WARN_CREATE_GLOBAL
+#setopt WARN_NESTED_VAR
+#setopt XTRACE
+
+autoload -Uz is-at-least && if ! is-at-least 5.2; then
+  print -u2 -PR "%F{1}${funcstack[1]##*/}:%f Running on Zsh version %B${ZSH_VERSION}%b, but Zsh %B5.2%b is the minimum supported version. Upgrade Zsh to fix this issue."
+  exit 1
+fi
+
+_trap_error() {
+  print -u2 -PR '%F{1}    ✖︎ script execution error%f'
+  print -PR -e "
+    Callstack:
+    ${(j:\n     :)funcfiletrace}
+  "
+  exit 2
+}
+
+package() {
+  if (( ! ${+SCRIPT_HOME} )) typeset -g SCRIPT_HOME=${ZSH_ARGZERO:A:h}
+  local host_os=${${(s:-:)ZSH_ARGZERO:t:r}[2]}
+  local target="${host_os}-${CPUTYPE}"
+  local project_root=${SCRIPT_HOME:A:h:h}
+  local buildspec_file="${project_root}/buildspec.json"
+  trap '_trap_error' ZERR
+
+  fpath=("${SCRIPT_HOME}/utils.zsh" ${fpath})
+  autoload -Uz set_loglevel log_info log_error log_output check_${host_os}
+
+  local -i _verbosity=1
+  local -r _version='0.0.1'
+  local -r -a _valid_targets=(
+    macos-x86_64
+    macos-arm64
+    macos-universal
+    linux-x86_64
+  )
+  local -r -a _valid_configs=(Debug RelWithDebInfo Release MinSizeRel)
+  local -r _usage="
+Usage: %B${functrace[1]%:*}%b <option> [<options>]
+
+%BOptions%b:
+
+%F{yellow} Package configuration options%f
+ -----------------------------------------------------------------------------
+  %B-t | --target%b                     Specify target - default: %B%F{green}${host_os}-${CPUTYPE}%f%b
+  %B-c | --config%b                     Build configuration - default: %B%F{green}RelWithDebInfo%f%b
+  %B-s | --codesign%b                   Enable codesigning (macOS only)
+  %B-n | --notarize%b                   Enable notarization (macOS only)
+
+%F{yellow} Output options%f
+ -----------------------------------------------------------------------------
+  %B-q | --quiet%b                      Quiet (error output only)
+  %B-v | --verbose%b                    Verbose (more detailed output)
+
+%F{yellow} General options%f
+ -----------------------------------------------------------------------------
+  %B-h | --help%b                       Print this usage help
+  %B-V | --version%b                    Print script version information"
+
+  local -a args
+  while (( # )) {
+    case ${1} {
+      -t|--target|-c|--config)
+        if (( # == 1 )) || [[ ${2:0:1} == '-' ]] {
+          log_error "Missing value for option %B${1}%b"
+          log_output ${_usage}
+          exit 2
+        }
+        ;;
+    }
+    case ${1} {
+      --)
+        shift
+        args+=($@)
+        break
+        ;;
+      -t|--target)
+        if (( ! ${_valid_targets[(Ie)${2}]} )) {
+          log_error "Invalid value %B${2}%b for option %B${1}%b"
+          log_output ${_usage}
+          exit 2
+        }
+        target=${2}
+        shift 2
+        ;;
+      -c|--config)
+        if (( ! ${_valid_configs[(Ie)${2}]} )) {
+          log_error "Invalid value %B${2}%b for option %B${1}%b"
+          log_output ${_usage}
+          exit 2
+        }
+        BUILD_CONFIG=${2}
+        shift 2
+        ;;
+      -s|--codesign) CODESIGN=1; shift ;;
+      -n|--notarize) NOTARIZE=1; shift ;;
+      -q|--quiet) (( _verbosity -= 1 )) || true; shift ;;
+      -v|--verbose) (( _verbosity += 1 )); shift ;;
+      -h|--help) log_output ${_usage}; exit 0 ;;
+      -V|--version) print -Pr "${_version}"; exit 0 ;;
+      *) log_error "Unknown option: %B${1}%b"; log_output ${_usage}; exit 2 ;;
+    }
+  }
+
+  set -- ${(@)args}
+  set_loglevel ${_verbosity}
+
+  check_${host_os}
+
+  read -r product_name product_version <<< \
+    "$(jq -r '. | {name, version} | join(" ")' ${project_root}/buildspec.json)"
+
+  if [[ ${host_os} == 'macos' ]] {
+    autoload -Uz check_packages check_xcnotary read_codesign read_codesign_installer read_codesign_pass
+
+    local output_name="${product_name}-${product_version}-${host_os}-${target##*-}.pkg"
+
+    if [[ ! -d ${project_root}/release/${product_name}.plugin ]] {
+      log_error 'No release artifact found. Run the build script or the CMake install procedure first.'
+      return 2
+    }
+
+    if [[ ! -f ${project_root}/build_${target}/installer-macos.generated.pkgproj ]] {
+      log_error 'Packages project file not found. Run the build script or the CMake build and install procedures first.'
+      return 2
+    }
+
+    check_packages
+
+    log_info "Packaging ${product_name}..."
+    pushd ${project_root}
+    packagesbuild \
+      --build-folder ${project_root}/release \
+      ${project_root}/build_${target}/installer-macos.generated.pkgproj
+
+    if (( ${+CODESIGN} )) {
+      read_codesign_installer
+      productsign \
+        --sign "${CODESIGN_IDENT_INSTALLER}" \
+        "${project_root}/release/${product_name}.pkg" \
+        "${project_root}/release/${output_name}"
+
+      rm "${project_root}/release/${product_name}.pkg"
+    } else {
+      mv "${project_root}/release/${product_name}.pkg" \
+        "${project_root}/release/${output_name}"
+    }
+
+    if (( ${+CODESIGN} + ${+NOTARIZE} > 1 )) {
+      check_xcnotary
+
+      local _error=0
+      if [[ -f "${project_root}/release/${output_name}" ]] {
+        xcnotary precheck "${project_root}/release/${output_name}" || _error=1
+      } else {
+        log_error "No package for notarization found."
+        return 2
+      }
+
+      if (( ! _error )) {
+        read_codesign_installer
+        read_codesign_pass
+
+        xcnotary notarize "${project_root}/release/${output_name}" \
+          --developer-account "${CODESIGN_IDENT_USER}" \
+          --developer-password-keychain-item "OBS-Codesign-Password" \
+          --provider "${CODESIGN_IDENT_SHORT}"
+      }
+    }
+    popd
+  } elif [[ ${host_os} == 'linux' ]] {
+    local -a cmake_args=()
+    if (( _loglevel > 1 )) cmake_args+=(--verbose)
+
+    pushd ${project_root}
+    cmake --build build_${target} --config ${BUILD_CONFIG:-RelWithDebInfo} -t package ${cmake_args}
+    popd
+  }
+}
+
+package "${@}"

+ 84 - 0
.github/scripts/Build-Windows.ps1

@@ -0,0 +1,84 @@
+[CmdletBinding()]
+param(
+    [ValidateSet('Debug', 'RelWithDebInfo', 'Release', 'MinSizeRel')]
+    [string] $Configuration = 'RelWithDebInfo',
+    [ValidateSet('x86', 'x64')]
+    [string] $Target,
+    [ValidateSet('Visual Studio 17 2022', 'Visual Studio 16 2019')]
+    [string] $CMakeGenerator = 'Visual Studio 16 2019'
+)
+
+$ErrorActionPreference = 'Stop'
+
+if ( $DebugPreference -eq 'Continue' ) {
+    $VerbosePreference = 'Continue'
+    $InformationPreference = 'Continue'
+}
+
+if ( $PSVersionTable.PSVersion -lt '7.0.0' ) {
+    Write-Warning 'The obs-deps PowerShell build script requires PowerShell Core 7. Install or upgrade your PowerShell version: https://aka.ms/pscore6'
+    exit 2
+}
+
+function Build {
+    trap {
+        Pop-Location -Stack BuildTemp
+        Write-Error $_
+        exit 2
+    }
+
+    $ScriptHome = $PSScriptRoot
+    $ProjectRoot = Resolve-Path -Path "$PSScriptRoot/../.."
+    $BuildSpecFile = "${ProjectRoot}/buildspec.json"
+
+    $UtilityFunctions = Get-ChildItem -Path $PSScriptRoot/utils.pwsh/*.ps1 -Recurse
+
+    foreach($Utility in $UtilityFunctions) {
+        Write-Debug "Loading $($Utility.FullName)"
+        . $Utility.FullName
+    }
+
+    $BuildSpec = Get-Content -Path ${BuildSpecFile} -Raw | ConvertFrom-Json
+    $ProductName = $BuildSpec.name
+    $ProductVersion = $BuildSpec.version
+
+    Setup-Host
+
+    (Get-Content -Path ${ProjectRoot}/CMakeLists.txt -Raw) `
+        -replace "project\((.*) VERSION (.*)\)", "project(${ProductName} VERSION ${ProductVersion})" `
+        | Out-File -Path ${ProjectRoot}/CMakeLists.txt
+
+    Setup-Obs
+
+    Push-Location -Stack BuildTemp
+
+    Ensure-Location $ProjectRoot
+
+    $CmakeArgs = @(
+        '-G', $CmakeGenerator
+        '-DCMAKE_SYSTEM_VERSION=10.0.18363.657'
+        "-DCMAKE_GENERATOR_PLATFORM=$(if (${script:Target} -eq "x86") { "Win32" } else { "x64" })"
+        "-DCMAKE_BUILD_TYPE=${Configuration}"
+        "-DCMAKE_PREFIX_PATH=$(Resolve-Path -Path "${ProjectRoot}/../obs-build-dependencies/plugin-deps-${Target}")"
+    )
+
+    Log-Information "Configuring ${ProductName}..."
+    Invoke-External cmake -S . -B build_${script:Target} @CmakeArgs
+
+    $CmakeArgs = @(
+        '--config', "${Configuration}"
+    )
+
+    if ( $VerbosePreference -eq 'Continue' ) {
+        $CmakeArgs+=('--verbose')
+    }
+
+    Log-Information "Building ${ProductName}..."
+    Invoke-External cmake --build "build_${script:Target}" @CmakeArgs
+    Log-Information "Install ${ProductName}..."
+    Invoke-External cmake --install "build_${script:Target}" --prefix "${ProjectRoot}/release" @CmakeArgs
+
+    Pop-Location -Stack BuildTemp
+}
+
+Build

+ 92 - 0
.github/scripts/Package-Windows.ps1

@@ -0,0 +1,92 @@
+[CmdletBinding()]
+param(
+    [ValidateSet('Debug', 'RelWithDebInfo', 'Release', 'MinSizeRel')]
+    [string] $Configuration = 'RelWithDebInfo',
+    [ValidateSet('x86', 'x64', 'x86+x64')]
+    [string] $Target,
+    [switch] $BuildInstaller = $false
+)
+
+$ErrorActionPreference = 'Stop'
+
+if ( $DebugPreference -eq 'Continue' ) {
+    $VerbosePreference = 'Continue'
+    $InformationPreference = 'Continue'
+}
+
+if ( $PSVersionTable.PSVersion -lt '7.0.0' ) {
+    Write-Warning 'The obs-deps PowerShell build script requires PowerShell Core 7. Install or upgrade your PowerShell version: https://aka.ms/pscore6'
+    exit 2
+}
+
+function Package {
+    trap {
+        Write-Error $_
+        exit 2
+    }
+
+    $ScriptHome = $PSScriptRoot
+    $ProjectRoot = Resolve-Path -Path "$PSScriptRoot/../.."
+    $BuildSpecFile = "${ProjectRoot}/buildspec.json"
+
+    $UtilityFunctions = Get-ChildItem -Path $PSScriptRoot/utils.pwsh/*.ps1 -Recurse
+
+    foreach( $Utility in $UtilityFunctions ) {
+        Write-Debug "Loading $($Utility.FullName)"
+        . $Utility.FullName
+    }
+
+    $BuildSpec = Get-Content -Path ${BuildSpecFile} -Raw | ConvertFrom-Json
+    $ProductName = $BuildSpec.name
+    $ProductVersion = $BuildSpec.version
+
+    $OutputName = "${ProductName}-${ProductVersion}-windows-${Target}"
+
+    Install-BuildDependencies -WingetFile "${ScriptHome}/.Wingetfile"
+
+    Log-Information "Packaging ${ProductName}..."
+
+    $RemoveArgs = @{
+        ErrorAction = 'SilentlyContinue'
+        Path = @(
+            "${ProjectRoot}/release/${ProductName}-${ProductVersion}-windows-*.zip"
+            "${ProjectRoot}/release/${ProductName}-${ProductVersion}-windows-*.exe"
+        )
+    }
+
+    Remove-Item @RemoveArgs
+
+    if ( ( $BuildInstaller ) ) {
+        if ( $Target -eq 'x86+x64' ) {
+            $IsccCandidates = Get-ChildItem -Recurse -Path '*.iss'
+
+            if ( $IsccCandidates.length -gt 0 ) {
+                $IsccFile = $IsccCandidates[0].FullName
+            } else {
+                $IsccFile = ''
+            }
+        } else {
+            $IsccFile = "${ProjectRoot}/build_${Target}/installer-Windows.generated.iss"
+        }
+
+        if ( ! ( Test-Path -Path $IsccFile ) ) {
+            throw 'InnoSetup install script not found. Run the build script or the CMake build and install procedures first.'
+        }
+
+        Log-Information 'Creating InnoSetup installer...'
+        Push-Location -Stack BuildTemp
+        Ensure-Location -Path "${ProjectRoot}/release"
+        Invoke-External iscc ${IsccFile} /O. /F"${OutputName}-Installer"
+        Pop-Location -Stack BuildTemp
+    }
+
+    $CompressArgs = @{
+        Path = (Get-ChildItem -Path "${ProjectRoot}/release" -Exclude "${OutputName}*.*")
+        CompressionLevel = 'Optimal'
+        DestinationPath = "${ProjectRoot}/release/${OutputName}.zip"
+    }
+
+    Compress-Archive -Force @CompressArgs
+}
+
+Package

+ 13 - 0
.github/scripts/build-linux.sh

@@ -0,0 +1,13 @@
+#!/bin/sh
+
+if ! type zsh > /dev/null 2>&1; then
+    echo ' => Installing script dependency Zsh.'
+
+    sudo apt-get update
+    sudo apt-get install zsh
+fi
+
+SCRIPT=$(readlink -f "${0}")
+SCRIPT_DIR=$(dirname "${SCRIPT}")
+
+zsh ${SCRIPT_DIR}/build-linux.zsh ${@}

+ 1 - 0
.github/scripts/build-linux.zsh

@@ -0,0 +1 @@
+.build.zsh

+ 1 - 0
.github/scripts/build-macos.zsh

@@ -0,0 +1 @@
+.build.zsh

+ 1 - 1
CI/utility/check-format.sh → .github/scripts/check-changes.sh

@@ -8,4 +8,4 @@ if [[ $dirty ]]; then
     echo "$dirty"
     echo "================================="
     exit 1
-fi
+fi

+ 51 - 0
.github/scripts/check-cmake.sh

@@ -0,0 +1,51 @@
+#!/usr/bin/env bash
+
+set -o errexit
+set -o pipefail
+
+if [ ${#} -eq 1 -a "${1}" = "VERBOSE" ]; then
+    VERBOSITY="-l debug"
+else
+    VERBOSITY=""
+fi
+
+if [ "${CI}" ]; then
+    MODE="--check"
+else
+    MODE="-i"
+fi
+
+# Runs the 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 cmake-format 2> /dev/null ; then
+    echo "Required cmake-format not found"
+    exit 1
+fi
+
+find . -type d \( \
+    -path ./\*build -o \
+    -path ./deps/jansson -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 -o \
+    -path ./plugins/obs-browser -o \
+    -path ./plugins/win-dshow/libdshowcapture \
+\) -prune -false -type f -o \
+    -name 'CMakeLists.txt' -or \
+    -name '*.cmake' \
+ | xargs -L10 -P ${NPROC} cmake-format ${MODE} ${VERBOSITY}

+ 1 - 1
CI/utility/formatcode.sh → .github/scripts/check-format.sh

@@ -42,7 +42,7 @@ else
 fi
 
 find . -type d \( \
-    -path ./\*build -o \
+    -path ./\*build\* -o \
     -path ./cmake -o \
     -path ./deps -o \
     -path ./plugins/decklink/\*/decklink-sdk -o \

+ 13 - 0
.github/scripts/package-linux.sh

@@ -0,0 +1,13 @@
+#!/bin/sh
+
+if ! type zsh > /dev/null 2>&1; then
+    echo ' => Installing script dependency Zsh.'
+
+    sudo apt-get update
+    sudo apt-get install zsh
+fi
+
+SCRIPT=$(readlink -f "${0}")
+SCRIPT_DIR=$(dirname "${SCRIPT}")
+
+zsh ${SCRIPT_DIR}/package-linux.zsh ${@}

+ 1 - 0
.github/scripts/package-linux.zsh

@@ -0,0 +1 @@
+.package.zsh

+ 1 - 0
.github/scripts/package-macos.zsh

@@ -0,0 +1 @@
+.package.zsh

+ 25 - 0
.github/scripts/utils.pwsh/Check-Git.ps1

@@ -0,0 +1,25 @@
+function Check-Git {
+    <#
+        .SYNOPSIS
+            Ensures available git executable on host system.
+        .DESCRIPTION
+            Checks whether a git command is available on the host system. If none is found,
+            Git is installed via winget.
+        .EXAMPLE
+            Check-Git
+    #>
+
+    if ( ! ( Test-Path function:Log-Info ) ) {
+        . $PSScriptRoot/Logger.ps1
+    }
+
+    Log-Information 'Checking for Git executable...'
+
+    if ( ! ( Get-Command git ) ) {
+        Log-Warning 'No Git executable found. Will try to install via winget.'
+        winget install git
+    } else {
+        Log-Debug "Git found at $(Get-Command git)."
+        Log-Status "Git found."
+    }
+}

+ 29 - 0
.github/scripts/utils.pwsh/Ensure-Location.ps1

@@ -0,0 +1,29 @@
+function Ensure-Location {
+    <#
+        .SYNOPSIS
+            Ensures current location to be set to specified directory.
+        .DESCRIPTION
+            If specified directory exists, switch to it. Otherwise create it,
+            then switch.
+        .EXAMPLE
+            Ensure-Location "My-Directory"
+            Ensure-Location -Path "Path-To-My-Directory"
+    #>
+
+    param(
+        [Parameter(Mandatory)]
+        [string] $Path
+    )
+
+    if ( ! ( Test-Path $Path ) ) {
+        $_Params = @{
+            ItemType = "Directory"
+            Path = ${Path}
+            ErrorAction = "SilentlyContinue"
+        }
+
+        New-Item @_Params | Set-Location
+    } else {
+        Set-Location -Path ${Path}
+    }
+}

+ 70 - 0
.github/scripts/utils.pwsh/Expand-ArchiveExt.ps1

@@ -0,0 +1,70 @@
+function Expand-ArchiveExt {
+    <#
+        .SYNOPSIS
+            Expands archive files.
+        .DESCRIPTION
+            Allows extraction of zip, 7z, gz, and xz archives.
+            Requires tar and 7-zip to be available on the system.
+            Archives ending with .zip but created using LZMA compression are
+            expanded using 7-zip as a fallback.
+        .EXAMPLE
+            Expand-ArchiveExt -Path <Path-To-Your-Archive>
+            Expand-ArchiveExt -Path <Path-To-Your-Archive> -DestinationPath <Expansion-Path>
+    #>
+
+    param(
+        [Parameter(Mandatory)]
+        [string] $Path,
+        [string] $DestinationPath = [System.IO.Path]::GetFileNameWithoutExtension($Path),
+        [switch] $Force
+    )
+
+    switch ( [System.IO.Path]::GetExtension($Path) ) {
+        .zip {
+            try {
+                Expand-Archive -Path $Path -DestinationPath $DestinationPath -Force:$Force
+            } catch {
+                if ( Get-Command 7z ) {
+                    Invoke-External 7z x -y $Path "-o${DestinationPath}"
+                } else {
+                    throw 'Fallback utility 7-zip not found. Please install 7-zip first.'
+                }
+            }
+            break
+        }
+        .7z {
+            if ( Get-Command 7z ) {
+                Invoke-External 7z x -y $Path "-o${DestinationPath}"
+            } else {
+                throw 'Extraction utility 7-zip not found. Please install 7-zip first.'
+            }
+            break
+        }
+        .gz {
+            try {
+                Invoke-External tar -x -o $DestinationPath -f $Path
+            } catch {
+                if ( Get-Command 7z ) {
+                    Invoke-External 7z x -y $Path "-o${DestinationPath}"
+                } else {
+                    throw 'Fallback utility 7-zip not found. Please install 7-zip first.'
+                }
+            }
+            break
+        }
+        .xz {
+            try {
+                Invoke-External tar -x -o $DestinationPath -f $Path
+            } catch {
+                if ( Get-Command 7z ) {
+                    Invoke-External 7z x -y $Path "-o${DestinationPath}"
+                } else {
+                    throw 'Fallback utility 7-zip not found. Please install 7-zip first.'
+                }
+            }
+        }
+        default {
+            throw 'Unsupported archive extension provided.'
+        }
+    }
+}

+ 60 - 0
.github/scripts/utils.pwsh/Install-BuildDependencies.ps1

@@ -0,0 +1,60 @@
+function Install-BuildDependencies {
+    <#
+        .SYNOPSIS
+            Installs required build dependencies.
+        .DESCRIPTION
+            Additional packages might be needed for successful builds. This module contains additional
+            dependencies available for installation via winget and, if possible, adds their locations
+            to the environment path for future invocation.
+        .EXAMPLE
+            Install-BuildDependencies
+    #>
+
+    param(
+        [string] $WingetFile = "$PSScriptRoot/.Wingetfile"
+    )
+
+    if ( ! ( Test-Path function:Log-Warning ) ) {
+        . $PSScriptRoot/Logger.ps1
+    }
+    
+    $Host64Bit = [System.Environment]::Is64BitOperatingSystem
+
+    $Paths = $Env:Path -split [System.IO.Path]::PathSeparator
+
+    $WingetOptions = @('install', '--accept-package-agreements', '--accept-source-agreements')
+
+    if ( $script:Quiet ) {
+        $WingetOptions += '--silent'
+    }
+
+    Get-Content $WingetFile | ForEach-Object {
+        $_, $Package, $_, $Path, $_, $Binary = ([regex]::Split($_, " (?=(?:[^']|'[^']*')*$)")) -replace ',', '' -replace "'",''
+
+        (${Env:ProgramFiles(x86)}, $Env:ProgramFiles) | ForEach-Object {
+            $Prefix = $_
+            $FullPath = "${Prefix}\${Path}"
+            if ( ( Test-Path $FullPath  ) -and ! ( $Paths -contains $FullPath ) ) {
+                $Paths += $FullPath
+                $Env:Path = $Paths -join [System.IO.Path]::PathSeparator
+            }
+        }
+
+        Log-Debug "Checking for command ${Binary}"
+        $Found = Get-Command -ErrorAction SilentlyContinue $Binary
+
+        if ( $Found ) {
+            Log-Status "Found dependency ${Binary} as $($Found.Source)"
+        } else {
+            Log-Status "Installing package ${Package}"
+
+            try {
+                $Params = $WingetOptions + $Package
+
+                winget @Params
+            } catch {
+                throw "Error while installing winget package ${Package}: $_"
+            }
+        }
+    }
+}

+ 40 - 0
.github/scripts/utils.pwsh/Invoke-External.ps1

@@ -0,0 +1,40 @@
+function Invoke-External {
+    <#
+        .SYNOPSIS
+            Invokes a non-PowerShell command.
+        .DESCRIPTION
+            Runs a non-PowerShell command, and captures its return code.
+            Throws an exception if the command returns non-zero.
+        .EXAMPLE
+            Invoke-External 7z x $MyArchive
+    #>
+
+    if ( $args.Count -eq 0 ) {
+        throw 'Invoke-External called without arguments.'
+    }
+
+    if ( ! ( Test-Path function:Log-Information ) ) {
+        . $PSScriptRoot/Utils-Logger.ps1
+    }
+
+    $Command = $args[0]
+    $CommandArgs = @()
+
+    if ( $args.Count -gt 1) {
+        $CommandArgs = $args[1..($args.Count - 1)]
+    }
+
+    $_EAP = $ErrorActionPreference
+    $ErrorActionPreference = "Continue"
+
+    Log-Debug "Invoke-External: ${Command} ${CommandArgs}"
+
+    & $command $commandArgs
+    $Result = $LASTEXITCODE
+
+    $ErrorActionPreference = $_EAP
+
+    if ( $Result -ne 0 ) {
+        throw "${Command} ${CommandArgs} exited with non-zero code ${Result}."
+    }
+}

+ 117 - 0
.github/scripts/utils.pwsh/Invoke-GitCheckout.ps1

@@ -0,0 +1,117 @@
+function Set-GitConfig {
+    <#
+        .SYNOPSIS
+            Sets a git config value.
+        .DESCRIPTION
+            Allows setting single or multiple config values in a PowerShell-friendly fashion.
+        .EXAMPLE
+            Set-GitConfig advice.detachedHead false
+    #>
+
+    if ( $args.Count -lt 2 ) {
+        throw 'Set-GitConfig called without required arguments <OPTION> <VALUE>.'
+    }
+
+    Invoke-External git config @args
+}
+
+function Invoke-GitCheckout {
+    <#
+        .SYNOPSIS
+            Checks out a specified git repository.
+        .DESCRIPTION
+            Wraps the git executable with PowerShell syntax to check out
+            a specified Git repository with a given commit hash and branch,
+            or a GitHub pull request ID.
+        .EXAMPLE
+            Invoke-GitCheckout -Uri "My-Repo-Uri" -Commit "My-Commit-Hash"
+            Invoke-GitCheckout -Uri "My-Repo-Uri" -Commit "My-Commit-Hash" -Branch "main"
+            Invoke-GitCheckout -Uri "My-Repo-Uri" -Commit "My-Commit-Hash" -PullRequest 250
+    #>
+
+    param(
+        [Parameter(Mandatory)]
+        [string] $Uri,
+        [Parameter(Mandatory)]
+        [string] $Commit,
+        [string] $Path,
+        [string] $Branch = "master",
+        [string] $PullRequest
+    )
+
+    if ( ! ( $Uri -like "*github.com*" ) -and ( $PullRequest -ne "" ) ) {
+        throw 'Fetching pull requests is only supported with GitHub-based repositories.'
+    }
+
+    if ( ! ( Test-Path function:Log-Information ) ) {
+        . $PSScriptRoot/Utils-Logger.ps1
+    }
+
+    if ( ! ( Test-Path function:Invoke-External ) ) {
+        . $PSScriptRoot/Invoke-External.ps1
+    }
+
+    $RepositoryName = [System.IO.Path]::GetFileNameWithoutExtension($Uri)
+
+    if ( $Path -eq "" ) {
+        $Path = "$(Get-Location | Convert-Path)\${RepositoryName}"
+    }
+
+    Push-Location -Stack GitCheckoutTemp
+
+    if ( Test-Path $Path/.git ) {
+        Write-Information "Repository ${RepositoryName} found in ${Path}"
+
+        Set-Location $Path
+
+        Set-GitConfig advice.detachedHead false
+        Set-GitConfig remote.origin.url $Uri
+        Set-GitConfig remote.origin.tapOpt --no-tags
+
+        $Ref = "+refs/heads/{0}:refs/remotes/origin/{0}" -f $Branch
+
+        Set-GitConfig --replace-all remote.origin.fetch $Ref
+
+        if ( $PullRequest -ne "" ) {
+            try {
+                Invoke-External git show-ref --quiet --verify refs/heads/pr-$PullRequest
+            } catch {
+                Invoke-External git fetch origin $("pull/{0}/head:pull-{0}" -f $PullRequest)
+            } finally {
+                Invoke-External git checkout -f "pull-${PullRequest}"
+            }
+        }
+
+        try {
+            $null = Invoke-External git rev-parse -q --verify "${Commit}^{commit}"
+        } catch {
+            Invoke-External git fetch origin
+        }
+
+        Invoke-External git checkout -f $Commit -- | Log-Information
+    } else {
+        Invoke-External git clone $Uri $Path
+
+        Set-Location $Path
+
+        Set-GitConfig advice.detachedHead false
+
+        if ( $PullRequest -ne "" ) {
+            $Ref = "pull/{0}/head:pull-{0}" -f $PullRequest
+            $Branch = "pull-${PullRequest}"
+            Invoke-External git fetch origin $Ref
+            Invoke-External git checkout $Branch
+        }
+
+        Invoke-External git checkout -f $Commit
+    }
+
+    Log-Information "Checked out commit ${Commit} on branch ${Branch}"
+
+    if ( Test-Path ${Path}/.gitmodules ) {
+        Invoke-External git submodule foreach --recursive git submodule sync
+        Invoke-External git submodule update --init --recursive
+    }
+
+    Pop-Location -Stack GitCheckoutTemp
+}

+ 123 - 0
.github/scripts/utils.pwsh/Logger.ps1

@@ -0,0 +1,123 @@
+function Log-Debug {
+    [CmdletBinding()]
+    param(
+        [Parameter(Mandatory,ValueFromPipeline)]
+        [ValidateNotNullOrEmpty()]
+        [string[]] $Message
+    )
+
+    Process {
+        foreach($m in $Message) {
+            Write-Debug $m
+        }
+    }
+}
+
+function Log-Verbose {
+    [CmdletBinding()]
+    param(
+        [Parameter(Mandatory,ValueFromPipeline)]
+        [ValidateNotNullOrEmpty()]
+        [string[]] $Message
+    )
+
+    Process {
+        foreach($m in $Message) {
+            Write-Verbose $m
+        }
+    }
+}
+
+function Log-Warning {
+    [CmdletBinding()]
+    param(
+        [Parameter(Mandatory,ValueFromPipeline)]
+        [ValidateNotNullOrEmpty()]
+        [string[]] $Message
+    )
+
+    Process {
+        foreach($m in $Message) {
+            Write-Warning $m
+        }
+    }
+}
+
+function Log-Error {
+    [CmdletBinding()]
+    param(
+        [Parameter(Mandatory,ValueFromPipeline)]
+        [ValidateNotNullOrEmpty()]
+        [string[]] $Message
+    )
+
+    Process {
+        foreach($m in $Message) {
+            Write-Error $m
+        }
+    }
+}
+
+function Log-Information {
+    [CmdletBinding()]
+    param(
+        [Parameter(Mandatory,ValueFromPipeline)]
+        [ValidateNotNullOrEmpty()]
+        [string[]] $Message
+    )
+
+    Process {
+        if ( ! ( $script:Quiet ) ) {
+            $StageName = $( if ( $script:StageName -ne $null ) { $script:StageName } else { '' })
+            $Icon = ' =>'
+
+            foreach($m in $Message) {
+                Write-Host -NoNewLine -ForegroundColor Blue "  ${StageName} $($Icon.PadRight(5)) "
+                Write-Host "${m}"
+            }
+        }
+    }
+}
+
+function Log-Status {
+    [CmdletBinding()]
+    param(
+        [Parameter(Mandatory,ValueFromPipeline)]
+        [ValidateNotNullOrEmpty()]
+        [string[]] $Message
+    )
+
+    Process {
+        if ( ! ( $script:Quiet ) ) {
+            $StageName = $( if ( $StageName -ne $null ) { $StageName } else { '' })
+            $Icon = '  >'
+
+            foreach($m in $Message) {
+                Write-Host -NoNewLine -ForegroundColor Green "  ${StageName} $($Icon.PadRight(5)) "
+                Write-Host "${m}"
+            }
+        }
+    }
+}
+
+function Log-Output {
+    [CmdletBinding()]
+    param(
+        [Parameter(Mandatory,ValueFromPipeline)]
+        [ValidateNotNullOrEmpty()]
+        [string[]] $Message
+    )
+
+    Process {
+        if ( ! ( $script:Quiet ) ) {
+            $StageName = $( if ( $script:StageName -ne $null ) { $script:StageName } else { '' })
+            $Icon = ''
+
+            foreach($m in $Message) {
+                Write-Output "  ${StageName} $($Icon.PadRight(5)) ${m}"
+            }
+        }
+    }
+}
+
+$Columns = (Get-Host).UI.RawUI.WindowSize.Width - 5

+ 110 - 0
.github/scripts/utils.pwsh/Setup-Host.ps1

@@ -0,0 +1,110 @@
+function Setup-Host {
+    if ( ! ( Test-Path function:Log-Output ) ) {
+        . $PSScriptRoot/Logger.ps1
+    }
+
+    if ( ! ( Test-Path function:Ensure-Location ) ) {
+        . $PSScriptRoot/Ensure-Location.ps1
+    }
+
+    if ( ! ( Test-Path function:Install-BuildDependencies ) ) {
+        . $PSScriptRoot/Install-BuildDependencies.ps1
+    }
+
+    Install-BuildDependencies -WingetFile "${ScriptHome}/.Wingetfile"
+
+    if ( $script:Target -eq '' ) { $script:Target = $script:HostArchitecture }
+
+    Push-Location -Stack BuildTemp
+    Log-Information 'Setting up obs-deps...'
+    $DepsVersion = $BuildSpec.dependencies.'obs-deps'."windows-${script:Target}".version
+    $DepsHash = $BuildSpec.dependencies.'obs-deps'."windows-${script:Target}".hash
+
+    if ( ${DepsVersion} -eq '' ) {
+        throw 'No obs-deps version found in buildspec.json.'
+    }
+    Log-Status 'Found obs-deps specification.'
+
+    Ensure-Location -Path "$(Resolve-Path -Path "${ProjectRoot}/..")/obs-build-dependencies"
+
+    if ( ! ( Test-Path -Path "windows-deps-${DepsVersion}-${script:Target}.zip" ) ) {
+        $Params = @{
+            UserAgent = 'NativeHost'
+            Uri = "https://github.com/obsproject/obs-deps/releases/download/win-${DepsVersion}/windows-deps-${DepsVersion}-${script:Target}.zip"
+            OutFile = "windows-deps-${DepsVersion}-${script:Target}.zip"
+            UseBasicParsing = $true
+            ErrorAction = 'Stop'
+        }
+
+        Invoke-WebRequest @Params
+        Log-Status "Downloaded obs-deps for ${script:Target}."
+    } else {
+        Log-Status 'Found downloaded obs-deps.'
+    }
+
+    $FileHash = Get-FileHash -Path "windows-deps-${DepsVersion}-${script:Target}.zip" -Algorithm SHA256
+
+    if ( $FileHash.Hash.ToLower() -ne $DepsHash ) {
+        throw "Checksum mismatch of obs-deps download. Expected '${DepsHash}', found '$(${FileHash}.Hash.ToLower())'"
+    }
+    Log-Status 'Checksum of downloaded obs-deps matches.'
+
+    Ensure-Location -Path "plugin-deps-${Target}"
+
+    if ( ! ( Test-Path function:Expand-ArchiveExt ) ) {
+        . $PSScriptRoot/Expand-ArchiveExt.ps1
+    }
+
+    Log-Information 'Extracting obs-deps...'
+    Expand-ArchiveExt -Path "../windows-deps-${DepsVersion}-${script:Target}.zip" -DestinationPath . -Force
+    Pop-Location -Stack BuildTemp
+
+    Push-Location -Stack BuildTemp
+    Log-Information 'Setting up Qt...'
+    $QtVersion = $BuildSpec.dependencies.'obs-deps-qt'."windows-${script:Target}".version
+    $QtHash = $BuildSpec.dependencies.'obs-deps-qt'."windows-${script:Target}".hash
+
+    if ( ${QtVersion} -eq '' ) {
+        throw 'No Qt version found in buildspec.json.'
+    }
+    Log-Status 'Found Qt specification.'
+
+    Ensure-Location -Path "$(Resolve-Path -Path "${ProjectRoot}/..")/obs-build-dependencies"
+
+    if ( ! ( Test-Path -Path "windows-deps-qt-${DepsVersion}-${script:Target}.zip" ) ) {
+        $Params = @{
+            UserAgent = 'NativeHost'
+            Uri = "https://cdn-fastly.obsproject.com/downloads/windows-deps-qt-${DepsVersion}-${script:Target}.zip"
+            OutFile = "windows-deps-qt-${DepsVersion}-${script:Target}.zip"
+            UseBasicParsing = $true
+            ErrorAction = 'Stop'
+        }
+
+        Invoke-WebRequest @Params
+        Log-Status "Downloaded Qt for ${script:Target}."
+    } else {
+        Log-Status 'Found downloaded Qt.'
+    }
+
+    $FileHash = Get-FileHash -Path "windows-deps-qt-${DepsVersion}-${script:Target}.zip" -Algorithm SHA256
+
+    if ( $FileHash.Hash.ToLower() -ne ${QtHash} ) {
+        throw "Checksum mismatch of Qt download. Expected '${QtHash}', found '$(${FileHash}.Hash.ToLower())'"
+    }
+    Log-Status 'Checksum of downloaded Qt matches.'
+
+    Ensure-Location -Path "plugin-deps-${Target}"
+
+    Log-Information 'Extracting Qt...'
+    Expand-ArchiveExt -Path "../windows-deps-qt-${DepsVersion}-${script:Target}.zip" -DestinationPath . -Force
+    Pop-Location -Stack BuildTemp
+}
+
+function Get-HostArchitecture {
+    $Host64Bit = [System.Environment]::Is64BitOperatingSystem
+    $HostArchitecture = ('x86', 'x64')[$Host64Bit]
+
+    return $HostArchitecture
+}
+
+$script:HostArchitecture = Get-HostArchitecture

+ 77 - 0
.github/scripts/utils.pwsh/Setup-Obs.ps1

@@ -0,0 +1,77 @@
+function Setup-Obs {
+    if ( ! ( Test-Path function:Log-Output ) ) {
+        . $PSScriptRoot/Logger.ps1
+    }
+
+    if ( ! ( Test-Path function:Check-Git ) ) {
+        . $PSScriptRoot/Check-Git.ps1
+    }
+
+    Check-Git
+
+    if ( ! ( Test-Path function:Ensure-Location ) ) {
+        . $PSScriptRoot/Ensure-Location.ps1
+    }
+
+    if ( ! ( Test-Path function:Invoke-GitCheckout ) ) {
+        . $PSScriptRoot/Invoke-GitCheckout.ps1
+    }
+
+    if ( ! ( Test-Path function:Invoke-External ) ) {
+        . $PSScriptRoot/Invoke-External.ps1
+    }
+
+    Log-Information 'Setting up OBS Studio...'
+
+    $ObsVersion = $BuildSpec.dependencies.'obs-studio'.version
+    $ObsRepository = $BuildSpec.dependencies.'obs-studio'.repository
+    $ObsBranch = $BuildSpec.dependencies.'obs-studio'.branch
+    $ObsHash = $BuildSpec.dependencies.'obs-studio'.hash
+
+    if ( $ObsVersion -eq '' ) {
+        throw 'No obs-studio version found in buildspec.json.'
+    }
+
+    Push-Location -Stack BuildTemp
+    Ensure-Location -Path "$(Resolve-Path -Path "${ProjectRoot}/../")/obs-studio"
+
+    Invoke-GitCheckout -Uri $ObsRepository -Commit $ObsHash -Path . -Branch $ObsBranch
+
+    Log-Information 'Configuring OBS Studio...'
+
+    $NumProcessors = (Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors
+
+    if ( $NumProcessors -gt 1 ) {
+        $env:UseMultiToolTask = $true
+        $env:EnforceProcessCountAcrossBuilds = $true
+    }
+
+    $CmakeArgs = @(
+        '-G', $script:CmakeGenerator
+        '-DCMAKE_SYSTEM_VERSION=10.0.18363.657'
+        "-DCMAKE_GENERATOR_PLATFORM=$(if (${script:Target} -eq "x86") { "Win32" } else { "x64" })"
+        "-DCMAKE_BUILD_TYPE=${script:Configuration}"
+        '-DENABLE_PLUGINS=OFF'
+        '-DENABLE_UI=OFF'
+        '-DENABLE_SCRIPTING=OFF'
+        "-DCMAKE_INSTALL_PREFIX=$(Resolve-Path -Path "${ProjectRoot}/../obs-build-dependencies/plugin-deps-${Target}")"
+        "-DCMAKE_PREFIX_PATH=$(Resolve-Path -Path "${ProjectRoot}/../obs-build-dependencies/plugin-deps-${Target}")"
+    )
+
+    Invoke-External cmake -S . -B plugin_${script:Target} @CmakeArgs
+
+    Log-Information 'Building libobs and obs-frontend-api...'
+
+    $CmakeArgs = @(
+        '--config', "$( if ( $script:Configuration -eq '' ) { 'RelWithDebInfo' } else { $script:Configuration })"
+    )
+
+    if ( $VerbosePreference -eq 'Continue' ) {
+        $CmakeArgs+=('--verbose')
+    }
+
+    Invoke-External cmake --build plugin_${script:Target} @CmakeArgs -t obs-frontend-api
+    Invoke-External cmake --install plugin_${script:Target} @CmakeArgs --component obs_libraries
+
+    Pop-Location -Stack BuildTemp
+}

+ 1 - 0
.github/scripts/utils.zsh/check_linux

@@ -0,0 +1 @@
+:

+ 18 - 0
.github/scripts/utils.zsh/check_macos

@@ -0,0 +1,18 @@
+autoload -Uz is-at-least log_info log_error log_status read_codesign
+
+local macos_version=$(sw_vers -productVersion)
+
+log_info 'Checking macOS version...'
+if ! is-at-least 10.15.0 "${macos_version}"; then
+  log_error "Minimum required macOS version is 10.15, but running on macOS ${macos_version}"
+  return 2
+else
+  log_status "macOS ${macos_version} is recent"
+fi
+
+log_info 'Checking for Homebrew...'
+if (( ! ${+commands[brew]} )) {
+  log_error 'No Homebrew command found. Please install Homebrew (https://brew.sh)'
+  return 2
+}
+brew bundle --file "${SCRIPT_HOME}/.Brewfile"

+ 51 - 0
.github/scripts/utils.zsh/check_packages

@@ -0,0 +1,51 @@
+if (( ! ${+commands[packagesbuild]} )) {
+  autoload -Uz log_info log_status mkcd
+
+  if (( ! ${+commands[curl]} )) {
+    log_error 'curl not found. Please install curl.'
+    return 2
+  }
+
+  if (( ! ${+project_root} )) {
+    log_error "'project_root' not set. Please set before running ${0}."
+    return 2
+  }
+
+  local -a curl_opts=()
+  if (( ! ${+CI} )) {
+    curl_opts+=(--progress-bar)
+  } else {
+    curl_opts+=(--show-error --silent)
+  }
+  curl_opts+=(--location -O ${@})
+
+  log_info 'Installing Packages.app...'
+
+  pushd
+  mkcd ${project_root:h}/obs-build-dependencies
+
+  local packages_url='http://s.sudre.free.fr/Software/files/Packages.dmg'
+  local packages_hash='6afdd25386295974dad8f078b8f1e41cabebd08e72d970bf92f707c7e48b16c9'
+
+  if [[ ! -f Packages.dmg ]] {
+    log_status 'Download Packages.app'
+    curl ${curl_opts} ${packages_url}
+  }
+
+  read -r image_checksum _ <<< "$(sha256sum Packages.dmg)"
+
+  if [[ ${packages_hash} != ${image_checksum} ]] {
+    log_error "Checksum mismatch of Packages.app download.
+Expected : ${packages_hash}
+Actual   : ${image_checksum}"
+    return 2
+  }
+
+  hdiutil attach -noverify Packages.dmg &> /dev/null && log_status 'Packages.dmg image mounted.'
+
+  log_info 'Installing Packages.app...'
+  packages_volume=$(hdiutil info -plist | grep '<string>/Volumes/Packages' | sed 's/.*<string>\(\/Volumes\/[^<]*\)<\/string>/\1/')
+
+  sudo installer -pkg "${packages_volume}/packages/Packages.pkg" -target / && rehash
+  hdiutil detach ${packages_volume} &> /dev/null && log_status 'Packages.dmg image unmounted.'
+}

+ 9 - 0
.github/scripts/utils.zsh/check_xcnotary

@@ -0,0 +1,9 @@
+autoload -Uz log_info log_error
+
+log_info 'Checking for Homebrew...'
+if (( ! ${+commands[brew]} )) {
+  log_error 'No Homebrew command found. Please install Homebrew (https://brew.sh)'
+  return 2
+}
+
+if (( ! ${+commands[xcnotary]} )) brew install akeru-inc/tap/xcnotary

+ 3 - 0
.github/scripts/utils.zsh/log_debug

@@ -0,0 +1,3 @@
+if (( ! ${+_loglevel} )) typeset -g _loglevel=1
+
+if (( _loglevel > 2 )) print -PR -e -- "%F{220}DEBUG: ${@}%f"

+ 3 - 0
.github/scripts/utils.zsh/log_error

@@ -0,0 +1,3 @@
+local icon='  ✖︎ '
+
+print -u2 -PR "%F{1} ${icon} %f ${@}"

+ 7 - 0
.github/scripts/utils.zsh/log_info

@@ -0,0 +1,7 @@
+if (( ! ${+_loglevel} )) typeset -g _loglevel=1
+
+if (( _loglevel > 0 )) {
+  local icon=' =>'
+
+  print -PR "%F{4}  ${(r:5:)icon}%f %B${@}%b"
+}

+ 7 - 0
.github/scripts/utils.zsh/log_output

@@ -0,0 +1,7 @@
+if (( ! ${+_loglevel} )) typeset -g _loglevel=1
+
+if (( _loglevel > 0 )) {
+  local icon=''
+
+  print -PR "  ${(r:5:)icon} ${@}"
+}

+ 7 - 0
.github/scripts/utils.zsh/log_status

@@ -0,0 +1,7 @@
+if (( ! ${+_loglevel} )) typeset -g _loglevel=1
+
+if (( _loglevel > 0 )) {
+  local icon='  >'
+
+  print -PR "%F{2}  ${(r:5:)icon}%f ${@}"
+}

+ 5 - 0
.github/scripts/utils.zsh/log_warning

@@ -0,0 +1,5 @@
+if (( _loglevel > 0 )) {
+  local icon=' =>'
+
+  print -PR "%F{3}  ${(r:5:)icon} ${@}%f"
+}

+ 1 - 0
.github/scripts/utils.zsh/mkcd

@@ -0,0 +1 @@
+[[ -n ${1} ]] && mkdir -p ${1} && builtin cd ${1}

+ 7 - 0
.github/scripts/utils.zsh/read_codesign

@@ -0,0 +1,7 @@
+autoload -Uz log_info
+
+if (( ! ${+CODESIGN_IDENT} )) {
+  typeset -g CODESIGN_IDENT
+  log_info 'Setting up identity for application codesigning...'
+  read CODESIGN_IDENT'?Apple Developer Application ID: '
+}

+ 7 - 0
.github/scripts/utils.zsh/read_codesign_installer

@@ -0,0 +1,7 @@
+autoload -Uz log_info
+
+if (( ! ${+CODESIGN_IDENT_INSTALLER} )) {
+  typeset -g CODESIGN_IDENT_INSTALLER
+  log_info 'Setting up identity for installer package codesigning...'
+  read CODESIGN_IDENT_INSTALLER'?Apple Developer Installer ID: '
+}

+ 31 - 0
.github/scripts/utils.zsh/read_codesign_pass

@@ -0,0 +1,31 @@
+##############################################################################
+# 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.
+##############################################################################
+
+autoload -Uz read_codesign read_codesign_user log_info
+
+if (( ! ${+CODESIGN_IDENT} )) {
+  read_codesign
+}
+
+if (( ! ${+CODESIGN_IDENT_USER} )) {
+  read_codesign_user
+}
+
+log_info 'Setting up password for notarization keychain...'
+if (( ! ${+CODESIGN_IDENT_PASS} )) {
+  read -s CODESIGN_IDENT_PASS'?Apple Developer ID password: '
+}
+
+log_info 'Setting up notarization keychain...'
+xcrun altool --store-password-in-keychain-item 'OBS-Codesign-Password' -u "${CODESIGN_IDENT_USER}" -p "${CODESIGN_IDENT_PASS}"
+typeset -g CODESIGN_IDENT_SHORT=$(print "${CODESIGN_IDENT}" | /usr/bin/sed -En 's/.+\((.+)\)/\1/p')

+ 7 - 0
.github/scripts/utils.zsh/read_codesign_user

@@ -0,0 +1,7 @@
+autoload -Uz log_info
+
+if (( ! ${+CODESIGN_IDENT_USER} )) {
+  typeset -g CODESIGN_IDENT_USER
+  log_info 'Setting up developer id for codesigning...'
+  read CODESIGN_IDENT_USER'?Apple Developer ID: '
+}

+ 17 - 0
.github/scripts/utils.zsh/set_loglevel

@@ -0,0 +1,17 @@
+autoload -Uz log_debug log_error
+
+local -r _usage="Usage: %B${0}%b <loglevel>
+
+Set log level, following levels are supported: 0 (quiet), 1 (normal), 2 (verbose), 3 (debug)"
+
+if (( ! # )); then
+  log_error 'Called without arguments.'
+  log_output ${_usage}
+  return 2
+elif (( ${1} >= 4 )); then
+  log_error 'Called with loglevel > 3.'
+  log_output ${_usage}
+fi
+
+typeset -g -i -r _loglevel=${1}
+log_debug "Log level set to '${1}'"

+ 44 - 0
.github/scripts/utils.zsh/setup_linux

@@ -0,0 +1,44 @@
+autoload -Uz log_error log_status log_info mkcd
+
+if (( ! ${+commands[apt-get]} )) {
+  log_error 'apt-get not found. Please ensure apt is available on the system.'
+  return 2
+}
+
+log_info 'Installing obs build dependencies...'
+sudo dpkg --add-architecture amd64
+sudo apt-get -qq update
+sudo apt-get install -y \
+    build-essential \
+    ninja-build \
+    clang \
+    clang-format \
+    git \
+    jq \
+    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
+
+rehash

+ 104 - 0
.github/scripts/utils.zsh/setup_macos

@@ -0,0 +1,104 @@
+autoload -Uz log_error log_status log_info mkcd
+
+if (( ! ${+commands[curl]} )) {
+  log_error 'curl not found. Please install curl.'
+  return 2
+}
+
+if (( ! ${+commands[jq]} )) {
+  log_error 'jq not found. Please install jq.'
+  return 2
+}
+
+if (( ! ${+project_root} )) {
+  log_error "'project_root' not set. Please set before running ${0}."
+  return 2
+}
+
+if (( ! ${+target} )) {
+  log_error "'target' not set. Please set before running ${0}."
+  return 2
+}
+
+local -a curl_opts=()
+if (( ! ${+CI} )) {
+    curl_opts+=(--progress-bar)
+} else {
+    curl_opts+=(--show-error --silent)
+}
+curl_opts+=(--location -O ${@})
+
+pushd ${project_root}
+log_info 'Setting up obs-deps...'
+read -r deps_version deps_hash <<< \
+  "$(jq -r --arg key "obs-deps" --arg target "${target}" \
+    '.dependencies[$key][$target] | {version, hash} | join(" ")' \
+    ${buildspec_file})"
+
+if [[ -z "${deps_version}" ]] {
+  log_error 'No obs-deps version found in buildspec.json.'
+  return 2
+}
+log_status 'Found obs-deps specification.'
+
+mkcd ${project_root:h}/obs-build-dependencies
+
+if [[ ! -f macos-deps-${deps_version}-${target##*-}.tar.xz ]] {
+  curl ${curl_opts} \
+    "https://github.com/obsproject/obs-deps/releases/download/${deps_version}/macos-deps-${deps_version}-${target##*-}.tar.xz" && \
+    log_status "Downloaded obs-deps for ${target}."
+} else {
+  log_status 'Found downloaded obs-deps.'
+}
+
+read -r artifact_checksum _ <<< "$(sha256sum macos-deps-${deps_version}-${target##*-}.tar.xz)"
+if [[ ${deps_hash} != ${artifact_checksum} ]] {
+  log_error "Checksum of downloaded obs-deps does not match specification.
+Expected : ${deps_hash}
+Actual   : ${artifact_checksum}"
+  return 2
+}
+log_status 'Checksum of downloaded obs-deps matches.'
+
+mkcd obs-plugin-deps
+XZ_OPT=-T0 tar -xzf ../macos-deps-${deps_version}-${target##*-}.tar.xz && log_status 'obs-deps extracted.'
+popd
+
+pushd ${project_root}
+log_info 'Setting up Qt...'
+read -r qt_version qt_hash <<< \
+  "$(jq -r --arg key "obs-deps-qt" --arg target "${target}" \
+    '.dependencies[$key][$target] | {version, hash} | join(" ")' \
+    ${buildspec_file})"
+
+if [[ -z "${qt_version}" ]] {
+  log_error 'No obs-deps version found in buildspec.json.'
+  return 2
+}
+log_status 'Found Qt specification.'
+
+mkcd ${project_root:h}/obs-build-dependencies
+
+if [[ ! -f macos-deps-qt-${deps_version}-${target##*-}.tar.xz ]] {
+  curl ${curl_opts} \
+    "https://github.com/obsproject/obs-deps/releases/download/${deps_version}/macos-deps-qt-${deps_version}-${target##*-}.tar.xz" && \
+    log_status "Downloaded Qt for ${target}"
+} else {
+  log_status 'Found downloaded Qt.'
+}
+
+read -r artifact_checksum _ <<< "$(sha256sum macos-deps-qt-${deps_version}-${target##*-}.tar.xz)"
+if [[ ${qt_hash} != ${artifact_checksum} ]] {
+  log_error "Checksum of downloaded Qt does not match specification.
+Expected : ${qt_hash}
+Actual   : ${artifact_checksum}"
+  return 2
+}
+log_status 'Checksum of downloaded Qt matches.'
+
+mkcd obs-plugin-deps
+XZ_OPT=-T0 tar -xzf ../macos-deps-qt-${qt_version}-${target##*-}.tar.xz && log_status 'Qt extracted.'
+
+xattr -r -d com.apple.quarantine *
+log_status 'Removed quarantine flag from downloaded dependencies...'
+popd

+ 105 - 0
.github/scripts/utils.zsh/setup_obs

@@ -0,0 +1,105 @@
+autoload -Uz log_error log_info log_status
+
+if (( ! ${+buildspec_file} )) {
+  log_error "'buildspec_file' not set. Please set before running ${0}."
+  return 2
+}
+
+if (( ! ${+commands[git]} )) {
+  log_error 'git not found. Please install git.'
+  return 2
+}
+
+if (( ! ${+commands[jq]} )) {
+  log_error 'jq not found. Please install jq.'
+  return 2
+}
+
+if (( ! ${+project_root} )) {
+  log_error "'project_root' not set. Please set before running ${0}."
+  return 2
+}
+
+if (( ! ${+target} )) {
+  log_error "'target' not set. Please set before running ${0}."
+  return 2
+}
+
+if [[ ! -r ${buildspec_file} ]] {
+  log_error \
+    'No buildspec.json found. Please create a build specification for your project.' \
+    'A buildspec.json.template file is provided in the repository to get you started.'
+  return 2
+}
+
+log_info 'Setting up OBS-Studio...'
+
+read -r obs_version obs_repo obs_branch obs_hash <<< \
+  "$(jq -r --arg key "obs-studio" \
+     '.dependencies[$key] | {version, repository, branch, hash} | join(" ")' \
+     ${buildspec_file})"
+
+if [[ -z ${obs_version} ]] {
+  log_error "No obs-studio version found in buildspec.json"
+  return 2
+}
+
+pushd
+mkcd ${project_root:h}/obs-studio
+
+if [[ -d .git ]] {
+  git config advice.detachedHead false
+  git config remote.pluginbuild.url "${obs_repo:-https://github.com/obsproject/obs-studio.git}"
+  git config remote.pluginbuild.fetch "+refs/heads/${obs_branch:-master}:refs/remotes/origin/${obs_branch:-master}"
+
+  git rev-parse -q --verify "${obs_hash}^{commit}" > /dev/null || git fetch pluginbuild
+  git checkout ${obs_branch:-master} -B ${product_name}
+  git reset --hard "${obs_hash}"
+  log_status 'Found existing obs-studio repository.'
+} else {
+  git clone "${obs_repo:-https://github.com/obsproject/obs-studio.git}" "${PWD}"
+  git config advice.detachedHead false
+  git checkout -f "${obs_hash}" --
+  git checkout ${obs_branch:-master} -b ${product_name}
+  log_status 'obs-studio checked out.'
+}
+
+git submodule foreach --recursive git submodule sync
+git submodule update --init --recursive
+
+log_info 'Configuring obs-studio...'
+
+local -a cmake_args=(
+  -DCMAKE_BUILD_TYPE=${BUILD_CONFIG:-Release}
+  -DENABLE_PLUGINS=OFF
+  -DENABLE_UI=OFF
+  -DENABLE_SCRIPTING=OFF
+  -DCMAKE_INSTALL_PREFIX="${project_root:h}/obs-build-dependencies/obs-plugin-deps"
+  -DCMAKE_PREFIX_PATH="${project_root:h}/obs-build-dependencies/obs-plugin-deps"
+)
+
+if (( _loglevel == 0 )) cmake_args+=(-Wno_deprecated -Wno-dev --log-level=ERROR)
+
+case ${target} {
+  macos-*)
+    cmake_args+=(
+      -DCMAKE_OSX_ARCHITECTURES=${${target##*-}//universal/x86_64;arm64}
+      -DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET:-10.15}
+    )
+    ;;
+  linux-*)
+    cmake_args+=(
+      -DENABLE_PIPEWIRE=OFF
+    )
+    ;;
+}
+
+cmake -S . -B plugin_build_${target##*-} -G Ninja ${cmake_args}
+
+log_info 'Building libobs and obs-frontend-api...'
+local -a cmake_args=()
+if (( _loglevel > 1 )) cmake_args+=(--verbose)
+
+cmake --build plugin_build_${target##*-} --config ${BUILD_CONFIG:-Release} ${cmake_args} -t obs-frontend-api
+cmake --install plugin_build_${target##*-} --config ${BUILD_CONFIG:-Release} --component obs_libraries ${cmake_args}
+popd

+ 256 - 276
.github/workflows/main.yml

@@ -1,4 +1,4 @@
-name: 'BUILD'
+name: 'Build on Push and Tag'
 
 on:
   push:
@@ -10,385 +10,365 @@ on:
     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'
+  PLUGIN_NAME: 'obs-plugintemplate'
 
 jobs:
   clang_check:
-    name: '01 - Code Format Check'
-    runs-on: [ubuntu-latest]
+    name: 01 - Code Format Check
+    runs-on: ubuntu-20.04
     steps:
-      - name: 'Checkout'
-        uses: actions/checkout@v2.3.3
+      - name: Checkout
+        uses: actions/checkout@v3
         with:
           submodules: 'recursive'
 
-      - name: 'Install clang-format'
+      - 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
+      - name: Run clang-format
+        run: ./.github/scripts/check-format.sh && ./.github/scripts/check-changes.sh
+
+      - name: Install cmake-format
+        run: sudo pip install cmakelang
+
+      - name: Run cmake-format
+        run: ./.github/scripts/check-cmake.sh
 
   macos_build:
-    name: '02 - macOS (Latest)'
-    runs-on: [macos-11]
+    name: 02 - macOS
+    runs-on: macos-11
     strategy:
       matrix:
-        arch: ['x86_64']
+        arch: ['x86_64', 'arm64', 'universal']
     if: always()
     needs: [clang_check]
+    outputs:
+      commitHash: ${{ steps.setup.outputs.commitHash }}
     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 != '' }}
+      CODESIGN_IDENT_INSTALLER: ''
+      MACOSX_DEPLOYMENT_TARGET: '10.15'
     defaults:
       run:
-        shell: bash
+        shell: zsh {0}
     steps:
-      - name: 'Checkout'
-        uses: actions/checkout@v2.3.3
+      - name: Checkout
+        uses: actions/checkout@v3
         with:
           path: 'plugin'
           submodules: 'recursive'
 
-      - name: 'Checkout'
-        uses: actions/checkout@v2.3.3
+      - name: Checkout obs-studio
+        uses: actions/checkout@v3
         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'
+      - name: Setup Environment
+        id: setup
+        working-directory: ${{ github.workspace }}/plugin
         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
+          typeset -a to_remove=()
 
-          echo "CACHE_DATE=$(date +"%Y-%m-%d")" >> $GITHUB_ENV
+          for formula (speexdsp curl php) {
+            if [[ -d ${HOMEBREW_PREFIX}/opt/${formula} ]] to_remove+=(${formula})
+          }
 
-      - 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 }}
+          if (( #to_remove > 0 )) brew uninstall --ignore-dependencies ${to_remove}
 
-      - 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 [[ '${{ secrets.MACOS_SIGNING_APPLICATION_IDENTITY }}' != '' && \
+                '${{ secrets.MACOS_SIGNING_INSTALLER_IDENTITY }}' != '' && \
+                '${{ secrets.MACOS_SIGNING_CERT }}' != '' ]] {
+            print '::set-output name=haveCodesignIdent::true'
+          } else {
+            print '::set-output name=haveCodesignIdent::false'
+          }
 
-          if [ -n "${REMOVE_FORMULAS}" ]; then
-            brew uninstall ${REMOVE_FORMULAS}
-          fi
+          if [[ '${{ secrets.MACOS_NOTARIZATION_USERNAME }}' != '' && \
+                '${{ secrets.MACOS_NOTARIZATION_PASSWORD }}' != '' ]] {
+            print '::set-output name=haveNotarizationUser::true'
+          } else {
+            print '::set-output name=haveNotarizationUser::false'
+          }
 
-      - name: 'Install dependencies'
-        run: CI/macos/01_install_dependencies.sh --architecture "${{ matrix.arch }}"
+          print "::set-output name=ccacheDate::$(date +"%Y-%m-%d")"
+          print "::set-output name=commitHash::$(git rev-parse --short HEAD)"
 
-      - name: 'Restore libobs and obs-frontend-api from cache'
-        id: libobs-cache
-        uses: actions/cache@v2.1.2
-        env:
-          CACHE_NAME: 'libobs-cache'
+      - name: Restore Compilation Cache
+        id: ccache-cache
+        uses: actions/cache@v2.1.7
         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'
+          path: ${{ github.workspace }}/.ccache
+          key: macos-${{ matrix.arch }}-ccache-plugin-${{ steps.setup.outputs.ccacheDate }}
+          restore-keys: |
+            macos-${{ matrix.arch }}-ccache-plugin-
+
+      - name: Check for GitHub Labels
+        id: seekingTesters
+        if: ${{ github.event_name == 'pull_request' }}
+        run: |
+          if [[ -n "$(curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -s "${{ github.event.pull_request.url }}" | jq -e '.labels[] | select(.name == "Seeking Testers")')" ]] {
+            print '::set-output name=found::true'
+          } else {
+            print '::set-output name=found::false'
+          }
+
+      - name: Install Apple Developer Certificate
+        if: ${{ github.event_name != 'pull_request' && steps.setup.outputs.haveCodesignIdent == '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'
+      - name: Set Signing Identity
+        if: ${{ github.event_name != 'pull_request' && steps.setup.outputs.haveCodesignIdent == '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 }}"
+          print "CODESIGN_IDENT=${{ secrets.MACOS_SIGNING_APPLICATION_IDENTITY }}" >> $GITHUB_ENV
+          print "CODESIGN_IDENT_INSTALLER=${{ secrets.MACOS_SIGNING_INSTALLER_IDENTITY }}" >> $GITHUB_ENV
 
-      - 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
+      - name: Build Plugin
+        uses: ./plugin/.github/actions/build-plugin
+        with:
+          workingDirectory: ${{ github.workspace }}/plugin
+          target: ${{ matrix.arch }}
+          config: RelWithDebInfo
+          codesign: 'true'
+          codesignIdent: ${{ env.CODESIGN_IDENT }}
+
+      - name: Package Plugin
+        uses: ./plugin/.github/actions/package-plugin
         with:
-          name: '${{ env.PRODUCT_NAME }}-macos-${{ matrix.arch }}'
-          path: '${{ github.workspace }}/plugin/*-macOS.pkg'
+          workingDirectory: ${{ github.workspace }}/plugin
+          target: ${{ matrix.arch }}
+          config: RelWithDebInfo
+          codesign: ${{ github.event_name != 'pull_request' && steps.setup.outputs.haveCodesignIdent == 'true' }}
+          notarize: ${{ startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' && steps.setup.outputs.haveNotarizationUser == 'true' }}
+          codesignIdent: ${{ env.CODESIGN_IDENT }}
+          installerIdent: ${{ env.CODESIGN_IDENT_INSTALLER }}
+          codesignUser: ${{ secrets.MACOS_NOTARIZATION_USERNAME }}
+          codesignPass: ${{ secrets.MACOS_NOTARIZATION_PASSWORD }}
+
+      - name: Upload Build Artifact
+        if: ${{ success() && (github.event_name != 'pull_request' || steps.seekingTesters.outputs.found == 'true') }}
+        uses: actions/upload-artifact@v3
+        with:
+          name: ${{ env.PLUGIN_NAME }}-macos-${{ matrix.arch }}-${{ steps.setup.outputs.commitHash }}
+          path: ${{ github.workspace }}/plugin/release/${{ env.PLUGIN_NAME }}-*-macos-*.pkg
 
   linux_build:
-    name: '02 - Linux (Ubuntu, 20.04)'
-    runs-on: ${{ matrix.ubuntu }}
+    name: 02 - Linux
+    runs-on: ubuntu-20.04
     strategy:
       matrix:
-        ubuntu: ['ubuntu-20.04', 'ubuntu-18.04']
+        arch: ['x86_64']
     if: always()
     needs: [clang_check]
+    outputs:
+      commitHash: ${{ steps.setup.outputs.commitHash }}
     defaults:
       run:
         shell: bash
     steps:
-      - name: 'Checkout'
-        uses: actions/checkout@v2.3.3
+      - name: Checkout
+        uses: actions/checkout@v3
         with:
           path: 'plugin'
           submodules: 'recursive'
 
-      - name: 'Checkout'
-        uses: actions/checkout@v2.3.3
+      - name: Checkout obs-studio
+        uses: actions/checkout@v3
         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'
+      - name: Setup Environment
+        working-directory: ${{ github.workspace }}/plugin
+        id: setup
         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 "::set-output name=ccacheDate::$(date +"%Y-%m-%d")"
+          echo "::set-output name=commitHash::$(git rev-parse --short HEAD)"
 
-          echo "CACHE_DATE=$(date +"%Y-%m-%d")" >> $GITHUB_ENV
-
-      - name: 'Restore ccache from cache'
+      - name: Restore Compilation Cache
         id: ccache-cache
-        uses: actions/cache@v2.1.2
-        env:
-          CACHE_NAME: 'ccache-cache'
+        uses: actions/cache@v2.1.7
         with:
           path: ${{ github.workspace }}/.ccache
-          key: ${{ runner.os }}-pr-${{ env.CACHE_NAME }}-${{ matrix.ubuntu }}-${{ env.CACHE_DATE }}
+          key: macos-${{ matrix.arch }}-ccache-plugin-${{ steps.setup.outputs.ccacheDate }}
+          restore-keys: |
+            macos-${{ matrix.arch }}-ccache-plugin-
 
-      - name: "Install Dependencies"
-        working-directory: 'plugin'
-        run: CI/linux/01_install_dependencies.sh --disable-pipewire
+      - name: Check for GitHub Labels
+        id: seekingTesters
+        if: ${{ github.event_name == 'pull_request' }}
+        run: |
+          if [[ -n "$(curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -s "${{ github.event.pull_request.url }}" | jq -e '.labels[] | select(.name == "Seeking Testers")')" ]]; then
+            echo '::set-output name=found::true'
+          else
+            echo '::set-output name=found::false'
+          fi
 
-      - name: 'Restore libobs and obs-frontend-api from cache'
-        id: libobs-cache
-        uses: actions/cache@v2.1.2
-        env:
-          CACHE_NAME: 'libobs-cache'
+      - name: Build Plugin
+        uses: ././plugin/.github/actions/build-plugin
         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
+          workingDirectory: ${{ github.workspace }}/plugin
+          target: ${{ matrix.arch }}
+          config: RelWithDebInfo
+          codesign: ${{ env.HAVE_CODESIGN_IDENTITY }}
+
+      - name: Package Plugin
+        uses: ./plugin/.github/actions/package-plugin
+        with:
+          workingDirectory: ${{ github.workspace }}/plugin
+          target: ${{ matrix.arch }}
+          config: RelWithDebInfo
+
+      - name: Upload Build Artifact
+        if: ${{ success() && (github.event_name != 'pull_request' || steps.seekingTesters.outputs.found == 'true') }}
+        uses: actions/upload-artifact@v3
         with:
-          name: '${{ env.PRODUCT_NAME }}-linux-${{ matrix.arch }}'
-          path: '${{ github.workspace }}/plugin/*.deb'
+          name: ${{ env.PLUGIN_NAME }}-linux-${{ matrix.arch }}-${{ steps.setup.outputs.commitHash }}
+          path: ${{ github.workspace }}/plugin/release/${{ env.PLUGIN_NAME }}-*-Linux.*
 
   windows_build:
-    name: '02 - Windows (Latest)'
-    runs-on: [windows-latest]
-    needs: [clang_check]
-    if: always()
+    name: 02 - Windows
+    runs-on: windows-2022
     strategy:
       matrix:
-        arch: [64, 32]
-    env:
-      CMAKE_GENERATOR: "Visual Studio 16 2019"
-      CMAKE_SYSTEM_VERSION: "10.0.18363.657"
+        arch: ['x86', 'x64']
+    if: always()
+    needs: [clang_check]
+    outputs:
+      commitHash: ${{ steps.setup.outputs.commitHash }}
+    defaults:
+      run:
+        shell: pwsh
     steps:
-      - name: 'Add msbuild to PATH'
-        uses: microsoft/setup-msbuild@v1.0.2
-
-      - name: 'Checkout'
-        uses: actions/checkout@v2.3.3
+      - name: Checkout
+        uses: actions/checkout@v3
         with:
           path: 'plugin'
           submodules: 'recursive'
 
-      - name: 'Checkout'
-        uses: actions/checkout@v2.3.3
+      - name: Checkout obs-studio
+        uses: actions/checkout@v3
         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'
+      - name: Setup Environment
+        working-directory: ${{ github.workspace }}/plugin
+        id: setup
         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'
+          $CommitHash = git rev-parse --short HEAD
+          Write-Output "::set-output name=commitHash::${CommitHash}"
 
-      - name: 'Download 64-bit artifact'
-        uses: actions/download-artifact@v2
+      - name: Check for GitHub Labels
+        id: seekingTesters
+        working-directory: ${{ github.workspace }}/plugin
+        if: ${{ github.event_name == 'pull_request' }}
+        run: |
+          $LabelFound = try {
+            $Params = @{
+              Authentication = 'Bearer'
+              Token = (ConvertTo-SecureString '${{ secrets.GITHUB_TOKEN }}' -AsPlainText)
+              Uri = '${{ github.event.pull_request.url }}'
+              UseBasicParsing = $true
+            }
+
+            (Invoke-RestMethod @Params).labels.name.contains("Seeking Testers")
+          } catch {
+            $false
+          }
+
+          Write-Output "::set-output name=found::$(([string]${LabelFound}).ToLower())"
+
+      - name: Build Plugin
+        uses: ././plugin/.github/actions/build-plugin
         with:
-          name: '${{ env.PRODUCT_NAME }}-windows-64'
-          path: ${{ github.workspace }}
+          workingDirectory: ${{ github.workspace }}/plugin
+          target: ${{ matrix.arch }}
+          config: RelWithDebInfo
+          visualStudio: 'Visual Studio 17 2022'
 
-      - name: 'Download 32-bit artifact'
-        uses: actions/download-artifact@v2
+      - name: Package Plugin
+        uses: ./plugin/.github/actions/package-plugin
         with:
-          name: '${{ env.PRODUCT_NAME }}-windows-32'
-          path: ${{ github.workspace }}
+          workingDirectory: ${{ github.workspace }}/plugin
+          target: ${{ matrix.arch }}
+          config: RelWithDebInfo
 
-      - 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' || steps.seekingTesters.outputs.found == 'true') }}
+        uses: actions/upload-artifact@v3
+        with:
+          name: ${{ env.PLUGIN_NAME }}-windows-${{ matrix.arch }}-${{ steps.setup.outputs.commitHash }}
+          path: ${{ github.workspace }}/plugin/release/${{ env.PLUGIN_NAME }}-*.zip
 
-      - name: 'Upload build Artifact'
-        if: success() && (github.event_name != 'pull_request' || env.SEEKING_TESTERS == '1')
-        uses: actions/upload-artifact@v2
+      - name: Package Plugin Installer
+        if: ${{ startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' }}
+        uses: ././plugin/.github/actions/package-plugin
         with:
-          name: '${{ env.PRODUCT_NAME }}-windows-release'
-          path: '${{ github.workspace }}/plugin/*-Windows-Installer.exe'
+          workingDirectory: ${{ github.workspace }}/plugin
+          target: ${{ matrix.arch }}
+          config: RelWithDebInfo
+          createInstaller: 'true'
+
+      - name: Upload Installer Artifact
+        if: ${{ startsWith(github.ref, 'refs/tags/') && github.event_name != 'pull_request' }}
+        uses: actions/upload-artifact@v3
+        with:
+          name: ${{ env.PLUGIN_NAME }}-windows-${{ matrix.arch }}-${{ steps.setup.outputs.commitHash }}-installer
+          path: ${{ github.workspace }}/plugin/release/${{ env.PLUGIN_NAME }}-*.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'
+
+  make-release:
+    name: 03 - Create and upload release
+    runs-on: ubuntu-20.04
+    if: github.event_name == 'push' && contains(github.ref, 'refs/tags/')
+    needs: [macos_build, linux_build, windows_build]
     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: Get Metadata
+        id: metadata
+        run: |
+          echo "::set-output name=version::${GITHUB_REF/refs\/tags\//}"
+          echo "::set-output name=date::$(date +"%Y-%m-%d")"
+          echo '::set-output name=commitHash::${{ needs.macos_build.outputs.commitHash }}'
 
-      - name: 'Install prerequisite XCNotary'
-        if: env.HAVE_CODESIGN_IDENTITY == 'true'
-        run: brew bundle --file CI/include/Xcnotary
+      - name: Download build artifacts
+        uses: actions/download-artifact@v3
 
-      - 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: Generate Checksums
+        run: |
+          shopt -s extglob
+          echo "### Checksums" > ${{ github.workspace }}/CHECKSUMS.txt
+          for file in ${{ github.workspace }}/**/@(*.pkg|*.exe|*.deb|*.zip); do
+            echo "    ${file##*/}: $(sha256sum "${file}" | cut -d " " -f 1)" >> ${{ github.workspace }}/CHECKSUMS.txt
+          done
 
-      - name: 'Upload notarized installer package'
-        if: env.HAVE_CODESIGN_IDENTITY == 'true'
-        uses: actions/upload-artifact@v2
+      - name: Create Release
+        id: create_release
+        uses: softprops/action-gh-release@1e07f4398721186383de40550babbdf2b84acfc5
         with:
-          name: '${{ env.PRODUCT_NAME }}-macos-release'
-          path: '${{ github.workspace }}/plugin/*-macOS.pkg'
+          draft: false
+          prerelease: false
+          tag_name: ${{ steps.metadata.outputs.version }}
+          name: "${{ env.PLUGIN_NAME }} Build ${{ steps.metadata.outputs.version }}"
+          body_path: ${{ github.workspace }}/CHECKSUMS.txt
+          files: |
+            ${{ github.workspace }}/${{ env.PLUGIN_NAME }}-windows-x64-${{ steps.metadata.outputs.commitHash }}/*.zip
+            ${{ github.workspace }}/${{ env.PLUGIN_NAME }}-windows-x64-${{ steps.metadata.outputs.commitHash }}/*.exe
+            ${{ github.workspace }}/${{ env.PLUGIN_NAME }}-windows-x86-${{ steps.metadata.outputs.commitHash }}/*.zip
+            ${{ github.workspace }}/${{ env.PLUGIN_NAME }}-windows-x86-${{ steps.metadata.outputs.commitHash }}/*.exe
+            ${{ github.workspace }}/${{ env.PLUGIN_NAME }}-linux-x86_64-${{ steps.metadata.outputs.commitHash }}/*.deb
+            ${{ github.workspace }}/${{ env.PLUGIN_NAME }}-macos-x86_64-${{ steps.metadata.outputs.commitHash }}/*.pkg
+            ${{ github.workspace }}/${{ env.PLUGIN_NAME }}-macos-arm64-${{ steps.metadata.outputs.commitHash }}/*.pkg
+            ${{ github.workspace }}/${{ env.PLUGIN_NAME }}-macos-universal-${{ steps.metadata.outputs.commitHash }}/*.pkg

+ 2 - 2
.gitignore

@@ -1,8 +1,7 @@
 *~
 .DS_Store
 /build/
-/build32/
-/build64/
+/build_*/
 /release/
 /installer/Output/
 
@@ -11,3 +10,4 @@
 
 # ignore generated files
 *.generated.*
+**/.Brewfile.lock.json

+ 0 - 103
CI/build-linux.sh

@@ -1,103 +0,0 @@
-#!/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 $*

+ 0 - 129
CI/build-macos.sh

@@ -1,129 +0,0 @@
-#!/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 $*

+ 0 - 132
CI/build-windows.ps1

@@ -1,132 +0,0 @@
-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

+ 0 - 2
CI/include/Brewfile

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

+ 0 - 1
CI/include/Xcnotary

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

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

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

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

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

+ 0 - 229
CI/include/build_support.sh

@@ -1,229 +0,0 @@
-#!/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}"
-}

+ 0 - 33
CI/include/build_support_linux.sh

@@ -1,33 +0,0 @@
-#!/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

+ 0 - 149
CI/include/build_support_macos.sh

@@ -1,149 +0,0 @@
-#!/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")
-}

+ 0 - 139
CI/include/build_support_windows.ps1

@@ -1,139 +0,0 @@
-$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")
-}

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

@@ -1,127 +0,0 @@
-#!/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 $*

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

@@ -1,73 +0,0 @@
-#!/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 $*

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

@@ -1,66 +0,0 @@
-#!/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 $*

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

@@ -1,68 +0,0 @@
-#!/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 $*

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

@@ -1,120 +0,0 @@
-#!/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 $*

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

@@ -1,79 +0,0 @@
-#!/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 $*

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

@@ -1,85 +0,0 @@
-#!/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 $*

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

@@ -1,150 +0,0 @@
-#!/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 $*

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

@@ -1,158 +0,0 @@
-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
-}

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

@@ -1,102 +0,0 @@
-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
-}

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

@@ -1,92 +0,0 @@
-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
- }

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

@@ -1,141 +0,0 @@
-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
-}

+ 52 - 86
CMakeLists.txt

@@ -1,124 +1,90 @@
 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)
+# (e.g.: obs-myawesomeplugin) and set
+project(obs-plugintemplate VERSION 1.0.5)
 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)
+# to see as the author of the plugin (in the plugin's metadata itself and in the
+# installers)
 set(PLUGIN_AUTHOR "Your Name Here")
 
-# Replace `com.example.obs-plugin-template` with a unique Bundle ID for macOS releases
-# (used both in the installer and when submitting the installer for notarization)
-set(MACOS_BUNDLEID "com.example.obs-plugintemplate")
+# Replace `com.example.obs-plugin-template` with a unique Bundle ID for macOS
+# releases (used both in the installer and when submitting the installer for
+# notarization)
+set(MACOS_BUNDLEID "com.example.${CMAKE_PROJECT_NAME}")
 
-# Replace `me@contoso.com` with the maintainer email address you want to put in Linux packages
+# Replace `me@contoso.com` with the maintainer email address you want to put in
+# Linux packages
 set(LINUX_MAINTAINER_EMAIL "me@mymailhost.com")
 
-# 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)
+# 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)
 
 # /!\ TAKE NOTE: No need to edit things past this point /!\
 
 find_package(libobs REQUIRED)
 find_package(obs-frontend-api REQUIRED)
-include(external/ObsPluginHelpers.cmake)
-find_package(Qt5Core REQUIRED)
-find_package(Qt5Widgets REQUIRED)
+include(cmake/ObsPluginHelpers.cmake)
 
+configure_file(src/plugin-macros.h.in
+               ${CMAKE_SOURCE_DIR}/src/plugin-macros.generated.h)
 
-configure_file(
-	src/plugin-macros.h.in
-	${CMAKE_SOURCE_DIR}/src/plugin-macros.generated.h)
-
-target_sources(${CMAKE_PROJECT_NAME}
-	PRIVATE
-		src/plugin-macros.generated.h)
+target_sources(${CMAKE_PROJECT_NAME} PRIVATE src/plugin-macros.generated.h)
 
 # --- Platform-independent build settings ---
 
 target_include_directories(${CMAKE_PROJECT_NAME}
-	PRIVATE ${CMAKE_SOURCE_DIR}/src)
+                           PRIVATE ${CMAKE_SOURCE_DIR}/src)
 
-target_link_libraries(${CMAKE_PROJECT_NAME}
-	PRIVATE
-		OBS::libobs
-		OBS::obs-frontend-api
-		Qt5::Core
-		Qt5::Widgets)
+target_link_libraries(
+  ${CMAKE_PROJECT_NAME} PRIVATE OBS::libobs OBS::obs-frontend-api Qt5::Core
+                                Qt5::Widgets)
 
-set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES
-	AUTOMOC ON
-	AUTOUIC ON
-	AUTORCC ON)
+set_target_properties(
+  ${CMAKE_PROJECT_NAME}
+  PROPERTIES AUTOMOC ON
+             AUTOUIC ON
+             AUTORCC ON)
 
-target_compile_features(${CMAKE_PROJECT_NAME}
-	PRIVATE
-		cxx_std_17)
+target_compile_features(${CMAKE_PROJECT_NAME} PRIVATE cxx_std_17)
 
 # --- End of section ---
 
 # --- Windows-specific build settings and tasks ---
 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 ---
+  configure_file(cmake/bundle/windows/installer-Windows.iss.in
+                 ${CMAKE_BINARY_DIR}/installer-Windows.generated.iss)
 
-# -- macOS specific build settings and tasks --
+  if(MSVC)
+    target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE /MP /d2FH4-)
+  endif()
+  # --- End of section ---
+
+  # -- macOS specific build settings and tasks --
 elseif(OS_MACOS)
-	configure_file(
-		bundle/installer-macOS.pkgproj.in
-		${CMAKE_SOURCE_DIR}/bundle/installer-macOS.generated.pkgproj)
-
-	configure_file(
-		CI/include/build_environment.sh.in
-		${CMAKE_SOURCE_DIR}/CI/include/build_environment.sh
-	)
-
-	set(MACOSX_PLUGIN_GUI_IDENTIFIER "${MACOS_BUNDLEID}")
-	set(MACOSX_PLUGIN_BUNDLE_VERSION "${CMAKE_PROJECT_VERSION}")
-	set(MACOSX_PLUGIN_SHORT_VERSION_STRING "1")
-
-	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 "")
-# --- End of section ---
+  configure_file(cmake/bundle/macos/installer-macOS.pkgproj.in
+                 ${CMAKE_BINARY_DIR}/installer-macOS.generated.pkgproj)
 
-# --- Linux-specific build settings and tasks ---
-else()
-	configure_file(
-		CI/include/build_environment.sh.in
-		${CMAKE_SOURCE_DIR}/CI/include/build_environment.sh
-	)
+  set(MACOSX_PLUGIN_GUI_IDENTIFIER "${MACOS_BUNDLEID}")
+  set(MACOSX_PLUGIN_BUNDLE_VERSION "${CMAKE_PROJECT_VERSION}")
+  set(MACOSX_PLUGIN_SHORT_VERSION_STRING "1")
+
+  target_compile_options(
+    ${CMAKE_PROJECT_NAME}
+    PRIVATE -Wall -Wextra -Werror-implicit-function-declaration -stdlib=libc++
+            -fvisibility=default)
 
-	target_compile_options(${CMAKE_PROJECT_NAME}
-		PRIVATE
-			-Wall
-			-Wextra)
+  set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES PREFIX "")
+  # --- End of section ---
+
+  # --- Linux-specific build settings and tasks ---
+else()
+  target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE -Wall -Wextra)
 
-	set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES PREFIX "")
+  set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES PREFIX "")
 endif()
 # --- End of section ---
 

+ 11 - 15
README.md

@@ -6,40 +6,36 @@ This plugin is meant to make it easy to quickstart development of new OBS plugin
 
 - The CMake project file
 - Boilerplate plugin source code
-- A continuous-integration configuration for automated builds (a.k.a Build Bot)
+- GitHub Actions workflows and repository actions
+- Build scripts for Windows, macOS, and Linux
 
 ## Configuring
 
-Open `CMakeLists.txt` and edit the following lines at the beginning:
+Open `buildspec.json` and change the name and version of the plugin accordingly. This is also where the obs-studio version as well as the pre-built dependencies for Windows and macOS are defined. Use a release version (with associated checksums) from a recent [obs-deps release](https://github.com/obsproject/obs-deps/releases).
+
+Next, open `CMakeLists.txt` and edit the following lines at the beginning:
 
 ```cmake
-# Change `obs-plugintemplate` to your plugin's name in a machine-readable format
-# (e.g.: obs-myawesomeplugin) and set the value next to `VERSION` as your plugin's current version
 project(obs-plugintemplate VERSION 1.0.0)
 
-# 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)
 set(PLUGIN_AUTHOR "Your Name Here")
 
-# Replace `com.example.obs-plugin-template` with a unique Bundle ID for macOS releases
-# (used both in the installer and when submitting the installer for notarization)
-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")
 ```
 
-## CI / Build Bot
+The build scripts (contained in the `.github/scripts` directory) will update the `project` line automatically based on values from the `buildspec.json` file. If the scripts are not used, these changes need to be done manually.
+
+## GitHub Actions & CI
 
-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.
+The scripts contained in `github/scripts` can be used to build and package the plugin and take care of setting up obs-studio as well as its own dependencies. A default workflow for GitHub Actions is also provided and will use these scripts.
 
 ### Retrieving build artifacts
 
-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.
+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 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.
+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
 

+ 56 - 0
buildspec.json

@@ -0,0 +1,56 @@
+{
+    "dependencies": {
+        "obs-studio": {
+            "version": "27.2.3",
+            "repository": "https://github.com/obsproject/obs-studio.git",
+            "branch": "master",
+            "hash": "13f2d7925ff49938e3b286a3b9a65d50c1491ec1"
+        },
+        "obs-deps": {
+            "macos-x86_64": {
+                "version": "2022-02-13",
+                "hash": "1a8715d66e664b857942deaded0dc46c4f6cd22e88f01ed1188f3bd3fcf632c4"
+            },
+            "macos-arm64": {
+                "version": "2022-02-13",
+                "hash": "2cfcaf05765400c696908f242aea87b6e1848e1a48cd3edc2eb7f8cb249c9d48"
+            },
+            "macos-universal": {
+                "version": "2022-02-13",
+                "hash": "77471b1d345a768e8efec3f6ad9dc79f3c7cd34840b66f721b80025d29713f5d"
+            },
+            "windows-x64": {
+                "version": "2022-03-16",
+                "hash": "ed73757d1faee1b8c4a9aeca539e1149704e430085608990771402e60074eec7"
+            },
+            "windows-x86": {
+                "version": "2022-03-16",
+                "hash": "4751f68488cf6d5dcc79fbf6735762154847ca509d669539b241bf4e5cbf7751"
+            }
+        },
+        "obs-deps-qt": {
+            "macos-x86_64": {
+                "version": "2022-02-13",
+                "hash": "35a58fee8dfd70d3d2dcc0ae0b77132c04a451c6f041a02dc41b207b375fc74b"
+            },
+            "macos-arm64": {
+                "version": "2022-02-13",
+                "hash": "e99146b9c7775c245a2d22f2ef24fc111fccd71bad0f03b64db707124ffb8707"
+            },
+            "macos-universal": {
+                "version": "2022-02-13",
+                "hash": "13fbcc45fd9d08b30e702d481fe4d58b23f93aa06848cede4ebe0956c79a5e8a"
+            },
+            "windows-x64": {
+                "version": "2022-03-16",
+                "hash": "4a5faed9bad327be079e08ed6715a287db8936d20e51b9cdfc7eb52d0a57c629"
+            },
+            "windows-x86": {
+                "version": "2022-03-16",
+                "hash": "6664bc60523a8c7c08690f6b800d8d57d830605b9c25d2ce41132c422b0c6e29"
+            }
+        }
+    },
+    "name": "obs-plugintemplate",
+    "version": "1.0.0"
+}

+ 444 - 0
cmake/ObsPluginHelpers.cmake

@@ -0,0 +1,444 @@
+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()
+
+if(NOT QT_VERSION)
+  set(QT_VERSION
+      "5"
+      CACHE STRING "OBS Qt version [5, 6]" FORCE)
+  set_property(CACHE QT_VERSION PROPERTY STRINGS 5 6)
+endif()
+
+macro(find_qt)
+  set(oneValueArgs VERSION)
+  set(multiValueArgs COMPONENTS COMPONENTS_WIN COMPONENTS_MAC COMPONENTS_LINUX)
+  cmake_parse_arguments(FIND_QT "" "${oneValueArgs}" "${multiValueArgs}"
+                        ${ARGN})
+
+  if(OS_WINDOWS)
+    find_package(
+      Qt${FIND_QT_VERSION}
+      COMPONENTS ${FIND_QT_COMPONENTS} ${FIND_QT_COMPONENTS_WIN}
+      REQUIRED)
+  elseif(OS_MACOS)
+    find_package(
+      Qt${FIND_QT_VERSION}
+      COMPONENTS ${FIND_QT_COMPONENTS} ${FIND_QT_COMPONENTS_MAC}
+      REQUIRED)
+  else()
+    find_package(
+      Qt${FIND_QT_VERSION}
+      COMPONENTS ${FIND_QT_COMPONENTS} ${FIND_QT_COMPONENTS_LINUX}
+      REQUIRED)
+  endif()
+
+  foreach(_COMPONENT IN LISTS FIND_QT_COMPONENTS FIND_QT_COMPONENTS_WIN
+                              FIND_QT_COMPONENTS_MAC FIND_QT_COMPONENTS_LINUX)
+    if(NOT TARGET Qt::${_COMPONENT} AND TARGET
+                                        Qt${FIND_QT_VERSION}::${_COMPONENT})
+
+      add_library(Qt::${_COMPONENT} INTERFACE IMPORTED)
+      set_target_properties(
+        Qt::${_COMPONENT} PROPERTIES INTERFACE_LINK_LIBRARIES
+                                     "Qt${FIND_QT_VERSION}::${_COMPONENT}")
+    endif()
+  endforeach()
+endmacro()
+
+find_qt(VERSION ${QT_VERSION} COMPONENTS Widgets Core)
+
+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)
+  find_program(CCACHE_PROGRAM "ccache")
+  set(CCACHE_SUPPORT
+      ON
+      CACHE BOOL "Enable ccache support")
+  mark_as_advanced(CCACHE_PROGRAM)
+  if(CCACHE_PROGRAM AND CCACHE_SUPPORT)
+    set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
+    set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
+    set(CMAKE_OBJC_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
+    set(CMAKE_OBJCXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
+    set(CMAKE_CUDA_COMPILER_LAUNCHER ${CCACHE_PROGRAM}) # CMake 3.9+
+  endif()
+
+  set(CMAKE_OSX_ARCHITECTURES
+      "x86_64"
+      CACHE STRING
+            "OBS build architecture for macOS - x86_64 required at least")
+  set_property(CACHE CMAKE_OSX_ARCHITECTURES PROPERTY STRINGS x86_64 arm64
+                                                      "x86_64;arm64")
+
+  set(CMAKE_OSX_DEPLOYMENT_TARGET
+      "10.13"
+      CACHE STRING "OBS deployment target for macOS - 10.15+ required")
+  set_property(CACHE CMAKE_OSX_DEPLOYMENT_TARGET PROPERTY STRINGS 10.15 11 12)
+
+  set(OBS_BUNDLE_CODESIGN_IDENTITY
+      "-"
+      CACHE STRING "OBS code signing identity for macOS")
+  set(OBS_CODESIGN_ENTITLEMENTS
+      ${CMAKE_SOURCE_DIR}/cmake/bundle/macos/entitlements.plist
+      CACHE INTERNAL "Path to codesign entitlements plist")
+  set(OBS_CODESIGN_LINKER
+      ON
+      CACHE BOOL "Enable linker code-signing on macOS (macOS 11+ required)")
+
+  # Xcode configuration
+  if(XCODE)
+    # Tell Xcode to pretend the linker signed binaries so that editing with
+    # install_name_tool preserves ad-hoc signatures. This option is supported by
+    # codesign on macOS 11 or higher. See CMake Issue 21854:
+    # https://gitlab.kitware.com/cmake/cmake/-/issues/21854
+
+    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)
+
+    set(_COMMAND
+        "${CMAKE_INSTALL_NAME_TOOL} \\
+      -change ${CMAKE_PREFIX_PATH}/lib/QtWidgets.framework/Versions/${QT_VERSION}/QtWidgets @rpath/QtWidgets.framework/Versions/${QT_VERSION}/QtWidgets \\
+      -change ${CMAKE_PREFIX_PATH}/lib/QtCore.framework/Versions/${QT_VERSION}/QtCore @rpath/QtCore.framework/Versions/${QT_VERSION}/QtCore \\
+      -change ${CMAKE_PREFIX_PATH}/lib/QtGui.framework/Versions/${QT_VERSION}/QtGui @rpath/QtGui.framework/Versions/${QT_VERSION}/QtGui \\
+      \\\"\${CMAKE_INSTALL_PREFIX}/${target}.plugin/Contents/MacOS/${target}\\\""
+    )
+    install(CODE "execute_process(COMMAND /bin/sh -c \"${_COMMAND}\")"
+            COMPONENT obs_plugins)
+
+    if(NOT XCODE)
+      set(_COMMAND
+          "/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\\\"")
+      install(CODE "execute_process(COMMAND /bin/sh -c \"${_COMMAND}\")"
+              COMPONENT obs_plugins)
+    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)
+    find_program(CCACHE_PROGRAM "ccache")
+    set(CCACHE_SUPPORT
+        ON
+        CACHE BOOL "Enable ccache support")
+    mark_as_advanced(CCACHE_PROGRAM)
+    if(CCACHE_PROGRAM AND CCACHE_SUPPORT)
+      set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
+      set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
+      set(CMAKE_OBJC_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
+      set(CMAKE_OBJCXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM})
+      set(CMAKE_CUDA_COMPILER_LAUNCHER ${CCACHE_PROGRAM}) # CMake 3.9+
+    endif()
+
+    option(LINUX_PORTABLE "Build portable version (Linux)" OFF)
+    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)"
+      )
+
+      set(CPACK_OUTPUT_FILE_PREFIX ${CMAKE_SOURCE_DIR}/release)
+
+      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)
+
+    install(
+      FILES $<TARGET_FILE:${target}>
+      DESTINATION $<CONFIG>/${OBS_PLUGIN_DESTINATION}
+      COMPONENT obs_rundir
+      EXCLUDE_FROM_ALL)
+
+    if(OS_WINDOWS)
+      install(
+        FILES $<TARGET_PDB_FILE:${target}>
+        CONFIGURATIONS "RelWithDebInfo" "Debug"
+        DESTINATION ${OBS_PLUGIN_DESTINATION}
+        COMPONENT ${target}_Runtime
+        OPTIONAL)
+
+      install(
+        FILES $<TARGET_PDB_FILE:${target}>
+        CONFIGURATIONS "RelWithDebInfo" "Debug"
+        DESTINATION $<CONFIG>/${OBS_PLUGIN_DESTINATION}
+        COMPONENT obs_rundir
+        OPTIONAL EXCLUDE_FROM_ALL)
+    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} obs-plugins/${target})
+    endif()
+
+    add_custom_command(
+      TARGET ${target}
+      POST_BUILD
+      COMMAND
+        "${CMAKE_COMMAND}" -DCMAKE_INSTALL_PREFIX=${OBS_OUTPUT_DIR}
+        -DCMAKE_INSTALL_COMPONENT=obs_rundir
+        -DCMAKE_INSTALL_CONFIG_NAME=$<CONFIG> -P
+        ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake
+      COMMENT "Installing to plugin rundir"
+      VERBATIM)
+  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
+        COMPONENT obs_plugins)
+
+      install(
+        DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data
+        DESTINATION $<CONFIG>/${OBS_DATA_DESTINATION}/${destination}
+        USE_SOURCE_PERMISSIONS
+        COMPONENT obs_rundir
+        EXCLUDE_FROM_ALL)
+    endif()
+  endfunction()
+
+  if(OS_WINDOWS)
+    function(setup_target_for_testing target destination)
+      install(
+        FILES $<TARGET_FILE:${target}>
+        DESTINATION $<CONFIG>/${OBS_PLUGIN_DESTINATION}
+        COMPONENT obs_testing
+        EXCLUDE_FROM_ALL)
+
+      install(
+        FILES $<TARGET_PDB_FILE:${target}>
+        CONFIGURATIONS "RelWithDebInfo" "Debug"
+        DESTINATION $<CONFIG>/${OBS_PLUGIN_DESTINATION}
+        COMPONENT obs_testing
+        OPTIONAL EXCLUDE_FROM_ALL)
+
+      install(
+        DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data/
+        DESTINATION $<CONFIG>/${OBS_DATA_DESTINATION}/${destination}
+        USE_SOURCE_PERMISSIONS
+        COMPONENT obs_testing
+        EXCLUDE_FROM_ALL)
+
+      add_custom_command(
+        TARGET ${target}
+        POST_BUILD
+        COMMAND
+          "${CMAKE_COMMAND}" -DCMAKE_INSTALL_PREFIX=${OBS_BUILD_DIR}/rundir
+          -DCMAKE_INSTALL_COMPONENT=obs_testing
+          -DCMAKE_INSTALL_CONFIG_NAME=$<CONFIG> -P
+          ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake
+        COMMENT "Installing to OBS test directory"
+        VERBATIM)
+    endfunction()
+  endif()
+endif()

+ 0 - 0
bundle/macOS/Plugin-Info.plist.in → cmake/bundle/macos/Plugin-Info.plist.in


+ 0 - 0
bundle/macOS/entitlements.plist → cmake/bundle/macos/entitlements.plist


+ 0 - 0
bundle/installer-macOS.pkgproj.in → cmake/bundle/macos/installer-macOS.pkgproj.in


+ 0 - 0
installer/installer-Windows.iss.in → cmake/bundle/windows/installer-Windows.iss.in


+ 0 - 274
external/ObsPluginHelpers.cmake

@@ -1,274 +0,0 @@
-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()

+ 4 - 3
src/plugin-main.c

@@ -25,11 +25,12 @@ OBS_MODULE_USE_DEFAULT_LOCALE(PLUGIN_NAME, "en-US")
 
 bool obs_module_load(void)
 {
-    blog(LOG_INFO, "plugin loaded successfully (version %s)", PLUGIN_VERSION);
-    return true;
+	blog(LOG_INFO, "plugin loaded successfully (version %s)",
+	     PLUGIN_VERSION);
+	return true;
 }
 
 void obs_module_unload()
 {
-    blog(LOG_INFO, "plugin unloaded");
+	blog(LOG_INFO, "plugin unloaded");
 }