├── .clang-format ├── .cmake-format.json ├── .github ├── actions │ ├── build-plugin │ │ └── action.yaml │ ├── package-plugin │ │ └── action.yaml │ ├── run-clang-format │ │ └── action.yaml │ ├── run-cmake-format │ │ └── action.yaml │ └── setup-macos-codesigning │ │ └── action.yaml ├── scripts │ ├── .Aptfile │ ├── .Brewfile │ ├── .Wingetfile │ ├── .build.zsh │ ├── .package.zsh │ ├── Build-Windows.ps1 │ ├── Package-Windows.ps1 │ ├── build-linux │ ├── build-macos │ ├── package-linux │ ├── package-macos │ ├── utils.pwsh │ │ ├── Ensure-Location.ps1 │ │ ├── Expand-ArchiveExt.ps1 │ │ ├── Install-BuildDependencies.ps1 │ │ ├── Invoke-External.ps1 │ │ └── Logger.ps1 │ └── utils.zsh │ │ ├── check_linux │ │ ├── check_macos │ │ ├── log_debug │ │ ├── log_error │ │ ├── log_group │ │ ├── log_info │ │ ├── log_output │ │ ├── log_status │ │ ├── log_warning │ │ ├── mkcd │ │ ├── read_codesign │ │ ├── read_codesign_installer │ │ ├── read_codesign_pass │ │ ├── read_codesign_team │ │ ├── read_codesign_user │ │ ├── set_loglevel │ │ ├── setup_ccache │ │ └── setup_linux └── workflows │ ├── build-project.yaml │ ├── check-format.yaml │ ├── dispatch.yaml │ ├── pr-pull.yaml │ └── push.yaml ├── .gitignore ├── CMakeLists.txt ├── CMakePresets.json ├── LICENSE ├── README.md ├── build-aux ├── .functions │ ├── log_debug │ ├── log_error │ ├── log_group │ ├── log_info │ ├── log_output │ ├── log_status │ ├── log_warning │ └── set_loglevel ├── .run-format.zsh ├── run-clang-format ├── run-cmake-format └── run-swift-format ├── buildspec.json ├── cmake ├── common │ ├── bootstrap.cmake │ ├── buildnumber.cmake │ ├── buildspec_common.cmake │ ├── ccache.cmake │ ├── compiler_common.cmake │ ├── helpers_common.cmake │ └── osconfig.cmake ├── linux │ ├── compilerconfig.cmake │ ├── defaults.cmake │ ├── helpers.cmake │ └── toolchains │ │ ├── aarch64-linux-clang.cmake │ │ ├── aarch64-linux-gcc.cmake │ │ ├── x86_64-linux-clang.cmake │ │ └── x86_64-linux-gcc.cmake ├── macos │ ├── buildspec.cmake │ ├── compilerconfig.cmake │ ├── defaults.cmake │ ├── helpers.cmake │ ├── resources │ │ ├── ccache-launcher-c.in │ │ ├── ccache-launcher-cxx.in │ │ ├── create-package.cmake.in │ │ ├── distribution.in │ │ └── installer-macos.pkgproj.in │ └── xcode.cmake └── windows │ ├── buildspec.cmake │ ├── compilerconfig.cmake │ ├── defaults.cmake │ ├── helpers.cmake │ └── resources │ ├── installer-Windows.iss.in │ └── resource.rc.in ├── data └── default_move.effect └── src └── scale-to-sound.c /.clang-format: -------------------------------------------------------------------------------- 1 | # please use clang-format version 16 or later 2 | 3 | Standard: c++17 4 | AccessModifierOffset: -8 5 | AlignAfterOpenBracket: Align 6 | AlignConsecutiveAssignments: false 7 | AlignConsecutiveDeclarations: false 8 | AlignEscapedNewlines: Left 9 | AlignOperands: true 10 | AlignTrailingComments: true 11 | AllowAllArgumentsOnNextLine: false 12 | AllowAllConstructorInitializersOnNextLine: false 13 | AllowAllParametersOfDeclarationOnNextLine: false 14 | AllowShortBlocksOnASingleLine: false 15 | AllowShortCaseLabelsOnASingleLine: false 16 | AllowShortFunctionsOnASingleLine: Inline 17 | AllowShortIfStatementsOnASingleLine: false 18 | AllowShortLambdasOnASingleLine: Inline 19 | AllowShortLoopsOnASingleLine: false 20 | AlwaysBreakAfterDefinitionReturnType: None 21 | AlwaysBreakAfterReturnType: None 22 | AlwaysBreakBeforeMultilineStrings: false 23 | AlwaysBreakTemplateDeclarations: false 24 | BinPackArguments: true 25 | BinPackParameters: true 26 | BraceWrapping: 27 | AfterClass: false 28 | AfterControlStatement: false 29 | AfterEnum: false 30 | AfterFunction: true 31 | AfterNamespace: false 32 | AfterObjCDeclaration: false 33 | AfterStruct: false 34 | AfterUnion: false 35 | AfterExternBlock: false 36 | BeforeCatch: false 37 | BeforeElse: false 38 | IndentBraces: false 39 | SplitEmptyFunction: true 40 | SplitEmptyRecord: true 41 | SplitEmptyNamespace: true 42 | BreakBeforeBinaryOperators: None 43 | BreakBeforeBraces: Custom 44 | BreakBeforeTernaryOperators: true 45 | BreakConstructorInitializers: BeforeColon 46 | BreakStringLiterals: false # apparently unpredictable 47 | ColumnLimit: 80 48 | CompactNamespaces: false 49 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 50 | ConstructorInitializerIndentWidth: 8 51 | ContinuationIndentWidth: 8 52 | Cpp11BracedListStyle: true 53 | DerivePointerAlignment: false 54 | DisableFormat: false 55 | FixNamespaceComments: true 56 | ForEachMacros: 57 | - 'json_object_foreach' 58 | - 'json_object_foreach_safe' 59 | - 'json_array_foreach' 60 | - 'HASH_ITER' 61 | IncludeBlocks: Preserve 62 | IndentCaseLabels: false 63 | IndentPPDirectives: None 64 | IndentWidth: 8 65 | IndentWrappedFunctionNames: false 66 | KeepEmptyLinesAtTheStartOfBlocks: true 67 | MaxEmptyLinesToKeep: 1 68 | NamespaceIndentation: None 69 | ObjCBinPackProtocolList: Auto 70 | ObjCBlockIndentWidth: 8 71 | ObjCSpaceAfterProperty: true 72 | ObjCSpaceBeforeProtocolList: true 73 | 74 | PenaltyBreakAssignment: 10 75 | PenaltyBreakBeforeFirstCallParameter: 30 76 | PenaltyBreakComment: 10 77 | PenaltyBreakFirstLessLess: 0 78 | PenaltyBreakString: 10 79 | PenaltyExcessCharacter: 100 80 | PenaltyReturnTypeOnItsOwnLine: 60 81 | 82 | PointerAlignment: Right 83 | ReflowComments: false 84 | SortIncludes: false 85 | SortUsingDeclarations: false 86 | SpaceAfterCStyleCast: false 87 | SpaceAfterLogicalNot: false 88 | SpaceAfterTemplateKeyword: false 89 | SpaceBeforeAssignmentOperators: true 90 | SpaceBeforeCtorInitializerColon: true 91 | SpaceBeforeInheritanceColon: true 92 | SpaceBeforeParens: ControlStatements 93 | SpaceBeforeRangeBasedForLoopColon: true 94 | SpaceInEmptyParentheses: false 95 | SpacesBeforeTrailingComments: 1 96 | SpacesInAngles: false 97 | SpacesInCStyleCastParentheses: false 98 | SpacesInContainerLiterals: false 99 | SpacesInParentheses: false 100 | SpacesInSquareBrackets: false 101 | StatementMacros: 102 | - 'Q_OBJECT' 103 | TabWidth: 8 104 | TypenameMacros: 105 | - 'DARRAY' 106 | UseTab: ForContinuationAndIndentation 107 | --- 108 | Language: ObjC 109 | AccessModifierOffset: 2 110 | AlignArrayOfStructures: Right 111 | AlignConsecutiveAssignments: None 112 | AlignConsecutiveBitFields: None 113 | AlignConsecutiveDeclarations: None 114 | AlignConsecutiveMacros: 115 | Enabled: true 116 | AcrossEmptyLines: false 117 | AcrossComments: true 118 | AllowShortBlocksOnASingleLine: Never 119 | AllowShortEnumsOnASingleLine: false 120 | AllowShortFunctionsOnASingleLine: Empty 121 | AllowShortIfStatementsOnASingleLine: Never 122 | AllowShortLambdasOnASingleLine: None 123 | AttributeMacros: ['__unused', '__autoreleasing', '_Nonnull', '__bridge'] 124 | BitFieldColonSpacing: Both 125 | #BreakBeforeBraces: Webkit 126 | BreakBeforeBraces: Custom 127 | BraceWrapping: 128 | AfterCaseLabel: false 129 | AfterClass: true 130 | AfterControlStatement: Never 131 | AfterEnum: false 132 | AfterFunction: true 133 | AfterNamespace: false 134 | AfterObjCDeclaration: false 135 | AfterStruct: false 136 | AfterUnion: false 137 | AfterExternBlock: false 138 | BeforeCatch: false 139 | BeforeElse: false 140 | BeforeLambdaBody: false 141 | BeforeWhile: false 142 | IndentBraces: false 143 | SplitEmptyFunction: false 144 | SplitEmptyRecord: false 145 | SplitEmptyNamespace: true 146 | BreakAfterAttributes: Never 147 | BreakArrays: false 148 | BreakBeforeConceptDeclarations: Allowed 149 | BreakBeforeInlineASMColon: OnlyMultiline 150 | BreakConstructorInitializers: AfterColon 151 | BreakInheritanceList: AfterComma 152 | ColumnLimit: 120 153 | ConstructorInitializerIndentWidth: 4 154 | ContinuationIndentWidth: 4 155 | EmptyLineAfterAccessModifier: Never 156 | EmptyLineBeforeAccessModifier: LogicalBlock 157 | ExperimentalAutoDetectBinPacking: false 158 | FixNamespaceComments: true 159 | IndentAccessModifiers: false 160 | IndentCaseBlocks: false 161 | IndentCaseLabels: true 162 | IndentExternBlock: Indent 163 | IndentGotoLabels: false 164 | IndentRequiresClause: true 165 | IndentWidth: 4 166 | IndentWrappedFunctionNames: true 167 | InsertBraces: false 168 | InsertNewlineAtEOF: true 169 | KeepEmptyLinesAtTheStartOfBlocks: false 170 | LambdaBodyIndentation: Signature 171 | NamespaceIndentation: All 172 | ObjCBinPackProtocolList: Auto 173 | ObjCBlockIndentWidth: 4 174 | ObjCBreakBeforeNestedBlockParam: false 175 | ObjCSpaceAfterProperty: true 176 | ObjCSpaceBeforeProtocolList: true 177 | PPIndentWidth: -1 178 | PackConstructorInitializers: NextLine 179 | QualifierAlignment: Leave 180 | ReferenceAlignment: Right 181 | RemoveSemicolon: false 182 | RequiresClausePosition: WithPreceding 183 | RequiresExpressionIndentation: OuterScope 184 | SeparateDefinitionBlocks: Always 185 | ShortNamespaceLines: 1 186 | SortIncludes: false 187 | #SortUsingDeclarations: LexicographicNumeric 188 | SortUsingDeclarations: true 189 | SpaceAfterCStyleCast: true 190 | SpaceAfterLogicalNot: false 191 | SpaceAroundPointerQualifiers: Default 192 | SpaceBeforeCaseColon: false 193 | SpaceBeforeCpp11BracedList: true 194 | SpaceBeforeCtorInitializerColon: true 195 | SpaceBeforeInheritanceColon: true 196 | SpaceBeforeParens: ControlStatements 197 | SpaceBeforeRangeBasedForLoopColon: true 198 | SpaceBeforeSquareBrackets: false 199 | SpaceInEmptyBlock: false 200 | SpaceInEmptyParentheses: false 201 | SpacesBeforeTrailingComments: 2 202 | SpacesInConditionalStatement: false 203 | SpacesInLineCommentPrefix: 204 | Minimum: 1 205 | Maximum: -1 206 | Standard: c++17 207 | TabWidth: 4 208 | UseTab: Never 209 | -------------------------------------------------------------------------------- /.cmake-format.json: -------------------------------------------------------------------------------- 1 | { 2 | "format": { 3 | "line_width": 120, 4 | "tab_size": 2, 5 | "enable_sort": true, 6 | "autosort": true 7 | }, 8 | "additional_commands": { 9 | "find_qt": { 10 | "flags": [], 11 | "kwargs": { 12 | "COMPONENTS": "+", 13 | "COMPONENTS_WIN": "+", 14 | "COMPONENTS_MACOS": "+", 15 | "COMPONENTS_LINUX": "+" 16 | } 17 | }, 18 | "set_target_properties_obs": { 19 | "pargs": 1, 20 | "flags": [], 21 | "kwargs": { 22 | "PROPERTIES": { 23 | "kwargs": { 24 | "PREFIX": 1, 25 | "OUTPUT_NAME": 1, 26 | "FOLDER": 1, 27 | "VERSION": 1, 28 | "SOVERSION": 1, 29 | "AUTOMOC": 1, 30 | "AUTOUIC": 1, 31 | "AUTORCC": 1, 32 | "AUTOUIC_SEARCH_PATHS": 1, 33 | "BUILD_RPATH": 1, 34 | "INSTALL_RPATH": 1 35 | } 36 | } 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /.github/actions/build-plugin/action.yaml: -------------------------------------------------------------------------------- 1 | name: 'Set up and build plugin' 2 | description: 'Builds the plugin for specified architecture and build config' 3 | inputs: 4 | target: 5 | description: 'Target architecture for dependencies' 6 | required: true 7 | config: 8 | description: 'Build configuration' 9 | required: false 10 | default: 'RelWithDebInfo' 11 | codesign: 12 | description: 'Enable codesigning (macOS only)' 13 | required: false 14 | default: 'false' 15 | codesignIdent: 16 | description: 'Developer ID for application codesigning (macOS only)' 17 | required: false 18 | default: '-' 19 | workingDirectory: 20 | description: 'Working directory for packaging' 21 | required: false 22 | default: ${{ github.workspace }} 23 | runs: 24 | using: composite 25 | steps: 26 | - name: Run macOS Build 27 | if: runner.os == 'macOS' 28 | shell: zsh --no-rcs --errexit --pipefail {0} 29 | working-directory: ${{ inputs.workingDirectory }} 30 | env: 31 | CODESIGN_IDENT: ${{ inputs.codesignIdent }} 32 | CODESIGN_TEAM: ${{ inputs.codesignTeam }} 33 | run: | 34 | : Run macOS Build 35 | 36 | local -a build_args=(--config ${{ inputs.config }}) 37 | if (( ${+RUNNER_DEBUG} )) build_args+=(--debug) 38 | 39 | if [[ '${{ inputs.codesign }}' == 'true' ]] build_args+=(--codesign) 40 | 41 | .github/scripts/build-macos ${build_args} 42 | 43 | - name: Install Dependencies 🛍️ 44 | if: runner.os == 'Linux' 45 | shell: bash 46 | run: | 47 | : Install Dependencies 🛍️ 48 | echo ::group::Install Dependencies 49 | eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" 50 | echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH 51 | brew install --quiet zsh 52 | echo ::endgroup:: 53 | 54 | - name: Run Ubuntu Build 55 | if: runner.os == 'Linux' 56 | shell: zsh --no-rcs --errexit --pipefail {0} 57 | working-directory: ${{ inputs.workingDirectory }} 58 | run: | 59 | : Run Ubuntu Build 60 | 61 | local -a build_args=( 62 | --target linux-${{ inputs.target }} 63 | --config ${{ inputs.config }} 64 | ) 65 | if (( ${+RUNNER_DEBUG} )) build_args+=(--debug) 66 | 67 | .github/scripts/build-linux ${build_args} 68 | 69 | - name: Run Windows Build 70 | if: runner.os == 'Windows' 71 | shell: pwsh 72 | run: | 73 | # Run Windows Build 74 | if ( $Env:RUNNER_DEBUG -ne $null ) { 75 | Set-PSDebug -Trace 1 76 | } 77 | 78 | $BuildArgs = @{ 79 | Target = '${{ inputs.target }}' 80 | Configuration = '${{ inputs.config }}' 81 | } 82 | 83 | .github/scripts/Build-Windows.ps1 @BuildArgs 84 | 85 | - name: Create Summary 📊 86 | if: contains(fromJSON('["Linux", "macOS"]'),runner.os) 87 | shell: zsh --no-rcs --errexit --pipefail {0} 88 | env: 89 | CCACHE_CONFIGPATH: ${{ inputs.workingDirectory }}/.ccache.conf 90 | run: | 91 | : Create Summary 📊 92 | 93 | local -a ccache_data 94 | if (( ${+RUNNER_DEBUG} )) { 95 | setopt XTRACE 96 | ccache_data=("${(fA)$(ccache -s -vv)}") 97 | } else { 98 | ccache_data=("${(fA)$(ccache -s)}") 99 | } 100 | 101 | print '### ${{ runner.os }} Ccache Stats (${{ inputs.target }})' >> $GITHUB_STEP_SUMMARY 102 | print '```' >> $GITHUB_STEP_SUMMARY 103 | for line (${ccache_data}) { 104 | print ${line} >> $GITHUB_STEP_SUMMARY 105 | } 106 | print '```' >> $GITHUB_STEP_SUMMARY 107 | -------------------------------------------------------------------------------- /.github/actions/package-plugin/action.yaml: -------------------------------------------------------------------------------- 1 | name: 'Package plugin' 2 | description: 'Packages the plugin for specified architecture and build config.' 3 | inputs: 4 | target: 5 | description: 'Build target for dependencies' 6 | required: true 7 | config: 8 | description: 'Build configuration' 9 | required: false 10 | default: 'RelWithDebInfo' 11 | codesign: 12 | description: 'Enable codesigning (macOS only)' 13 | required: false 14 | default: 'false' 15 | notarize: 16 | description: 'Enable notarization (macOS only)' 17 | required: false 18 | default: 'false' 19 | codesignIdent: 20 | description: 'Developer ID for application codesigning (macOS only)' 21 | required: false 22 | default: '-' 23 | installerIdent: 24 | description: 'Developer ID for installer package codesigning (macOS only)' 25 | required: false 26 | default: '' 27 | codesignTeam: 28 | description: 'Developer team for codesigning (macOS only)' 29 | required: false 30 | default: '' 31 | codesignUser: 32 | description: 'Apple ID username for notarization (macOS only)' 33 | required: false 34 | default: '' 35 | codesignPass: 36 | description: 'Apple ID password for notarization (macOS only)' 37 | required: false 38 | default: '' 39 | package: 40 | description: 'Create Windows or macOS installation package' 41 | required: false 42 | default: 'false' 43 | workingDirectory: 44 | description: 'Working directory for packaging' 45 | required: false 46 | default: ${{ github.workspace }} 47 | runs: 48 | using: composite 49 | steps: 50 | - name: Run macOS Packaging 51 | if: runner.os == 'macOS' 52 | shell: zsh --no-rcs --errexit --pipefail {0} 53 | working-directory: ${{ inputs.workingDirectory }} 54 | env: 55 | CODESIGN_IDENT: ${{ inputs.codesignIdent }} 56 | CODESIGN_IDENT_INSTALLER: ${{ inputs.installerIdent }} 57 | CODESIGN_TEAM: ${{ inputs.codesignTeam }} 58 | CODESIGN_IDENT_USER: ${{ inputs.codesignUser }} 59 | CODESIGN_IDENT_PASS: ${{ inputs.codesignPass }} 60 | run: | 61 | : Run macOS Packaging 62 | 63 | local -a package_args=(--config ${{ inputs.config }}) 64 | if (( ${+RUNNER_DEBUG} )) package_args+=(--debug) 65 | 66 | if [[ '${{ inputs.codesign }}' == 'true' ]] package_args+=(--codesign) 67 | if [[ '${{ inputs.notarize }}' == 'true' ]] package_args+=(--notarize) 68 | if [[ '${{ inputs.package }}' == 'true' ]] package_args+=(--package) 69 | 70 | .github/scripts/package-macos ${package_args} 71 | 72 | - name: Install Dependencies 🛍️ 73 | if: runner.os == 'Linux' 74 | shell: bash 75 | run: | 76 | : Install Dependencies 🛍️ 77 | echo ::group::Install Dependencies 78 | eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" 79 | echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH 80 | brew install --quiet zsh 81 | echo ::endgroup:: 82 | 83 | - name: Run Ubuntu Packaging 84 | if: runner.os == 'Linux' 85 | shell: zsh --no-rcs --errexit --pipefail {0} 86 | working-directory: ${{ inputs.workingDirectory }} 87 | run: | 88 | : Run Ubuntu Packaging 89 | package_args=( 90 | --target linux-${{ inputs.target }} 91 | --config ${{ inputs.config }} 92 | ) 93 | if (( ${+RUNNER_DEBUG} )) build_args+=(--debug) 94 | 95 | if [[ '${{ inputs.package }}' == 'true' ]] package_args+=(--package) 96 | 97 | .github/scripts/package-linux ${package_args} 98 | 99 | - name: Run Windows Packaging 100 | if: runner.os == 'Windows' 101 | shell: pwsh 102 | run: | 103 | # Run Windows Packaging 104 | if ( $Env:RUNNER_DEBUG -ne $null ) { 105 | Set-PSDebug -Trace 1 106 | } 107 | 108 | $PackageArgs = @{ 109 | Target = '${{ inputs.target }}' 110 | Configuration = '${{ inputs.config }}' 111 | } 112 | 113 | if ( '${{ inputs.package }}' -eq 'true' ) { 114 | $PackageArgs += @{BuildInstaller = $true} 115 | } 116 | 117 | .github/scripts/Package-Windows.ps1 @PackageArgs 118 | -------------------------------------------------------------------------------- /.github/actions/run-clang-format/action.yaml: -------------------------------------------------------------------------------- 1 | name: Run clang-format 2 | description: Runs clang-format and checks for any changes introduced by it 3 | inputs: 4 | failCondition: 5 | description: Controls whether failed checks also fail the workflow run 6 | required: false 7 | default: 'never' 8 | workingDirectory: 9 | description: Working directory for checks 10 | required: false 11 | default: ${{ github.workspace }} 12 | runs: 13 | using: composite 14 | steps: 15 | - name: Check Runner Operating System 🏃‍♂️ 16 | if: runner.os == 'Windows' 17 | shell: bash 18 | run: | 19 | : Check Runner Operating System 🏃‍♂️ 20 | echo "::notice::run-clang-format action requires a macOS-based or Linux-based runner." 21 | exit 2 22 | 23 | - name: Install Dependencies 🛍️ 24 | if: runner.os == 'Linux' 25 | shell: bash 26 | run: | 27 | : Install Dependencies 🛍️ 28 | echo ::group::Install Dependencies 29 | eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" 30 | echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH 31 | echo "/home/linuxbrew/.linuxbrew/opt/clang-format@16/bin" >> $GITHUB_PATH 32 | brew install --quiet zsh 33 | echo ::endgroup:: 34 | 35 | - name: Run clang-format 🐉 36 | id: result 37 | shell: zsh --no-rcs --errexit --pipefail {0} 38 | working-directory: ${{ inputs.workingDirectory }} 39 | env: 40 | GITHUB_EVENT_FORCED: ${{ github.event.forced }} 41 | GITHUB_REF_BEFORE: ${{ github.event.before }} 42 | run: | 43 | : Run clang-format 🐉 44 | if (( ${+RUNNER_DEBUG} )) setopt XTRACE 45 | 46 | local -a changes=($(git diff --name-only HEAD~1 HEAD)) 47 | case ${GITHUB_EVENT_NAME} { 48 | pull_request) changes=($(git diff --name-only origin/${GITHUB_BASE_REF} HEAD)) ;; 49 | push) if [[ ${GITHUB_EVENT_FORCED} != true ]] changes=($(git diff --name-only ${GITHUB_REF_BEFORE} HEAD)) ;; 50 | *) ;; 51 | } 52 | 53 | if (( ${changes[(I)(*.c|*.h|*.cpp|*.hpp|*.m|*.mm)]} )) { 54 | echo ::group::Install clang-format-16 55 | brew install --quiet obsproject/tools/clang-format@16 56 | echo ::endgroup:: 57 | 58 | echo ::group::Run clang-format-16 59 | ./build-aux/run-clang-format --fail-${{ inputs.failCondition }} --check 60 | echo ::endgroup:: 61 | } 62 | -------------------------------------------------------------------------------- /.github/actions/run-cmake-format/action.yaml: -------------------------------------------------------------------------------- 1 | name: Run cmake-format 2 | description: Runs cmake-format and checks for any changes introduced by it 3 | inputs: 4 | failCondition: 5 | description: Controls whether failed checks also fail the workflow run 6 | required: false 7 | default: 'never' 8 | workingDirectory: 9 | description: Working directory for checks 10 | required: false 11 | default: ${{ github.workspace }} 12 | runs: 13 | using: composite 14 | steps: 15 | - name: Check Runner Operating System 🏃‍♂️ 16 | if: runner.os == 'Windows' 17 | shell: bash 18 | run: | 19 | : Check Runner Operating System 🏃‍♂️ 20 | echo "::notice::run-cmake-format action requires a macOS-based or Linux-based runner." 21 | exit 2 22 | 23 | - name: Install Dependencies 🛍️ 24 | if: runner.os == 'Linux' 25 | shell: bash 26 | run: | 27 | : Install Dependencies 🛍️ 28 | echo ::group::Install Dependencies 29 | eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" 30 | echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH 31 | brew install --quiet zsh 32 | echo ::endgroup:: 33 | 34 | - name: Run cmake-format 🎛️ 35 | id: result 36 | shell: zsh --no-rcs --errexit --pipefail {0} 37 | working-directory: ${{ github.workspace }} 38 | env: 39 | GITHUB_EVENT_FORCED: ${{ github.event.forced }} 40 | GITHUB_REF_BEFORE: ${{ github.event.before }} 41 | run: | 42 | : Run cmake-format 🎛️ 43 | if (( ${+RUNNER_DEBUG} )) setopt XTRACE 44 | 45 | local -a changes=($(git diff --name-only HEAD~1 HEAD)) 46 | case ${GITHUB_EVENT_NAME} { 47 | pull_request) changes=($(git diff --name-only origin/${GITHUB_BASE_REF} HEAD)) ;; 48 | push) if [[ ${GITHUB_EVENT_FORCED} != true ]] changes=($(git diff --name-only ${GITHUB_REF_BEFORE} HEAD)) ;; 49 | *) ;; 50 | } 51 | 52 | if (( ${changes[(I)*.cmake|*CMakeLists.txt]} )) { 53 | echo ::group::Install cmakelang 54 | pip3 install cmakelang 55 | echo ::endgroup:: 56 | echo ::group::Run cmake-format 57 | ./build-aux/run-cmake-format --fail-${{ inputs.failCondition }} --check 58 | echo ::endgroup:: 59 | } 60 | -------------------------------------------------------------------------------- /.github/actions/setup-macos-codesigning/action.yaml: -------------------------------------------------------------------------------- 1 | name: Set up macOS codesigning 2 | description: Sets up code signing certificates, provisioning profiles, and notarization information 3 | inputs: 4 | codesignIdentity: 5 | description: Codesigning identity 6 | required: true 7 | installerIdentity: 8 | description: Codesigning identity for package installer 9 | required: false 10 | codesignCertificate: 11 | description: PKCS12 certificate in base64 format 12 | required: true 13 | certificatePassword: 14 | description: Password required to install PKCS12 certificate 15 | required: true 16 | keychainPassword: 17 | description: Password to use for temporary keychain 18 | required: false 19 | notarizationUser: 20 | description: Apple ID to use for notarization 21 | required: false 22 | notarizationPassword: 23 | description: Application password for notarization 24 | provisioningProfile: 25 | description: Provisioning profile in base64 format 26 | required: false 27 | outputs: 28 | haveCodesignIdent: 29 | description: True if necessary codesigning credentials were found 30 | value: ${{ steps.codesign.outputs.haveCodesignIdent }} 31 | haveProvisioningProfile: 32 | description: True if necessary provisioning profile credentials were found 33 | value: ${{ steps.provisioning.outputs.haveProvisioningProfile }} 34 | haveNotarizationUser: 35 | description: True if necessary notarization credentials were found 36 | value: ${{ steps.notarization.outputs.haveNotarizationUser }} 37 | codesignIdent: 38 | description: Codesigning identity 39 | value: ${{ steps.codesign.outputs.codesignIdent }} 40 | installerIdent: 41 | description: Codesigning identity for package installer 42 | value: ${{ steps.codesign.outputs.installerIdent }} 43 | codesignTeam: 44 | description: Codesigning team 45 | value: ${{ steps.codesign.outputs.codesignTeam }} 46 | runs: 47 | using: composite 48 | steps: 49 | - name: Check Runner Operating System 🏃‍♂️ 50 | if: runner.os != 'macOS' 51 | shell: bash 52 | run: | 53 | : Check Runner Operating System 🏃‍♂️ 54 | echo "setup-macos-codesigning action requires a macOS-based runner." 55 | exit 2 56 | 57 | - name: macOS Codesigning ✍️ 58 | shell: zsh --no-rcs --errexit --pipefail {0} 59 | id: codesign 60 | env: 61 | MACOS_SIGNING_IDENTITY: ${{ inputs.codesignIdentity }} 62 | MACOS_SIGNING_IDENTITY_INSTALLER: ${{ inputs.installerIdentity}} 63 | MACOS_SIGNING_CERT: ${{ inputs.codesignCertificate }} 64 | MAOCS_SIGNING_CERT_PASSWORD: ${{ inputs.certificatePassword }} 65 | MACOS_KEYCHAIN_PASSWORD: ${{ inputs.keychainPassword }} 66 | run: | 67 | : macOS Codesigning ✍️ 68 | if (( ${+RUNNER_DEBUG} )) setopt XTRACE 69 | 70 | if [[ ${MACOS_SIGNING_IDENTITY} && ${MACOS_SIGNING_IDENTITY_INSTALLER} && ${MACOS_SIGNING_CERT} ]] { 71 | print 'haveCodesignIdent=true' >> $GITHUB_OUTPUT 72 | 73 | local -r certificate_path="${RUNNER_TEMP}/build_certificate.p12" 74 | local -r keychain_path="${RUNNER_TEMP}/app-signing.keychain-db" 75 | 76 | print -n "${MACOS_SIGNING_CERT}" | base64 --decode --output="${certificate_path}" 77 | 78 | : "${MACOS_KEYCHAIN_PASSWORD:="$(print ${RANDOM} | shasum | head -c 32)"}" 79 | 80 | print '::group::Keychain setup' 81 | security create-keychain -p "${MACOS_KEYCHAIN_PASSWORD}" ${keychain_path} 82 | security set-keychain-settings -lut 21600 ${keychain_path} 83 | security unlock-keychain -p "${MACOS_KEYCHAIN_PASSWORD}" ${keychain_path} 84 | 85 | security import "${certificate_path}" -P "${MAOCS_SIGNING_CERT_PASSWORD}" -A \ 86 | -t cert -f pkcs12 -k ${keychain_path} \ 87 | -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/xcrun 88 | 89 | security set-key-partition-list -S 'apple-tool:,apple:' -k "${MACOS_KEYCHAIN_PASSWORD}" \ 90 | ${keychain_path} &> /dev/null 91 | 92 | security list-keychain -d user -s ${keychain_path} 'login-keychain' 93 | print '::endgroup::' 94 | 95 | local -r team_id="${${MACOS_SIGNING_IDENTITY##* }//(\(|\))/}" 96 | 97 | print "codesignIdent=${MACOS_SIGNING_IDENTITY}" >> $GITHUB_OUTPUT 98 | print "installerIdent=${MACOS_SIGNING_IDENTITY_INSTALLER}" >> $GITHUB_OUTPUT 99 | print "MACOS_KEYCHAIN_PASSWORD=${MACOS_KEYCHAIN_PASSWORD}" >> $GITHUB_ENV 100 | print "codesignTeam=${team_id}" >> $GITHUB_OUTPUT 101 | } else { 102 | print 'haveCodesignIdent=false' >> $GITHUB_OUTPUT 103 | } 104 | 105 | - name: Provisioning Profile 👤 106 | shell: zsh --no-rcs --errexit --pipefail {0} 107 | id: provisioning 108 | if: ${{ fromJSON(steps.codesign.outputs.haveCodesignIdent) }} 109 | env: 110 | MACOS_SIGNING_PROVISIONING_PROFILE: ${{ inputs.provisioningProfile }} 111 | run: | 112 | : Provisioning Profile 👤 113 | if (( ${+RUNNER_DEBUG} )) setopt XTRACE 114 | 115 | if [[ ${MACOS_SIGNING_PROVISIONING_PROFILE} ]] { 116 | print 'haveProvisioningProfile=true' >> $GITHUB_OUTPUT 117 | 118 | local -r profile_path="${RUNNER_TEMP}/build_profile.provisionprofile" 119 | print -n "${MACOS_SIGNING_PROVISIONING_PROFILE}" \ 120 | | base64 --decode --output ${profile_path} 121 | 122 | print '::group::Provisioning Profile Setup' 123 | mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles 124 | security cms -D -i ${profile_path} -o ${RUNNER_TEMP}/build_profile.plist 125 | local -r uuid="$(plutil -extract UUID raw ${RUNNER_TEMP}/build_profile.plist)" 126 | local -r team_id="$(plutil -extract TeamIdentifier.0 raw -expect string ${RUNNER_TEMP}/build_profile.plist)" 127 | 128 | if [[ ${team_id} != '${{ steps.codesign.codesignTeam }}' ]] { 129 | print '::notice::Code Signing team in provisioning profile does not match certificate.' 130 | } 131 | 132 | cp ${profile_path} ~/Library/MobileDevice/Provisioning\ Profiles/${uuid}.provisionprofile 133 | print "provisioningProfileUUID=${uuid}" >> $GITHUB_OUTPUT 134 | print '::endgroup::' 135 | } else { 136 | print 'haveProvisioningProfile=false' >> $GITHUB_OUTPUT 137 | } 138 | 139 | - name: Notarization 🧑‍💼 140 | shell: zsh --no-rcs --errexit --pipefail {0} 141 | id: notarization 142 | env: 143 | MACOS_NOTARIZATION_USERNAME: ${{ inputs.notarizationUser }} 144 | MACOS_NOTARIZATION_PASSWORD: ${{ inputs.notarizationPassword }} 145 | run: | 146 | : Notarization 🧑‍💼 147 | if (( ${+RUNNER_DEBUG} )) setopt XTRACE 148 | 149 | if [[ ${MACOS_NOTARIZATION_USERNAME} && ${MACOS_NOTARIZATION_PASSWORD} ]] { 150 | print 'haveNotarizationUser=true' >> $GITHUB_OUTPUT 151 | } else { 152 | print 'haveNotarizationUser=false' >> $GITHUB_OUTPUT 153 | } 154 | -------------------------------------------------------------------------------- /.github/scripts/.Aptfile: -------------------------------------------------------------------------------- 1 | package 'cmake' 2 | package 'ccache' 3 | package 'git' 4 | package 'jq' 5 | package 'ninja-build', bin: 'ninja' 6 | package 'pkg-config' 7 | -------------------------------------------------------------------------------- /.github/scripts/.Brewfile: -------------------------------------------------------------------------------- 1 | brew "ccache" 2 | brew "coreutils" 3 | brew "cmake" 4 | brew "git" 5 | brew "jq" 6 | brew "xcbeautify" 7 | -------------------------------------------------------------------------------- /.github/scripts/.Wingetfile: -------------------------------------------------------------------------------- 1 | package 'cmake', path: 'Cmake\bin', bin: 'cmake' 2 | package 'innosetup', path: 'Inno Setup 6', bin: 'iscc' 3 | -------------------------------------------------------------------------------- /.github/scripts/.build.zsh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | builtin emulate -L zsh 4 | setopt EXTENDED_GLOB 5 | setopt PUSHD_SILENT 6 | setopt ERR_EXIT 7 | setopt ERR_RETURN 8 | setopt NO_UNSET 9 | setopt PIPE_FAIL 10 | setopt NO_AUTO_PUSHD 11 | setopt NO_PUSHD_IGNORE_DUPS 12 | setopt FUNCTION_ARGZERO 13 | 14 | ## Enable for script debugging 15 | # setopt WARN_CREATE_GLOBAL 16 | # setopt WARN_NESTED_VAR 17 | # setopt XTRACE 18 | 19 | autoload -Uz is-at-least && if ! is-at-least 5.2; then 20 | print -u2 -PR "${CI:+::error::}%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." 21 | exit 1 22 | fi 23 | 24 | TRAPEXIT() { 25 | local return_value=$? 26 | 27 | if (( ${+CI} )) unset NSUnbufferedIO 28 | 29 | return ${return_value} 30 | } 31 | 32 | TRAPZERR() { 33 | if (( ${_loglevel:-3} > 2 )) { 34 | print -u2 -PR "${CI:+::error::}%F{1} ✖︎ script execution error%f" 35 | print -PR -e " 36 | Callstack: 37 | ${(j:\n :)funcfiletrace} 38 | " 39 | } 40 | 41 | exit 2 42 | } 43 | 44 | build() { 45 | if (( ! ${+SCRIPT_HOME} )) typeset -g SCRIPT_HOME=${ZSH_ARGZERO:A:h} 46 | local host_os=${${(s:-:)ZSH_ARGZERO:t:r}[2]} 47 | local project_root=${SCRIPT_HOME:A:h:h} 48 | local buildspec_file=${project_root}/buildspec.json 49 | 50 | fpath=("${SCRIPT_HOME}/utils.zsh" ${fpath}) 51 | autoload -Uz log_group log_info log_error log_output set_loglevel check_${host_os} setup_ccache 52 | 53 | if [[ ! -r ${buildspec_file} ]] { 54 | log_error \ 55 | 'No buildspec.json found. Please create a build specification for your project.' 56 | return 2 57 | } 58 | 59 | typeset -g -a skips=() 60 | local -i verbosity=1 61 | local -r _version='2.0.0' 62 | local -r -a _valid_targets=( 63 | macos-universal 64 | linux-x86_64 65 | linux-aarch64 66 | ) 67 | local target 68 | local config='RelWithDebInfo' 69 | local -r -a _valid_configs=(Debug RelWithDebInfo Release MinSizeRel) 70 | local -i codesign=0 71 | 72 | if [[ ${host_os} == linux ]] { 73 | local -r -a _valid_generators=(Ninja 'Unix Makefiles') 74 | local generator='Ninja' 75 | local -r _usage_host=" 76 | %F{yellow} Additional options for Linux builds%f 77 | ----------------------------------------------------------------------------- 78 | %B--generator%b Specify build system to generate 79 | Available generators: 80 | - Ninja 81 | - Unix Makefiles" 82 | } elif [[ ${host_os} == macos ]] { 83 | local -r _usage_host=" 84 | %F{yellow} Additional options for macOS builds%f 85 | ----------------------------------------------------------------------------- 86 | %B-s | --codesign%b Enable codesigning (macOS only)" 87 | } 88 | 89 | local -i print_config=0 90 | local -r _usage=" 91 | Usage: %B${functrace[1]%:*}%b