├── versionsdb.txt ├── version.txt ├── versionsdbremote.txt ├── msa.commit ├── mcpelauncher-ui.commit ├── mcpelauncher.commit ├── dmg-background.tif ├── .gitignore ├── .github ├── dependabot.yml ├── ISSUE_TEMPLATE │ └── config.yml └── workflows │ ├── ci.yml │ ├── m1.yml │ └── main.yml ├── patch_qt.sh ├── changelog.txt ├── README.md ├── templates └── Info.plist.tmpl ├── download_qt.sh └── __main__.py /versionsdb.txt: -------------------------------------------------------------------------------- 1 | HEAD -------------------------------------------------------------------------------- /version.txt: -------------------------------------------------------------------------------- 1 | v1.x-nightly -------------------------------------------------------------------------------- /versionsdbremote.txt: -------------------------------------------------------------------------------- 1 | HEAD -------------------------------------------------------------------------------- /msa.commit: -------------------------------------------------------------------------------- 1 | cfcebaa0845df8e0eebaae5b211e38f8d812beab -------------------------------------------------------------------------------- /mcpelauncher-ui.commit: -------------------------------------------------------------------------------- 1 | bc03bd2d8de2ec97d55411ac316f633ac7f7a5a1 -------------------------------------------------------------------------------- /mcpelauncher.commit: -------------------------------------------------------------------------------- 1 | f742a77e13e612c8e93302ef69b966654fc9f915 -------------------------------------------------------------------------------- /dmg-background.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minecraft-linux/macos-builder/HEAD/dmg-background.tif -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | output/ 2 | source/ 3 | qt/ 4 | qt_tmp/ 5 | .vscode/ 6 | .idea/ 7 | __pycache__/ 8 | .DS_Store 9 | 10 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Checkout the wiki 4 | url: https://mcpelauncher.readthedocs.io 5 | about: You find useful information about this launcher 6 | - name: Ask on Discord 7 | url: https://discord.gg/TaUNBXr 8 | about: You can ask for help here! 9 | -------------------------------------------------------------------------------- /patch_qt.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | 3 | # TODO: Qt's installer also patches the paths in several other places - should we also do that? 4 | 5 | printf "[Paths]\nPrefix=..\n" > bin/qt.conf 6 | 7 | sed -i.bak 's/QT_EDITION = .*/QT_EDITION = OpenSource/' mkspecs/qconfig.pri 8 | sed -i.bak 's/QT_LICHECK = licheck_mac/QT_LICHECK =/' mkspecs/qconfig.pri 9 | rm mkspecs/qconfig.pri.bak 10 | -------------------------------------------------------------------------------- /changelog.txt: -------------------------------------------------------------------------------- 1 |

Fixed new multiplayer problems on macOS / crash when someone else opens Minecraft in the local network of 1.21.40 - 1.21.60.21.

The game runs now on limited fps when V-Sync is broken (when it is enabled), now capped between 80-110fps before it where greater than 2000

Disabled Fullscreen support of Menubar and f11 shortcut due to causing more bugs than being useful, use the green button and hide the menubar

2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > [!WARNING] 2 | > Deprecated CI scripts, I don't like piracy 3 | 4 | ### Can I play with an APK? 5 | 6 | No, this allowed piracy that is forbidden in this project. 7 | 8 | Any attempt to document workarounds or make it easy to import an paid apk without a valid google play game license is undesirable. 9 | 10 | Game licenses can be revoked at any point of time by you, microsoft/mojang or google, as it happened for all residents of Russia. 11 | 12 | Ignoring this policy may cause suspension including termination of this project like happended between 2022-2023. 13 | 14 | _Exception to the rule are Minecraft Trial and Edu where the latter doesn't work at this time._ 15 | 16 | For the most current version of this rule see https://minecraft-linux.github.io/faq/index.html#can-i-play-with-an-apk 17 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | workflow_dispatch: 8 | inputs: 9 | type: 10 | type: choice 11 | default: draft 12 | options: 13 | - build 14 | - draft 15 | - release 16 | jobs: 17 | read-repo-files: 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Setup Outputs 22 | id: out 23 | run: | 24 | echo "mcpelauncher-ref=$(cat mcpelauncher.commit)" >> $GITHUB_OUTPUT 25 | outputs: 26 | mcpelauncher-ref: ${{ steps.out.outputs.mcpelauncher-ref }} 27 | ci: 28 | needs: read-repo-files 29 | if: (!cancelled()) 30 | uses: ./.github/workflows/main.yml 31 | with: 32 | publish: ${{ github.event_name == 'push' && github.server_url == 'https://github.com' || github.event_name == 'workflow_dispatch' && inputs.type == 'release' }} 33 | use-repo-files: true 34 | offset: 400 35 | build-m1: true 36 | draft: ${{ github.event_name == 'workflow_dispatch' && inputs.type == 'draft' }} 37 | mcpelauncher-ref: ${{ needs.read-repo-files.outputs.mcpelauncher-ref || 'ng' }} 38 | secrets: inherit 39 | -------------------------------------------------------------------------------- /templates/Info.plist.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSHighResolutionCapable 6 | 7 | CFBundleIdentifier 8 | {{ cf_bundle_identifier }} 9 | CFBundleExecutable 10 | {{ cf_bundle_executable }} 11 | CFBundleGetInfoString 12 | {{ cf_bundle_get_info_string }} 13 | CFBundleIconFile 14 | {{ cf_bundle_icon_file }} 15 | CFBundleName 16 | {{ cf_bundle_name }} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleVersion 20 | {{ cf_bundle_version }} 21 | SUFeedURL 22 | {{ cf_sparkle_feed }} 23 | SUEnableAutomaticChecks 24 | 25 | SUPublicEDKey 26 | {{ cf_sparkle_public_ed_key }} 27 | SUScheduledCheckInterval 28 | 0 29 | SUAllowsAutomaticUpdates 30 | 31 | SUAutomaticallyUpdate 32 | 33 | LSSupportsGameMode 34 | 35 | LSMinimumSystemVersion 36 | {{ cf_bundle_macos_min }} 37 | CFBundleDocumentTypes 38 | 39 | 40 | CFBundleTypeExtensions 41 | 42 | mcpack 43 | mcworld 44 | mcaddon 45 | mctemplate 46 | 47 | CFBundleTypeRole 48 | Viewer 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /download_qt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | QT_BASE_URL=${QT_BASE_URL-"http://download.qt.io/online/qtsdkrepository/mac_x64/desktop/qt5_592/"} 4 | QT_VERSION_SHORT=${QT_VERSION_SHORT-"5.9.2"} 5 | QT_VERSION=${QT_VERSION-"5.9.2-0-201710050729"} 6 | QT_PACKAGE_PREFIX=${QT_PACKAGE_PREFIX-"qt.592."} 7 | QT_PACKAGE_SUFFIX=${QT_PACKAGE_SUFFIX-"clang_64"} 8 | QT_PREBUILT_SUFFIX=${QT_PREBUILT_SUFFIX-"-MacOS-OSX_10_10-Clang-MacOS-OSX_10_10-X86_64"} 9 | 10 | COLOR_STATUS=$'\033[1m\033[32m' 11 | COLOR_RESET=$'\033[0m' 12 | 13 | function install_module() { 14 | echo "${COLOR_STATUS}Downloading $2${COLOR_RESET}" 15 | remote_sha1=$(curl -L "$2.sha1") 16 | curl -L -C - -o $1 $2 17 | local_sha1=$(shasum $1 | cut -d " " -f 1) 18 | if [[ "$remote_sha1" != "$local_sha1" ]]; then 19 | echo "$1: sha1 mismatch - local: $local_sha1; remote: $remote_sha1" 20 | exit 1 21 | fi 22 | 7z x -y -oqt/ $1 23 | } 24 | function install_module_main() { 25 | url_base="$QT_BASE_URL$QT_PACKAGE_PREFIX$QT_PACKAGE_SUFFIX/$QT_VERSION$1$QT_PREBUILT_SUFFIX" 26 | install_module "qt_tmp/$1.7z" "$url_base.7z" 27 | } 28 | function install_module_extra() { 29 | url_base="$QT_BASE_URL$QT_PACKAGE_PREFIX$1.$QT_PACKAGE_SUFFIX/$QT_VERSION$2$QT_PREBUILT_SUFFIX" 30 | install_module "qt_tmp/$2.7z" "$url_base.7z" 31 | } 32 | 33 | mkdir -p qt 34 | mkdir -p qt_tmp 35 | 36 | install_module_main qtbase 37 | install_module_main qtdeclarative 38 | install_module_main qtgraphicaleffects 39 | install_module_main qtsvg 40 | install_module_main qtquickcontrols 41 | install_module_main qtquickcontrols2 42 | install_module_main qtwebchannel 43 | install_module_main qttools 44 | install_module_main qtlocation 45 | install_module_extra qtwebengine qtwebengine 46 | 47 | echo "${COLOR_STATUS}Patching$2${COLOR_RESET}" 48 | cd qt/$QT_VERSION_SHORT/clang_64/ 49 | ../../../patch_qt.sh 50 | 51 | curl -L -C - -o sparkle.tar.xz https://github.com/sparkle-project/Sparkle/releases/download/1.26.0/Sparkle-1.26.0.tar.xz 52 | tar -xf ./sparkle.tar.xz 53 | mv Sparkle.framework lib/ 54 | -------------------------------------------------------------------------------- /.github/workflows/m1.yml: -------------------------------------------------------------------------------- 1 | name: Manual Build 2 | on: 3 | workflow_call: 4 | inputs: 5 | mcpelauncher-manifest-repo: 6 | description: 'mcpelauncher repo' 7 | default: 'https://github.com/minecraft-linux/mcpelauncher-manifest.git' 8 | type: string 9 | mcpelauncher-manifest-ref: 10 | description: 'mcpelauncher ref' 11 | default: 'ng' 12 | type: string 13 | submodule-refs: 14 | type: string 15 | default: "[]" 16 | workflow_dispatch: 17 | inputs: 18 | mcpelauncher-manifest-repo: 19 | description: 'mcpelauncher repo' 20 | default: 'https://github.com/minecraft-linux/mcpelauncher-manifest.git' 21 | type: string 22 | mcpelauncher-manifest-ref: 23 | description: 'mcpelauncher ref' 24 | default: 'ng' 25 | type: string 26 | submodule-refs: 27 | type: string 28 | default: "[]" 29 | 30 | jobs: 31 | openssl: 32 | runs-on: ${{ matrix.OS }} 33 | strategy: 34 | fail-fast: false 35 | matrix: 36 | include: 37 | - OS: macos-latest 38 | deps: '' 39 | sdkroot: '' 40 | version: '11.0' 41 | arch: 'arm64' 42 | opensslflags: darwin64-arm64 43 | env: 44 | MACOSX_DEPLOYMENT_TARGET: ${{ matrix.version }} 45 | cache-name: cache-openssl-${{ matrix.OS }}-${{ matrix.version }}-${{ matrix.arch }} 46 | steps: 47 | - name: Cache openssl 48 | id: cache 49 | uses: actions/cache@v4 50 | with: 51 | path: output 52 | key: ${{ env.cache-name }} 53 | - uses: actions/checkout@v1 54 | if: ${{ steps.cache.outputs.cache-hit != 'true' && startsWith(matrix.OS, 'macOS') && matrix.sdkroot != '' && !startsWith(matrix.sdkroot, '/') }} 55 | with: 56 | repository: phracker/MacOSX-SDKs 57 | ref: refs/heads/master 58 | - name: Install Deps 59 | if: ${{ steps.cache.outputs.cache-hit != 'true' && matrix.deps != '' }} 60 | run: ${{ matrix.deps }} 61 | - name: Build OpenSSL 62 | if: steps.cache.outputs.cache-hit != 'true' 63 | shell: pwsh 64 | run: | 65 | if ('${{ matrix.sdkroot }}' -ne '') { 66 | if ('${{ matrix.sdkroot }}'.StartsWith('/')) { 67 | $Env:SDKROOT = '${{ matrix.sdkroot }}' 68 | } else { 69 | $Env:SDKROOT = '${{ github.workspace }}/${{ matrix.sdkroot }}' 70 | } 71 | } 72 | git clone https://github.com/openssl/openssl.git -b openssl-3.2 73 | $INSDIR = (Get-Location).ToString() + "/output" 74 | pushd openssl 75 | perl ./Configure ${{ matrix.opensslflags }} ('--prefix=' + $INSDIR) 76 | make install_sw 77 | - name: Create tar archive 78 | run: | 79 | install_name_tool -id @rpath/libssl.dylib -add_rpath @loader_path/../Frameworks lib/libssl.dylib || : 80 | install_name_tool -id @rpath/libcrypto.dylib -add_rpath @loader_path/../Frameworks lib/libcrypto.dylib || : 81 | tar cJf ../openssl.tar.xz . 82 | working-directory: output 83 | - name: Upload Binary 84 | uses: actions/upload-artifact@v4 85 | with: 86 | name: openssl-${{ matrix.OS }}-${{ matrix.version }}-${{ matrix.arch }} 87 | path: output/ 88 | - name: Upload Binary 89 | uses: actions/upload-artifact@v4 90 | with: 91 | name: openssl-${{ matrix.OS }}-${{ matrix.version }}-${{ matrix.arch }}-tar 92 | path: openssl.tar.xz 93 | angle: 94 | runs-on: ${{ matrix.OS }} 95 | strategy: 96 | fail-fast: false 97 | matrix: 98 | include: 99 | - OS: macos-latest 100 | deps: '' 101 | version: '11.0' 102 | arch: 'arm64' 103 | env: 104 | MACOSX_DEPLOYMENT_TARGET: ${{ matrix.version }} 105 | cache-name: cache-angle-${{ matrix.OS }}-${{ matrix.version }}-${{ matrix.arch }} 106 | steps: 107 | - name: Cache angle 108 | id: cache 109 | uses: actions/cache@v4 110 | with: 111 | path: output 112 | key: ${{ env.cache-name }} 113 | - uses: actions/checkout@v1 114 | if: ${{ steps.cache.outputs.cache-hit != 'true' && startsWith(matrix.OS, 'macOS') && matrix.sdkroot != '' && !startsWith(matrix.sdkroot, '/') }} 115 | with: 116 | repository: phracker/MacOSX-SDKs 117 | ref: refs/heads/master 118 | - name: Install Deps 119 | if: ${{ steps.cache.outputs.cache-hit != 'true' && matrix.deps != '' }} 120 | run: ${{ matrix.deps }} 121 | - name: Build angle 122 | if: steps.cache.outputs.cache-hit != 'true' 123 | shell: pwsh 124 | run: | 125 | if ('${{ matrix.sdkroot }}' -ne '') { 126 | if ('${{ matrix.sdkroot }}'.StartsWith('/')) { 127 | $Env:SDKROOT = '${{ matrix.sdkroot }}' 128 | } else { 129 | $Env:SDKROOT = '${{ github.workspace }}/${{ matrix.sdkroot }}' 130 | } 131 | } 132 | $INSDIR = (Get-Location).ToString() + "/output" 133 | mkdir $INSDIR 134 | git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git 135 | $Env:PATH = $Env:PATH + ':' + $PWD.ToString() + '/depot_tools' 136 | git clone https://github.com/minecraft-linux/angle.git -b metal-freeze 137 | pushd angle 138 | python scripts/bootstrap.py 139 | gclient sync 140 | @" 141 | target_cpu="${{ matrix.arch }}" 142 | is_debug=false 143 | mac_sdk_min="${{ matrix.version }}" 144 | mac_min_system_version="${{ matrix.version }}" 145 | mac_deployment_target="${{ matrix.version }}" 146 | angle_enable_metal=true 147 | angle_enable_swiftshader=false 148 | angle_enable_vulkan=false 149 | "@ > ($INSDIR + "/args.gn") 150 | if ('${{ matrix.sdkroot }}' -ne '') { 151 | echo 'mac_sdk_path="' + $Env:SDKROOT + '"' >> ($INSDIR + "/args.gn") 152 | } 153 | echo "args.gn:" 154 | cat ($INSDIR + "/args.gn") 155 | echo "Confguring" 156 | gn gen ($INSDIR) 157 | autoninja -C ($INSDIR) libEGL libGLESv2 158 | - name: Create tar archive 159 | run: | 160 | tar cJf ../angle.tar.xz . 161 | working-directory: output 162 | - name: Upload Binary 163 | uses: actions/upload-artifact@v4 164 | with: 165 | name: angle-${{ matrix.OS }}-${{ matrix.version }}-${{ matrix.arch }} 166 | path: output/ 167 | - name: Upload Binary 168 | uses: actions/upload-artifact@v4 169 | with: 170 | name: angle-${{ matrix.OS }}-${{ matrix.version }}-${{ matrix.arch }}-tar 171 | path: angle.tar.xz 172 | build: 173 | runs-on: ${{ matrix.OS }} 174 | needs: [ "openssl" ] 175 | strategy: 176 | fail-fast: false 177 | matrix: 178 | include: 179 | - AppImage: false 180 | OS: macos-latest 181 | arch: arm64 182 | version: "11.0" 183 | container: '{}' 184 | deps: | 185 | brew install autoconf automake 186 | echo 'set(CMAKE_SYSTEM_NAME Darwin)' > toolchain.txt 187 | echo 'set(CMAKE_SYSTEM_PROCESSOR aarch64)' >> toolchain.txt 188 | triple: arm64-apple-darwin 189 | cmakeextraflags: ('-DCMAKE_TOOLCHAIN_FILE='+ $INSDIR + '/../toolchain.txt') 190 | openssl: true 191 | env: 192 | MACOSX_DEPLOYMENT_TARGET: ${{ matrix.version }} 193 | CC: clang 194 | CXX: clang++ 195 | DEBIAN_FRONTEND: noninteractive 196 | # container: ${{ fromJson(matrix.container) }} 197 | steps: 198 | - uses: actions/checkout@v1 199 | if: ${{ startsWith(matrix.OS, 'macOS') && matrix.sdkroot != '' && !startsWith(matrix.sdkroot, '/') }} 200 | with: 201 | repository: phracker/MacOSX-SDKs 202 | ref: refs/heads/master 203 | - name: Install Deps 204 | shell: pwsh 205 | run: ${{ matrix.deps }} 206 | - name: Sync Submodule Sources 207 | uses: actions/github-script@v7 208 | with: 209 | github-token: none 210 | script: | 211 | var downloadRepo = async function(path, repo, ref) { 212 | await io.mkdirP(path); 213 | await exec.exec("git", ["init"], { cwd: path }); 214 | await exec.exec("git", ["remote", "add", "origin", repo], { cwd: path }); 215 | await exec.exec("git", ["fetch", "origin", ref], { cwd: path }); 216 | await exec.exec("git", ["reset", "--hard", "FETCH_HEAD"], { cwd: path }); 217 | await exec.exec("git", ["submodule", "update", "--init", "--recursive"], { cwd: path }); 218 | }; 219 | await downloadRepo("mcpelauncher", process.env.MCPELAUNCHER_REPO, process.env.MCPELAUNCHER_REF); 220 | var submoduleRefs = JSON.parse(process.env.SUBMODULEREFS); 221 | for(var submoduleRef of submoduleRefs) { 222 | if(submoduleRef.project === "mcpelauncher") { 223 | await exec.exec("git", ["fetch", submoduleRef.origin || "origin", submoduleRef.ref], { cwd: `${submoduleRef.project}/${submoduleRef.path}` }); 224 | await exec.exec("git", ["checkout", "FETCH_HEAD"], { cwd: `${submoduleRef.project}/${submoduleRef.path}` }); 225 | } 226 | } 227 | env: 228 | SUBMODULEREFS: ${{ inputs.submodule-refs || '[]' }} 229 | MCPELAUNCHER_REPO: ${{ inputs.mcpelauncher-manifest-repo }} 230 | MCPELAUNCHER_REF: ${{ inputs.mcpelauncher-manifest-ref }} 231 | - uses: actions/download-artifact@v4 232 | id: openssl 233 | if: ${{ matrix.openssl }} 234 | with: 235 | name: openssl-${{ matrix.OS }}-${{ matrix.version }}-${{ matrix.arch }} 236 | - name: Building mcpelauncher ${{ inputs.mcpelauncher-manifest-repo }}/${{ inputs.mcpelauncher-manifest-ref }} 237 | shell: pwsh 238 | env: 239 | CC: clang 240 | CXX: clang++ 241 | run: | 242 | if ('${{ matrix.sdkroot }}' -ne '') { 243 | if ('${{ matrix.sdkroot }}'.StartsWith('/')) { 244 | $Env:SDKROOT = '${{ matrix.sdkroot }}' 245 | } else { 246 | $Env:SDKROOT = '${{ github.workspace }}/${{ matrix.sdkroot }}' 247 | } 248 | } 249 | mkdir output 250 | mkdir build 251 | $INSDIR = (Get-Location).ToString() + "/output" 252 | ${{ matrix.envflags }} 253 | pushd build 254 | $EXTRA_FLAGS = '' 255 | if ('${{steps.openssl.outputs.download-path}}' -ne '') { 256 | brew uninstall --ignore-dependencies openssl@3 257 | if ($EXTRA_FLAGS -ne '') { 258 | $EXTRA_FLAGS += ' ' 259 | } 260 | $EXTRA_FLAGS += '-DOPENSSL_ROOT_DIR=${{steps.openssl.outputs.download-path}}' 261 | } 262 | cmake ../mcpelauncher '-DCMAKE_POLICY_VERSION_MINIMUM=4.0' '-DCMAKE_BUILD_TYPE=Release' '-DBUILD_UI=OFF' ('-DCMAKE_INSTALL_PREFIX=' + $INSDIR) -DCMAKE_ASM_FLAGS="--target=${{ matrix.triple }}" -DCMAKE_C_FLAGS="--target=${{ matrix.triple }} ${{ matrix.cflags }}" -DCMAKE_CXX_FLAGS="--target=${{ matrix.triple }} ${{ matrix.cxxflags }}" -DCMAKE_CXX_COMPILER_TARGET=${{ matrix.triple }} $EXTRA_FLAGS ${{ matrix.cmakeextraflags }} '-DMSA_DAEMON_PATH=.' '-DENABLE_DEV_PATHS=OFF' '-DXAL_WEBVIEW_QT_PATH=.' 263 | make install -j4 264 | popd 265 | popd 266 | 267 | - name: Create tar archive 268 | run: | 269 | tar cJf ../mcpelauncher.tar.xz . 270 | working-directory: output 271 | - name: Upload Binary 272 | uses: actions/upload-artifact@v4 273 | with: 274 | name: mcpelauncher-${{ matrix.OS }}-${{ matrix.version }}-${{ matrix.arch }} 275 | path: output/ 276 | - name: Upload tar 277 | uses: actions/upload-artifact@v4 278 | with: 279 | name: mcpelauncher-${{ matrix.OS }}-${{ matrix.version }}-${{ matrix.arch }}-tar 280 | path: mcpelauncher.tar.xz 281 | -------------------------------------------------------------------------------- /__main__.py: -------------------------------------------------------------------------------- 1 | from os import makedirs, path, cpu_count, listdir, getenv 2 | from subprocess import check_call as call 3 | import subprocess 4 | from shutil import rmtree, copyfile, copytree 5 | import shutil 6 | import argparse 7 | from jinja2 import Template 8 | 9 | # Change for each release 10 | VERSION = '0.0.1' 11 | 12 | TEMPLATES_DIR = 'templates' 13 | OUTPUT_DIR = 'output' 14 | SOURCE_DIR = 'source' 15 | APP_OUTPUT_NAME = 'Minecraft Bedrock Launcher.app' 16 | APP_OUTPUT_DIR = path.join(OUTPUT_DIR, APP_OUTPUT_NAME) 17 | 18 | ENABLE_COLORS=True 19 | 20 | 21 | def display_stage(name): 22 | if ENABLE_COLORS: 23 | print("\x1B[1m\x1B[32m=> " + name + "\x1B[0m") 24 | else: 25 | print(name) 26 | 27 | 28 | parser = argparse.ArgumentParser() 29 | parser.add_argument('--qt-path', help='Specify the Qt installation path', required=True) 30 | parser.add_argument('--update-url', help='Enable checking updates in the metalauncher from the specified URL') 31 | parser.add_argument('--build-id', help='Specify the build ID for update checking purposes') 32 | parser.add_argument('--update-sparkle-appcast', help='Sparkle appcast URL') 33 | parser.add_argument('--update-sparkle-ed-public-key', help='Enable checking updates in the metalauncher from the specified URL') 34 | parser.add_argument('--version', help='App version') 35 | parser.add_argument('--prettyversion', help='App pretty version in settings') 36 | parser.add_argument('--force', help='Always remove the output directory', action='store_true') 37 | parser.add_argument('--qtworkaround', help='apply a qt workaround', action='store_true') 38 | parser.add_argument('--skip-sync-sources', help='skip sync-sources', action='store_true') 39 | parser.add_argument('--use-own-curl', help='skip sync-sources', action='store_true') 40 | parser.add_argument('--app-root', help='base folder of the Application before running macdeployqt') 41 | args = parser.parse_args() 42 | 43 | if(args.version): 44 | VERSION = args.version 45 | 46 | if path.exists(path.join(OUTPUT_DIR)): 47 | if not args.force: 48 | print('Removing `{}/`! Click enter to continue, or ^C to exit'.format(OUTPUT_DIR)) 49 | input() 50 | rmtree(OUTPUT_DIR) 51 | 52 | display_stage("Initializing") 53 | makedirs(path.join(APP_OUTPUT_DIR, 'Contents', 'Resources')) 54 | makedirs(path.join(APP_OUTPUT_DIR, 'Contents', 'Frameworks')) 55 | makedirs(path.join(APP_OUTPUT_DIR, 'Contents', 'MacOS')) 56 | if not path.isdir(SOURCE_DIR): 57 | makedirs(SOURCE_DIR) 58 | 59 | # Download .icns file 60 | ICON_FILE = path.join(SOURCE_DIR, 'minecraft.icns') 61 | if not path.exists(ICON_FILE): 62 | display_stage("Downloading icons file") 63 | call(['curl', '-sL', '-o', ICON_FILE, 'https://github.com/minecraft-linux/mcpelauncher-ui-qt/raw/0b956a0fc816d900d5b3f2883c6a401330c50fab/Resources/mcpelauncher-icon.icns']) 64 | copyfile(ICON_FILE, path.join(APP_OUTPUT_DIR, 'Contents', 'Resources', 'minecraft.icns')) 65 | 66 | # Download the sources 67 | def clone_repo(name, url, branch): 68 | display_stage("Cloning repository: " + url) 69 | directory = path.join(SOURCE_DIR, name) 70 | if not path.isdir(directory): 71 | makedirs(directory) 72 | call(['git', 'init'], cwd=directory) 73 | call(['git', 'remote', 'add', 'origin', url], cwd=directory) 74 | call(['git', 'fetch', 'origin', branch], cwd=directory) 75 | call(['git', 'reset', '--hard', 'FETCH_HEAD'], cwd=directory) 76 | call(['git', 'submodule', 'update', '--init', '--recursive'], cwd=directory) 77 | else: 78 | call(['git', 'pull'], cwd=directory) 79 | call(['git', 'submodule', 'update', '--init', '--recursive'], cwd=directory) 80 | 81 | if not args.skip_sync_sources: 82 | display_stage("Downloading sources") 83 | 84 | with open('msa.commit', 'r') as file: 85 | clone_repo('msa', 'https://github.com/minecraft-linux/msa-manifest.git', file.read().replace('\n', '')) 86 | with open('mcpelauncher.commit', 'r') as file: 87 | clone_repo('mcpelauncher', 'https://github.com/minecraft-linux/mcpelauncher-manifest.git', file.read().replace('\n', '')) 88 | with open('mcpelauncher-ui.commit', 'r') as file: 89 | clone_repo('mcpelauncher-ui', 'https://github.com/minecraft-linux/mcpelauncher-ui-manifest.git', file.read().replace('\n', '')) 90 | 91 | # Build 92 | # QT_INSTALL_PATH = subprocess.check_output(['brew', '--prefix', 'qt']).decode('utf-8').strip() 93 | QT_INSTALL_PATH = path.abspath(args.qt_path) 94 | CMAKE_INSTALL_PREFIX = path.abspath(path.join(SOURCE_DIR, "install")) 95 | CMAKE_QT_EXTRA_OPTIONS = ["-DCMAKE_PREFIX_PATH=" + QT_INSTALL_PATH, '-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=ON'] 96 | 97 | MCPELAUNCHER_EXTRA_OPTIONS = [] 98 | if args.use_own_curl: 99 | MCPELAUNCHER_EXTRA_OPTIONS += [ "-DUSE_OWN_CURL=ON" ] 100 | else: 101 | MCPELAUNCHER_EXTRA_OPTIONS += [ "-DUSE_OWN_CURL=OFF" ] 102 | 103 | if not path.isdir(CMAKE_INSTALL_PREFIX): 104 | makedirs(CMAKE_INSTALL_PREFIX) 105 | 106 | def cmake_cmd(source_dir): 107 | return ['cmake', source_dir, '-DCMAKE_INSTALL_PREFIX=' + CMAKE_INSTALL_PREFIX, '-DCMAKE_POLICY_VERSION_MINIMUM=4.0'] 108 | 109 | def build_component(name, cmake_opts): 110 | display_stage("Building: " + name) 111 | source_dir = path.abspath(path.join(SOURCE_DIR, name)) 112 | build_dir = path.join(SOURCE_DIR, "build", name) 113 | if not path.isdir(build_dir): 114 | makedirs(build_dir) 115 | call(cmake_cmd(source_dir) + cmake_opts, cwd=build_dir) 116 | call(['make', '-j' + str(cpu_count()), 'install'], cwd=build_dir) 117 | 118 | def build_component32(name, cmake_opts): 119 | display_stage("Building: " + name) 120 | source_dir = path.abspath(path.join(SOURCE_DIR, name)) 121 | build_dir = path.join(SOURCE_DIR, "build", name) 122 | if not path.isdir(build_dir): 123 | makedirs(build_dir) 124 | call(cmake_cmd(source_dir) + cmake_opts, cwd=build_dir) 125 | call(['make', '-j' + str(cpu_count())], cwd=build_dir) 126 | shutil.copy2(path.join(build_dir, 'mcpelauncher-client', 'mcpelauncher-client'), path.join(CMAKE_INSTALL_PREFIX, 'bin', 'mcpelauncher-client32')) 127 | 128 | VERSION_OPTS = [] 129 | if args.update_url and args.build_id: 130 | VERSION_OPTS = ["-DENABLE_UPDATE_CHECK=ON", "-DUPDATE_CHECK_URL=" + args.update_url, "-DUPDATE_CHECK_BUILD_ID=" + args.build_id] 131 | 132 | SPARKLE_OPTS = [] 133 | if args.update_sparkle_appcast: 134 | SPARKLE_OPTS = [ "-DENABLE_SPARKLE_UPDATE_CHECK=1", "-DSPARKLE_UPDATE_CHECK_URL=" + args.update_sparkle_appcast] 135 | 136 | display_stage("Building") 137 | OPENSSL64_OPTS = [ '-DOPENSSL_ROOT_DIR=' + path.abspath('ssl64'), '-DOPENSSL_CRYPTO_LIBRARY=' + path.abspath('ssl64/lib/libcrypto.dylib')] 138 | OPENSSL64_INCLUDES = '-I' + path.abspath('ssl64/include') + ' -L' + path.abspath('ssl64/lib') 139 | build_component("msa", ['-DENABLE_MSA_QT_UI=ON', '-DMSA_UI_PATH_DEV=OFF', '-DCMAKE_CXX_FLAGS=-DNDEBUG -Wl,-L' + path.abspath('libcxx-build') + ',-rpath,@loader_path/../Frameworks' +' -D_LIBCPP_DISABLE_AVAILABILITY=1 -I' + path.abspath('libcxx64-build/include/c++/v1')] + CMAKE_QT_EXTRA_OPTIONS) 140 | build_component("mcpelauncher", ['-DMSA_DAEMON_PATH=.', '-DENABLE_DEV_PATHS=OFF', '-DBUILD_FAKE_JNI_TESTS=OFF', '-DXAL_WEBVIEW_QT_PATH=.', '-DJNI_USE_JNIVM=ON', '-DBUILD_FAKE_JNI_EXAMPLES=OFF', '-DCMAKE_CXX_FLAGS=-DNDEBUG -Wl,-L' + path.abspath('libcxx-build') +',-rpath,@loader_path/../Frameworks -D_LIBCPP_DISABLE_AVAILABILITY=1 -I' + path.abspath('libcxx64-build/include/c++/v1') + ' ' + OPENSSL64_INCLUDES] + CMAKE_QT_EXTRA_OPTIONS + MCPELAUNCHER_EXTRA_OPTIONS + OPENSSL64_OPTS) 141 | build_component32("mcpelauncher", ['-DMSA_DAEMON_PATH=.', '-DENABLE_DEV_PATHS=OFF', '-DENABLE_QT_ERROR_UI=OFF', '-DBUILD_FAKE_JNI_TESTS=OFF', '-DOPENSSL_ROOT_DIR=' + path.abspath('ssl32'), '-DOPENSSL_CRYPTO_LIBRARY=' + path.abspath('ssl32/lib/libcrypto.dylib'), '-DBUILD_FAKE_JNI_EXAMPLES=OFF', '-DCMAKE_ASM_FLAGS=-m32', '-DCMAKE_C_FLAGS=-m32', '-DCMAKE_CXX_FLAGS=-m32 -DNDEBUG -Wl,-L' + path.abspath('libcxx-build') +',-rpath,@loader_path/../Frameworks -D_LIBCPP_DISABLE_AVAILABILITY=1 -I' + path.abspath('libcxx32-build/include/c++/v1') + ' -I' + path.abspath('ssl32/include') + ' -L' + path.abspath('ssl32/lib'), '-DCMAKE_CXX_COMPILER_TARGET=i386-apple-darwin', '-DCMAKE_LIBRARY_ARCHITECTURE=i386-apple-darwin', '-DBUILD_WEBVIEW=OFF', '-DXAL_WEBVIEW_QT_PATH=.', '-DJNI_USE_JNIVM=ON'] + MCPELAUNCHER_EXTRA_OPTIONS) 142 | ADDITIONAL_UI_OPTS = [] 143 | if args.prettyversion: 144 | ADDITIONAL_UI_OPTS += [ "-DLAUNCHER_VERSION_NAME=" + args.prettyversion ] 145 | if args.build_id: 146 | ADDITIONAL_UI_OPTS += [ "-DLAUNCHER_VERSION_CODE=" + args.build_id ] 147 | changelog = "" 148 | with open('changelog.txt', 'r') as file: 149 | changelog = file.read().replace('\n', '
') 150 | ADDITIONAL_UI_OPTS += [ "-DLAUNCHER_CHANGE_LOG=" + changelog ] 151 | 152 | with open('versionsdb.txt', 'r') as file: 153 | ref = file.read().replace('\n', '') 154 | clone_repo('versionsdb', 'https://github.com/minecraft-linux/mcpelauncher-versiondb.git', ref) 155 | ADDITIONAL_UI_OPTS += [ "-DLAUNCHER_VERSIONDB_PATH=" + path.abspath(path.join(SOURCE_DIR, 'versionsdb'))] 156 | 157 | with open('versionsdbremote.txt', 'r') as file: 158 | ref = file.read().replace('\n', '') 159 | ADDITIONAL_UI_OPTS += [ "-DLAUNCHER_VERSIONDB_URL=https://raw.githubusercontent.com/minecraft-linux/mcpelauncher-versiondb/" + ref] 160 | 161 | build_component("mcpelauncher-ui", ['-DGAME_LAUNCHER_PATH=.', '-DCMAKE_CXX_FLAGS=-DNDEBUG -Wl,-F'+ QT_INSTALL_PATH + '/lib/,-L' + path.abspath('libcxx-build') +',-rpath,@loader_path/../Frameworks -D_LIBCPP_DISABLE_AVAILABILITY=1 -I' + path.abspath('libcxx64-build/include/c++/v1') + ' ' + OPENSSL64_INCLUDES, "-DQt5QuickCompiler_FOUND=OFF", "-DLAUNCHER_ENABLE_GOOGLE_PLAY_LICENCE_CHECK=ON", "-DLAUNCHER_DISABLE_DEV_MODE=ON"] + VERSION_OPTS + SPARKLE_OPTS + CMAKE_QT_EXTRA_OPTIONS + ADDITIONAL_UI_OPTS + OPENSSL64_OPTS) 162 | 163 | display_stage("Copying files") 164 | def copy_installed_files(from_path, to_path): 165 | for f in listdir(from_path): 166 | print("Copying file: " + f) 167 | if path.isdir(path.join(from_path, f)): 168 | copytree(path.join(from_path, f), path.join(to_path, f), True, dirs_exist_ok = True) 169 | else: 170 | shutil.copy2(path.join(from_path, f), path.join(to_path, f), follow_symlinks = False) 171 | 172 | if path.exists(args.app_root): 173 | copy_installed_files(args.app_root, APP_OUTPUT_DIR) 174 | 175 | copy_installed_files(path.join(CMAKE_INSTALL_PREFIX, 'bin'), path.join(APP_OUTPUT_DIR, 'Contents', 'MacOS')) 176 | copy_installed_files(path.join(CMAKE_INSTALL_PREFIX, 'share'), path.join(APP_OUTPUT_DIR, 'Contents', 'Resources')) 177 | # Workaround Qt 5.9.2 178 | if args.qtworkaround: 179 | copy_installed_files(path.join(QT_INSTALL_PATH, 'qml', 'QtQuick'), path.join(APP_OUTPUT_DIR, 'Contents', 'Resources', 'qml', 'QtQuick')) 180 | copy_installed_files(path.join(QT_INSTALL_PATH, 'qml', 'QtQuick.2'), path.join(APP_OUTPUT_DIR, 'Contents', 'Resources', 'qml', 'QtQuick.2')) 181 | 182 | display_stage("Building Info.plist file") 183 | with open(path.join(TEMPLATES_DIR, 'Info.plist.tmpl'), 'r') as raw: 184 | info = Template(raw.read()) 185 | output = info.render( 186 | cf_bundle_identifier = 'io.mrarm.mcpelauncher.ui', 187 | cf_bundle_executable = 'mcpelauncher-ui-qt', 188 | cf_bundle_get_info_string = 'Minecraft Bedrock Launcher', 189 | cf_bundle_icon_file = 'minecraft', 190 | cf_bundle_name = 'Minecraft Bedrock Launcher', 191 | cf_bundle_version = VERSION, 192 | cf_sparkle_feed = args.update_sparkle_appcast, 193 | cf_sparkle_public_ed_key = args.update_sparkle_ed_public_key, 194 | cf_bundle_macos_min = getenv("MACOSX_DEPLOYMENT_TARGET", "10.7") 195 | ) 196 | 197 | f = open(path.join(APP_OUTPUT_DIR, 'Contents', 'Info.plist'), 'w') 198 | f.write(output) 199 | f.close() 200 | 201 | display_stage("Copying Qt libraries") 202 | QT_DEPLOY_OPTIONS = [path.join(QT_INSTALL_PATH, 'bin', 'macdeployqt'), APP_OUTPUT_DIR] 203 | QT_DEPLOY_OPTIONS.append('-qmldir=' + path.join(SOURCE_DIR, 'mcpelauncher-ui', 'mcpelauncher-ui-qt')) 204 | QT_DEPLOY_OPTIONS.append('-qmldir=' + path.join(SOURCE_DIR, 'mcpelauncher', 'mcpelauncher-webview')) 205 | QT_DEPLOY_OPTIONS.append('-qmldir=' + path.join(SOURCE_DIR, 'mcpelauncher', 'mcpelauncher-errorwindow', 'src', 'qml')) 206 | QT_DEPLOY_OPTIONS.append('-executable=' + path.abspath(path.join(APP_OUTPUT_DIR, 'Contents', 'MacOS', 'mcpelauncher-ui-qt'))) 207 | QT_DEPLOY_OPTIONS.append('-executable=' + path.abspath(path.join(APP_OUTPUT_DIR, 'Contents', 'MacOS', 'msa-ui-qt'))) 208 | QT_DEPLOY_OPTIONS.append('-executable=' + path.abspath(path.join(APP_OUTPUT_DIR, 'Contents', 'MacOS', 'mcpelauncher-webview'))) 209 | QT_DEPLOY_OPTIONS.append('-executable=' + path.abspath(path.join(APP_OUTPUT_DIR, 'Contents', 'MacOS', 'mcpelauncher-error'))) 210 | call(QT_DEPLOY_OPTIONS) 211 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_call: 3 | inputs: 4 | submodule-refs: 5 | type: string 6 | default: "[]" 7 | mcpelauncher-repo: 8 | type: string 9 | default: https://github.com/minecraft-linux/mcpelauncher-manifest 10 | mcpelauncher-ref: 11 | type: string 12 | default: ${{ github.repository == 'minecraft-linux/mcpelauncher-manifest' && (github.sha || github.ref) || 'ng' }} 13 | mcpelauncher-ui-repo: 14 | type: string 15 | default: https://github.com/minecraft-linux/mcpelauncher-ui-manifest 16 | mcpelauncher-ui-ref: 17 | type: string 18 | default: ${{ github.repository == 'minecraft-linux/mcpelauncher-ui-manifest' && (github.sha || github.ref) || 'ng' }} 19 | msa-repo: 20 | type: string 21 | default: https://github.com/minecraft-linux/msa-manifest 22 | msa-ref: 23 | type: string 24 | default: ${{ github.repository == 'minecraft-linux/msa-manifest' && (github.sha || github.ref) || 'master' }} 25 | MacOSX1014sdkRepo: 26 | type: string 27 | default: ChristopherHX/MacOSX10.14.sdk 28 | MacOSX1014sdkRef: 29 | type: string 30 | default: 18f574aa8d71402560dd3cbf349a9f8b2cec3833 31 | use-repo-files: 32 | type: boolean 33 | default: false 34 | publish: 35 | type: boolean 36 | default: false 37 | draft: 38 | type: boolean 39 | default: false 40 | offset: 41 | type: number 42 | default: 0 43 | build-m1: 44 | type: boolean 45 | default: true 46 | secrets: 47 | MacOSX1014sdk: 48 | description: 'A ssh key to download macOS sdk 10.14' 49 | required: false 50 | SPARKLE_ECDSA: 51 | description: 'sparkle ecdsa public key' 52 | required: false 53 | SPARKLE_ECDSA_PUB: 54 | description: 'sparkle ecdsa public key' 55 | required: false 56 | jobs: 57 | build-libcxx32: 58 | runs-on: macos-15-intel 59 | steps: 60 | #- name: Select Xcode 61 | # run: sudo xcode-select -switch /Applications/Xcode_14.2.app 62 | - name: Check Cache libcxx32 63 | id: libcxx32-llvm 64 | uses: ChristopherHX/check-cache@main 65 | env: 66 | cache-name: cache-libcxx32--macos-10-10-4 67 | with: 68 | path: libcxx32-build 69 | key: ${{ runner.os }}-build-${{ env.cache-name }} 70 | - name: Cache libcxx32 71 | if: steps.libcxx32-llvm.outputs.cache-hit != 'true' 72 | uses: actions/cache@v4 73 | env: 74 | cache-name: cache-libcxx32--macos-10-10-4 75 | with: 76 | path: libcxx32-build 77 | key: ${{ runner.os }}-build-${{ env.cache-name }} 78 | - uses: actions/checkout@v1 79 | if: steps.libcxx32-llvm.outputs.cache-hit != 'true' 80 | with: 81 | repository: phracker/MacOSX-SDKs 82 | ref: refs/heads/master 83 | - name: Set up Python 84 | uses: actions/setup-python@v5 85 | with: 86 | python-version: '3.13' 87 | id: setup-py 88 | - name: Build libcxx, libcxxabi 89 | if: steps.libcxx32-llvm.outputs.cache-hit != 'true' 90 | run: | 91 | export MACOSX_DEPLOYMENT_TARGET=10.10.0 92 | export SDKROOT=${{ github.workspace }}/../MacOSX-SDKs/MacOSX10.10.sdk 93 | git clone https://github.com/llvm/llvm-project.git llvm -b release/10.x 94 | mkdir -p libcxx32-build 95 | cd libcxx32-build 96 | cmake ../llvm/llvm -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DHAVE_CXX_ATOMICS_WITHOUT_LIB=ON -DHAVE_CXX_ATOMICS64_WITHOUT_LIB=ON -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" -DCMAKE_BUILD_TYPE=Release -DLIBCXX_BUILD_32_BITS=ON -DLIBCXXABI_BUILD_32_BITS=ON -DLLVM_BUILD_32_BITS=ON -DPYTHON_EXECUTABLE=${{ steps.setup-py.outputs.python-path }} 97 | make -j8 cxx cxxabi 98 | build-libcxx64: 99 | runs-on: macos-15-intel 100 | steps: 101 | - name: Check Cache libcxx64 102 | id: libcxx64-llvm 103 | uses: ChristopherHX/check-cache@main 104 | env: 105 | cache-name: cache-libcxx64--macos-10-10-4 106 | with: 107 | path: libcxx64-build 108 | key: ${{ runner.os }}-build-${{ env.cache-name }} 109 | - name: Cache libcxx64 110 | if: steps.libcxx64-llvm.outputs.cache-hit != 'true' 111 | uses: actions/cache@v4 112 | env: 113 | cache-name: cache-libcxx64--macos-10-10-4 114 | with: 115 | path: libcxx64-build 116 | key: ${{ runner.os }}-build-${{ env.cache-name }} 117 | - uses: actions/checkout@v1 118 | if: steps.libcxx64-llvm.outputs.cache-hit != 'true' 119 | with: 120 | repository: phracker/MacOSX-SDKs 121 | ref: refs/heads/master 122 | - name: Set up Python 123 | uses: actions/setup-python@v5 124 | with: 125 | python-version: '3.13' 126 | id: setup-py 127 | - name: Build libcxx, libcxxabi 128 | if: steps.libcxx64-llvm.outputs.cache-hit != 'true' 129 | run: | 130 | export MACOSX_DEPLOYMENT_TARGET=10.10.0 131 | export SDKROOT=${{ github.workspace }}/../MacOSX-SDKs/MacOSX10.10.sdk 132 | git clone https://github.com/llvm/llvm-project.git llvm -b release/10.x 133 | mkdir -p libcxx64-build 134 | cd libcxx64-build 135 | cmake ../llvm/llvm -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DHAVE_CXX_ATOMICS_WITHOUT_LIB=ON -DHAVE_CXX_ATOMICS64_WITHOUT_LIB=ON -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" -DCMAKE_BUILD_TYPE=Release -DPYTHON_EXECUTABLE=${{ steps.setup-py.outputs.python-path }} 136 | make -j8 cxx cxxabi 137 | build-libcxx: 138 | runs-on: macos-15-intel 139 | needs: [build-libcxx32,build-libcxx64] 140 | steps: 141 | - name: Check libcxx 142 | id: libcxx-llvm 143 | uses: ChristopherHX/check-cache@main 144 | env: 145 | cache-name: cache-libcxx--macos-10-10-4 146 | with: 147 | path: libcxx-build 148 | key: ${{ runner.os }}-build-${{ env.cache-name }} 149 | - name: Cache libcxx32 150 | if: steps.libcxx-llvm.outputs.cache-hit != 'true' 151 | id: libcxx32-llvm 152 | uses: actions/cache@v4 153 | env: 154 | cache-name: cache-libcxx32--macos-10-10-4 155 | with: 156 | path: libcxx32-build 157 | key: ${{ runner.os }}-build-${{ env.cache-name }} 158 | - name: Cache libcxx64 159 | if: steps.libcxx-llvm.outputs.cache-hit != 'true' 160 | id: libcxx64-llvm 161 | uses: actions/cache@v4 162 | env: 163 | cache-name: cache-libcxx64--macos-10-10-4 164 | with: 165 | path: libcxx64-build 166 | key: ${{ runner.os }}-build-${{ env.cache-name }} 167 | - name: Cache libcxx 168 | if: steps.libcxx-llvm.outputs.cache-hit != 'true' 169 | uses: actions/cache@v4 170 | env: 171 | cache-name: cache-libcxx--macos-10-10-4 172 | with: 173 | path: libcxx-build 174 | key: ${{ runner.os }}-build-${{ env.cache-name }} 175 | - name: Build universal lib 176 | if: steps.libcxx-llvm.outputs.cache-hit != 'true' 177 | run: | 178 | mkdir -p libcxx-build/ 179 | lipo -create libcxx32-build/lib/libc++.dylib libcxx64-build/lib/libc++.dylib -output libcxx-build/libc++.1.dylib 180 | lipo -create libcxx32-build/lib/libc++abi.dylib libcxx64-build/lib/libc++abi.dylib -output libcxx-build/libc++abi.1.dylib 181 | cd libcxx-build 182 | ln -s libc++.1.dylib libc++.dylib 183 | ln -s libc++abi.1.dylib libc++abi.dylib 184 | install_name_tool -rpath @loader_path/../lib @loader_path/../Frameworks libc++.dylib 185 | install_name_tool -rpath @loader_path/../lib @loader_path/../Frameworks libc++abi.dylib 186 | buildopenssl32: 187 | runs-on: macos-15-intel 188 | steps: 189 | - name: Check for openssl 190 | id: cache-openssl32 191 | uses: ChristopherHX/check-cache@main 192 | env: 193 | cache-name: cache-openssl32-macos-10-10 194 | with: 195 | path: ssl32 196 | key: ${{ runner.os }}-build-${{ env.cache-name }} 197 | - name: Cache openssl 198 | if: steps.cache-openssl32.outputs.cache-hit != 'true' 199 | uses: actions/cache@v4 200 | env: 201 | cache-name: cache-openssl32-macos-10-10 202 | with: 203 | path: ssl32 204 | key: ${{ runner.os }}-build-${{ env.cache-name }} 205 | - uses: actions/checkout@v3 206 | if: env.HAVE_SECRET && steps.cache-openssl32.outputs.cache-hit != 'true' 207 | with: 208 | repository: ${{ inputs.MacOSX1014sdkRepo}} 209 | ref: ${{ inputs.MacOSX1014sdkRef }} 210 | ssh-key: ${{ secrets.MacOSX1014sdk }} 211 | path: MacOSX10.14.sdk 212 | env: 213 | HAVE_SECRET: ${{ secrets.MacOSX1014sdk && '1' || '' }} 214 | - uses: actions/checkout@v1 215 | if: env.MISSING_SECRET && steps.cache-openssl32.outputs.cache-hit != 'true' 216 | with: 217 | repository: phracker/MacOSX-SDKs 218 | ref: refs/heads/master 219 | env: 220 | MISSING_SECRET: ${{ !secrets.MacOSX1014sdk && '1' || '' }} 221 | - name: Update env 222 | if: steps.cache-openssl32.outputs.cache-hit != 'true' 223 | run: | 224 | echo MACOSX_DEPLOYMENT_TARGET=10.10.0 > $GITHUB_ENV 225 | echo SDKROOT=${{ github.workspace }}/${{ secrets.MacOSX1014sdk && 'MacOSX10.14.sdk' || '../MacOSX-SDKs/MacOSX10.13.sdk' }} >> $GITHUB_ENV 226 | - name: Prepare Legacy sdk 227 | if: steps.cache-openssl32.outputs.cache-hit != 'true' 228 | run: | 229 | cd "$SDKROOT/usr/include" 230 | ln -s "$(xcrun --sdk macosx --show-sdk-path)/usr/include/c++" c++ 231 | - name: Build OpenSSL 232 | if: steps.cache-openssl32.outputs.cache-hit != 'true' 233 | run: | 234 | # Keep sing openssl 1.1.1 on 32bit, 3.2 refuses to configure 235 | git clone https://github.com/openssl/openssl.git -b OpenSSL_1_1_1-stable 236 | cd openssl 237 | KERNEL_BITS=32 ./config --prefix="$PWD/../ssl32" 238 | make -j8 239 | sudo make install_sw -j8 240 | buildopenssl64: 241 | runs-on: macos-15-intel 242 | steps: 243 | - name: Check for openssl 244 | id: cache-openssl64 245 | uses: ChristopherHX/check-cache@main 246 | env: 247 | cache-name: cache-openssl64-macos-10-10 248 | with: 249 | path: ssl64 250 | key: ${{ runner.os }}-build-${{ env.cache-name }} 251 | - name: Cache openssl 252 | if: steps.cache-openssl64.outputs.cache-hit != 'true' 253 | uses: actions/cache@v4 254 | env: 255 | cache-name: cache-openssl64-macos-10-10 256 | with: 257 | path: ssl64 258 | key: ${{ runner.os }}-build-${{ env.cache-name }} 259 | - uses: actions/checkout@v3 260 | if: env.HAVE_SECRET && steps.cache-openssl64.outputs.cache-hit != 'true' 261 | with: 262 | repository: ${{ inputs.MacOSX1014sdkRepo}} 263 | ref: ${{ inputs.MacOSX1014sdkRef }} 264 | ssh-key: ${{ secrets.MacOSX1014sdk }} 265 | path: MacOSX10.14.sdk 266 | env: 267 | HAVE_SECRET: ${{ secrets.MacOSX1014sdk && '1' || '' }} 268 | - uses: actions/checkout@v1 269 | if: env.MISSING_SECRET && steps.cache-openssl64.outputs.cache-hit != 'true' 270 | with: 271 | repository: phracker/MacOSX-SDKs 272 | ref: refs/heads/master 273 | env: 274 | MISSING_SECRET: ${{ !secrets.MacOSX1014sdk && '1' || '' }} 275 | - name: Update env 276 | if: steps.cache-openssl64.outputs.cache-hit != 'true' 277 | run: | 278 | echo MACOSX_DEPLOYMENT_TARGET=10.10.0 > $GITHUB_ENV 279 | echo SDKROOT=${{ github.workspace }}/${{ secrets.MacOSX1014sdk && 'MacOSX10.14.sdk' || '../MacOSX-SDKs/MacOSX10.13.sdk' }} >> $GITHUB_ENV 280 | - name: Prepare Legacy sdk 281 | if: steps.cache-openssl64.outputs.cache-hit != 'true' 282 | run: | 283 | cd "$SDKROOT/usr/include" 284 | ln -s "$(xcrun --sdk macosx --show-sdk-path)/usr/include/c++" c++ 285 | - name: Build OpenSSL 286 | if: steps.cache-openssl64.outputs.cache-hit != 'true' 287 | run: | 288 | git clone https://github.com/openssl/openssl.git -b openssl-3.2 289 | cd openssl 290 | KERNEL_BITS=64 ./config --prefix="$PWD/../ssl64" 291 | make -j8 292 | sudo make install_sw -j8 293 | buildopenssl: 294 | runs-on: macos-15-intel 295 | needs: [buildopenssl32, buildopenssl64] 296 | steps: 297 | - name: Check openssl 298 | id: openssl 299 | uses: ChristopherHX/check-cache@main 300 | env: 301 | cache-name: cache-openssl-2 302 | with: 303 | path: ssl 304 | key: ${{ runner.os }}-build-${{ env.cache-name }} 305 | - name: Cache openssl 306 | if: steps.openssl.outputs.cache-hit != 'true' 307 | uses: actions/cache@v4 308 | env: 309 | cache-name: cache-openssl-2 310 | with: 311 | path: ssl 312 | key: ${{ runner.os }}-build-${{ env.cache-name }} 313 | - name: Cache openssl32 314 | if: steps.openssl.outputs.cache-hit != 'true' 315 | uses: actions/cache@v4 316 | env: 317 | cache-name: cache-openssl32-macos-10-10 318 | with: 319 | path: ssl32 320 | key: ${{ runner.os }}-build-${{ env.cache-name }} 321 | - name: Cache openssl64 322 | if: steps.openssl.outputs.cache-hit != 'true' 323 | uses: actions/cache@v4 324 | env: 325 | cache-name: cache-openssl64-macos-10-10 326 | with: 327 | path: ssl64 328 | key: ${{ runner.os }}-build-${{ env.cache-name }} 329 | - name: Build universal lib 330 | if: steps.openssl.outputs.cache-hit != 'true' 331 | run: | 332 | mkdir -p ssl/lib 333 | lipo -create ssl32/lib/libssl.dylib ssl64/lib/libssl.dylib -output ssl/lib/libssl.dylib 334 | lipo -create ssl32/lib/libcrypto.dylib ssl64/lib/libcrypto.dylib -output ssl/lib/libcrypto.dylib 335 | cd ssl/lib 336 | install_name_tool -id @rpath/libssl.dylib -add_rpath @loader_path/../Frameworks libssl.dylib 337 | install_name_tool -id @rpath/libcrypto.dylib -add_rpath @loader_path/../Frameworks libcrypto.dylib 338 | buildangle: 339 | runs-on: macos-15-intel 340 | # needs: [buildangle32, buildangle64] 341 | steps: 342 | - name: Check angle 343 | id: angle 344 | uses: ChristopherHX/check-cache@main 345 | env: 346 | cache-name: cache-angle-3 347 | with: 348 | path: source/osx-angle-ci/artifacts 349 | key: ${{ runner.os }}-build-${{ env.cache-name }} 350 | - name: Cache angle 351 | if: steps.angle.outputs.cache-hit != 'true' 352 | uses: actions/cache@v4 353 | env: 354 | cache-name: cache-angle-3 355 | with: 356 | path: source/osx-angle-ci/artifacts 357 | key: ${{ runner.os }}-build-${{ env.cache-name }} 358 | # See https://github.com/minecraft-linux/macos-builder/commit/2588136caaad8c993f3912d981dab13b9846360e for building it 359 | # python2 now runs via python3 in macOS hosted runners 360 | - uses: actions/setup-python@v5 361 | with: 362 | python-version: '3.x' 363 | architecture: 'x64' 364 | if: steps.angle.outputs.cache-hit != 'true' 365 | - run: | 366 | mkdir -p source/osx-angle-ci/artifacts 367 | if: steps.angle.outputs.cache-hit != 'true' 368 | - run: | 369 | from subprocess import check_call as call 370 | import shutil 371 | from os import path 372 | DMG_MOUNT_PATH = '/Volumes/Minecraft Bedrock Launcher/' 373 | DMG_FILE = 'Minecraft Bedrock Launcher.dmg' 374 | call(['curl', '-sL', '-o', DMG_FILE, 'https://github.com/minecraft-linux/macos-builder/releases/download/v0.12.2-448/Minecraft_Bedrock_Launcher_v0.12.2-macOS-x86_64-0.2.448_macOS_10.13.0.dmg']) 375 | call(['hdiutil', 'attach', '-noautoopen', '-mountpoint', DMG_MOUNT_PATH, '-quiet', DMG_FILE]) 376 | shutil.copy2(path.join(DMG_MOUNT_PATH, 'Minecraft Bedrock Launcher.app', 'Contents', 'Frameworks', 'libEGL.dylib'), './source/osx-angle-ci/artifacts/libEGL.dylib', follow_symlinks = True) 377 | shutil.copy2(path.join(DMG_MOUNT_PATH, 'Minecraft Bedrock Launcher.app', 'Contents', 'Frameworks', 'libGLESv2.dylib'), './source/osx-angle-ci/artifacts/libGLESv2.dylib', follow_symlinks = True) 378 | shell: python 379 | if: steps.angle.outputs.cache-hit != 'true' 380 | - run: | 381 | lipo -remove arm64 ./source/osx-angle-ci/artifacts/libEGL.dylib -output ./source/osx-angle-ci/artifacts/libEGL.dylib 382 | lipo -remove arm64 ./source/osx-angle-ci/artifacts/libGLESv2.dylib -output ./source/osx-angle-ci/artifacts/libGLESv2.dylib 383 | if: steps.angle.outputs.cache-hit != 'true' 384 | build-protobuf: 385 | runs-on: macos-15-intel 386 | steps: 387 | #- name: Select Xcode 388 | # run: sudo xcode-select -switch /Applications/Xcode_14.2.app 389 | - uses: actions/cache/restore@v4 390 | id: cache 391 | with: 392 | path: protobuf-build 393 | key: protobuf-macos-x64 394 | lookup-only: true 395 | - uses: actions/checkout@v3 396 | if: env.HAVE_SECRET && steps.cache.outputs.cache-hit != 'true' 397 | with: 398 | repository: ${{ inputs.MacOSX1014sdkRepo}} 399 | ref: ${{ inputs.MacOSX1014sdkRef }} 400 | ssh-key: ${{ secrets.MacOSX1014sdk }} 401 | path: MacOSX10.14.sdk 402 | env: 403 | HAVE_SECRET: ${{ secrets.MacOSX1014sdk && '1' || '' }} 404 | - uses: actions/checkout@v1 405 | if: env.MISSING_SECRET && steps.cache.outputs.cache-hit != 'true' 406 | with: 407 | repository: phracker/MacOSX-SDKs 408 | ref: refs/heads/master 409 | env: 410 | MISSING_SECRET: ${{ !secrets.MacOSX1014sdk && '1' || '' }} 411 | - name: Update env 412 | if: steps.cache.outputs.cache-hit != 'true' 413 | run: | 414 | echo MACOSX_DEPLOYMENT_TARGET=10.10.0 > $GITHUB_ENV 415 | echo SDKROOT=${{ github.workspace }}/${{ secrets.MacOSX1014sdk && 'MacOSX10.14.sdk' || '../MacOSX-SDKs/MacOSX10.13.sdk' }} >> $GITHUB_ENV 416 | - name: Prepare Legacy sdk 417 | if: steps.cache.outputs.cache-hit != 'true' 418 | run: | 419 | cd "$SDKROOT/usr/include" 420 | ln -s "$(xcrun --sdk macosx --show-sdk-path)/usr/include/c++" c++ 421 | - name: Install brew dependencies 422 | if: steps.cache.outputs.cache-hit != 'true' 423 | run: | 424 | brew install autoconf || : 425 | brew install automake || : 426 | brew install libtool || : 427 | - name: Get Source Protobuf 428 | if: steps.cache.outputs.cache-hit != 'true' 429 | run: | 430 | git clone https://github.com/protocolbuffers/protobuf.git -b 21.x protobuf 431 | git -C protobuf submodule update --init --recursive 432 | - name: Build Protobuf 433 | if: steps.cache.outputs.cache-hit != 'true' 434 | run: | 435 | mkdir -p "$GITHUB_WORKSPACE/protobuf-build" 436 | ./autogen.sh 437 | ./configure --prefix="$GITHUB_WORKSPACE/protobuf-build" 438 | make -j8 439 | make install -j8 440 | working-directory: protobuf 441 | - uses: actions/cache/save@v4 442 | if: steps.cache.outputs.cache-hit != 'true' 443 | with: 444 | path: protobuf-build 445 | key: protobuf-macos-x64 446 | build-m1: 447 | if: inputs.build-m1 448 | uses: ./.github/workflows/m1.yml 449 | with: 450 | mcpelauncher-manifest-repo: ${{ inputs.mcpelauncher-repo }} 451 | mcpelauncher-manifest-ref: ${{ inputs.mcpelauncher-ref }} 452 | submodule-refs: ${{ inputs.submodule-refs }} 453 | build: 454 | runs-on: macos-15-intel 455 | if: "!(cancelled() || failure())" 456 | needs: [build-libcxx, buildopenssl, buildangle, build-protobuf, build-m1] 457 | permissions: 458 | id-token: write # required to get an oidc token 459 | contents: read 460 | strategy: 461 | fail-fast: false 462 | matrix: 463 | include: 464 | - target: "10.10.0" 465 | micro: 0 466 | QT_BASE_URL: http://download.qt.io/online/qtsdkrepository/mac_x64/desktop/qt5_592/ 467 | QT_VERSION_SHORT: 5.9.2 468 | QT_VERSION: 5.9.2-0-201710050729 469 | QT_PACKAGE_PREFIX: qt.592. 470 | QT_PACKAGE_SUFFIX: clang_64 471 | QT_PREBUILT_SUFFIX: -MacOS-OSX_10_10-Clang-MacOS-OSX_10_10-X86_64 472 | extraflags: "--qtworkaround" 473 | - target: "10.12.0" 474 | micro: 1 475 | QT_BASE_URL: http://download.qt.io/online/qtsdkrepository/mac_x64/desktop/qt5_5113/ 476 | QT_VERSION_SHORT: 5.11.3 477 | QT_VERSION: 5.11.3-0-201811291904 478 | QT_PACKAGE_PREFIX: qt.qt5.5113. 479 | QT_PACKAGE_SUFFIX: clang_64 480 | QT_PREBUILT_SUFFIX: -MacOS-MacOS_10_12-Clang-MacOS-MacOS_10_12-X86_64 481 | - target: "10.13.0" 482 | micro: 2 483 | QT_BASE_URL: http://download.qt.io/online/qtsdkrepository/mac_x64/desktop/qt5_5150/ 484 | QT_VERSION_SHORT: 5.15.0 485 | QT_VERSION: 5.15.0-0-202005140805 486 | QT_PACKAGE_PREFIX: qt.qt5.5150. 487 | QT_PACKAGE_SUFFIX: clang_64 488 | QT_PREBUILT_SUFFIX: -MacOS-MacOS_10_13-Clang-MacOS-MacOS_10_13-X86_64 489 | env: 490 | CMAKE_OSX_ARCHITECTURES: x86_64 # Is this needed? archive member: libglfw3.a(cocoa_init.m.o) cputype (16777223) does not match previous archive members cputype (7) (all members must match) 491 | steps: 492 | #- name: Select Xcode 493 | # run: sudo xcode-select -switch /Applications/Xcode_14.2.app 494 | - name: Setup Vars 495 | id: setup-vars 496 | uses: actions/github-script@v7 497 | with: 498 | script: | 499 | core.setOutput("owner", context.repo.owner); 500 | core.setOutput("repo", context.repo.repo); 501 | core.setOutput("build-number", "" + (${{ github.run_number }} + ${{ inputs.offset }})); 502 | - uses: ChristopherHX/oidc@f8f35d97bc37ffbe779bb3ab8453920fedf6fb37 503 | id: oidc 504 | continue-on-error: true 505 | - uses: actions/checkout@v3 506 | with: 507 | repository: ${{ steps.oidc.outputs.job_workflow_repo_name_and_owner || inputs.submodule-refs && 'minecraft-linux/macos-builder' || github.repository }} 508 | ref: ${{ steps.oidc.outputs.job_workflow_repo_ref || inputs.submodule-refs && 'main' || github.sha || github.ref }} 509 | - name: Sync Submodule Sources 510 | if: ${{ !inputs.use-repo-files && inputs.submodule-refs }} 511 | uses: actions/github-script@v7 512 | with: 513 | github-token: none 514 | script: | 515 | var downloadRepo = async function(path, repo, ref) { 516 | await io.mkdirP(path); 517 | await exec.exec("git", ["init"], { cwd: path }); 518 | await exec.exec("git", ["remote", "add", "origin", repo], { cwd: path }); 519 | await exec.exec("git", ["fetch", "origin", ref], { cwd: path }); 520 | await exec.exec("git", ["reset", "--hard", "FETCH_HEAD"], { cwd: path }); 521 | await exec.exec("git", ["submodule", "update", "--init", "--recursive"], { cwd: path }); 522 | }; 523 | await downloadRepo("source/mcpelauncher", process.env.MCPELAUNCHER_REPO, process.env.MCPELAUNCHER_REF); 524 | await downloadRepo("source/mcpelauncher-ui", process.env.MCPELAUNCHER_UI_REPO, process.env.MCPELAUNCHER_UI_REF); 525 | await downloadRepo("source/msa", process.env.MSA_REPO, process.env.MSA_REF); 526 | var submoduleRefs = JSON.parse(process.env.SUBMODULEREFS); 527 | for(var submoduleRef of submoduleRefs) { 528 | await exec.exec("git", ["fetch", submoduleRef.origin || "origin", submoduleRef.ref], { cwd: `source/${submoduleRef.project}/${submoduleRef.path}` }); 529 | await exec.exec("git", ["checkout", "FETCH_HEAD"], { cwd: `source/${submoduleRef.project}/${submoduleRef.path}` }); 530 | } 531 | env: 532 | SUBMODULEREFS: ${{ inputs.submodule-refs }} 533 | MCPELAUNCHER_REPO: ${{ inputs.mcpelauncher-repo }} 534 | MCPELAUNCHER_REF: ${{ inputs.mcpelauncher-ref }} 535 | MCPELAUNCHER_UI_REPO: ${{ inputs.mcpelauncher-ui-repo }} 536 | MCPELAUNCHER_UI_REF: ${{ inputs.mcpelauncher-ui-ref }} 537 | MSA_REPO: ${{ inputs.msa-repo }} 538 | MSA_REF: ${{ inputs.msa-ref }} 539 | 540 | - name: download m1 angle 541 | if: inputs.build-m1 542 | uses: actions/download-artifact@v4 543 | with: 544 | name: angle-macos-latest-11.0-arm64 545 | path: "m1-artifacts" 546 | - name: download m1 openssl 547 | if: inputs.build-m1 548 | uses: actions/download-artifact@v4 549 | with: 550 | name: openssl-macos-latest-11.0-arm64 551 | path: "m1-artifacts" 552 | - name: download m1 mcpelauncher 553 | if: inputs.build-m1 554 | uses: actions/download-artifact@v4 555 | with: 556 | name: mcpelauncher-macos-latest-11.0-arm64 557 | path: "m1-artifacts" 558 | - name: Cache libcxx32 559 | id: libcxx32-llvm 560 | uses: actions/cache@v4 561 | env: 562 | cache-name: cache-libcxx32--macos-10-10-4 563 | with: 564 | path: libcxx32-build 565 | key: ${{ runner.os }}-build-${{ env.cache-name }} 566 | - name: Cache libcxx64 567 | id: libcxx64-llvm 568 | uses: actions/cache@v4 569 | env: 570 | cache-name: cache-libcxx64--macos-10-10-4 571 | with: 572 | path: libcxx64-build 573 | key: ${{ runner.os }}-build-${{ env.cache-name }} 574 | - name: Cache libcxx 575 | id: libcxx-llvm 576 | uses: actions/cache@v4 577 | env: 578 | cache-name: cache-libcxx--macos-10-10-4 579 | with: 580 | path: libcxx-build 581 | key: ${{ runner.os }}-build-${{ env.cache-name }} 582 | - name: Cache openssl 583 | uses: actions/cache@v4 584 | env: 585 | cache-name: cache-openssl-2 586 | with: 587 | path: ssl 588 | key: ${{ runner.os }}-build-${{ env.cache-name }} 589 | - name: Cache openssl32 590 | uses: actions/cache@v4 591 | env: 592 | cache-name: cache-openssl32-macos-10-10 593 | with: 594 | path: ssl32 595 | key: ${{ runner.os }}-build-${{ env.cache-name }} 596 | - name: Cache openssl64 597 | uses: actions/cache@v4 598 | env: 599 | cache-name: cache-openssl64-macos-10-10 600 | with: 601 | path: ssl64 602 | key: ${{ runner.os }}-build-${{ env.cache-name }} 603 | - name: patch ssl 604 | run: | 605 | cd ssl32 606 | rm -rf lib 607 | ln -s ../ssl/lib 608 | cd ../ssl64 609 | rm -rf lib 610 | ln -s ../ssl/lib 611 | - name: Cache angle 612 | if: steps.angle.outputs.cache-hit != 'true' 613 | uses: actions/cache@v4 614 | env: 615 | cache-name: cache-angle-3 616 | with: 617 | path: source/osx-angle-ci/artifacts 618 | key: ${{ runner.os }}-build-${{ env.cache-name }} 619 | - uses: actions/cache/restore@v4 620 | with: 621 | fail-on-cache-miss: true 622 | path: protobuf-build 623 | key: protobuf-macos-x64 624 | - name: brew install / link 625 | run: | 626 | brew install p7zip automake 627 | brew uninstall openssl@3 || : 628 | env: 629 | HOMEBREW_NO_AUTO_UPDATE: 1 630 | - name: Cache qt 631 | if: 'false' 632 | id: cache-qt 633 | uses: actions/cache@v4 634 | env: 635 | cache-name: cache-qt-macos-${{ matrix.target }} 636 | with: 637 | path: qt 638 | key: ${{ runner.os }}-build-${{ env.cache-name }} 639 | - name: Download Qt 640 | # if: steps.cache-qt.outputs.cache-hit != 'true' 641 | run: | 642 | ./download_qt.sh 643 | env: 644 | QT_BASE_URL: ${{ matrix.QT_BASE_URL }} 645 | QT_VERSION_SHORT: ${{ matrix.QT_VERSION_SHORT }} 646 | QT_VERSION: ${{ matrix.QT_VERSION }} 647 | QT_PACKAGE_PREFIX: ${{ matrix.QT_PACKAGE_PREFIX }} 648 | QT_PACKAGE_SUFFIX: ${{ matrix.QT_PACKAGE_SUFFIX }} 649 | QT_PREBUILT_SUFFIX: ${{ matrix.QT_PREBUILT_SUFFIX }} 650 | - uses: actions/checkout@v3 651 | if: env.HAVE_SECRET 652 | with: 653 | repository: ${{ inputs.MacOSX1014sdkRepo}} 654 | ref: ${{ inputs.MacOSX1014sdkRef }} 655 | ssh-key: ${{ secrets.MacOSX1014sdk }} 656 | path: MacOSX10.14.sdk 657 | env: 658 | HAVE_SECRET: ${{ secrets.MacOSX1014sdk && '1' || '' }} 659 | - uses: actions/checkout@v1 660 | if: env.MISSING_SECRET 661 | with: 662 | repository: phracker/MacOSX-SDKs 663 | ref: refs/heads/master 664 | env: 665 | MISSING_SECRET: ${{ !secrets.MacOSX1014sdk && '1' || '' }} 666 | - name: Update env 667 | run: | 668 | echo MACOSX_DEPLOYMENT_TARGET=${{ matrix.target }} > $GITHUB_ENV 669 | echo SDKROOT=${{ github.workspace }}/${{ secrets.MacOSX1014sdk && 'MacOSX10.14.sdk' || '../MacOSX-SDKs/MacOSX10.13.sdk' }} >> $GITHUB_ENV 670 | - name: Prepare Legacy sdk 671 | run: | 672 | cd "$SDKROOT/usr/include" 673 | ln -s "$(xcrun --sdk macosx --show-sdk-path)/usr/include/c++" c++ 674 | - name: Get Source libzip 675 | run: | 676 | git clone https://github.com/nih-at/libzip libzip 677 | git -C libzip checkout v1.9.2 678 | - name: Build libzip 679 | run: | 680 | cmake libzip -B libzip-build -DCMAKE_POLICY_VERSION_MINIMUM=4.0 -DBUILD_TOOLS=OFF -DBUILD_REGRESS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_DOC=OFF -DENABLE_BZIP2=OFF -DENABLE_LZMA=OFF -DENABLE_ZSTD=OFF -DENABLE_COMMONCRYPTO=OFF -DENABLE_GNUTLS=OFF -DENABLE_MBEDTLS=OFF -DENABLE_OPENSSL=OFF -DENABLE_WINDOWS_CRYPTO=OFF -DENABLE_FDOPEN=OFF 681 | cmake --build libzip-build --parallel 682 | sudo cmake --build libzip-build --target install --parallel 683 | - name: Install python dependencies # This is a throw away VM 684 | run: pip3 install --break-system-packages jinja2 ds_store 685 | 686 | - name: add deps to base app 687 | run: | 688 | sudo cp -R protobuf-build/* /usr/local/ 689 | mkdir -p base-app/Contents/Frameworks/ 690 | cp libcxx-build/* base-app/Contents/Frameworks/ 691 | cp ssl/lib/* base-app/Contents/Frameworks/ 692 | cp ./source/osx-angle-ci/artifacts/* base-app/Contents/Frameworks/ 693 | - name: add m1 build 694 | if: inputs.build-m1 695 | run: | 696 | mkdir -p base-app/Contents/Frameworks/ 697 | lipo -create m1-artifacts/lib/libssl.dylib base-app/Contents/Frameworks/libssl.dylib -output base-app/Contents/Frameworks/libssl.dylib 698 | lipo -create m1-artifacts/lib/libcrypto.dylib base-app/Contents/Frameworks/libcrypto.dylib -output base-app/Contents/Frameworks/libcrypto.dylib 699 | lipo -create m1-artifacts/libEGL.dylib base-app/Contents/Frameworks/libEGL.dylib -output base-app/Contents/Frameworks/libEGL.dylib 700 | lipo -create m1-artifacts/libGLESv2.dylib base-app/Contents/Frameworks/libGLESv2.dylib -output base-app/Contents/Frameworks/libGLESv2.dylib 701 | mkdir -p base-app/Contents/Resources/ 702 | cp -R m1-artifacts/share/* base-app/Contents/Resources/ 703 | mkdir -p base-app/Contents/MacOS/ 704 | cp m1-artifacts/bin/mcpelauncher-client base-app/Contents/MacOS/mcpelauncher-client-arm64-v8a 705 | chmod +x base-app/Contents/MacOS/mcpelauncher-client-arm64-v8a 706 | install_name_tool -add_rpath @loader_path/../Frameworks base-app/Contents/MacOS/mcpelauncher-client-arm64-v8a || : 707 | - name: Build 708 | run: | 709 | python3 __main__.py --qt-path qt/*/*${{ secrets.SPARKLE_ECDSA_PUB && format('{0} {1}', ' --update-sparkle-appcast https://github.com/${GITHUB_REPOSITORY}/releases/download/ng.dmg/appcast.xml --update-sparkle-ed-public-key ', secrets.SPARKLE_ECDSA_PUB) }} --app-root base-app --build-id ${{ steps.setup-vars.outputs.build-number }} --prettyversion "$(cat version.txt)-macOS-x86_64-0.${{ matrix.micro }}.${{ steps.setup-vars.outputs.build-number }}" --version "0.${{ matrix.micro }}.${{ steps.setup-vars.outputs.build-number }}" ${{ matrix.extraflags }}${{ !inputs.use-repo-files && inputs.submodule-refs && ' --skip-sync-sources' || '' }}${{ secrets.MacOSX1014sdk && ' --use-own-curl' || '' }} 710 | - name: Build .dmg 711 | run: python3 build_dmg.py 712 | - name: Generate Dist 713 | run: | 714 | DMG_FILENAME="Minecraft_Bedrock_Launcher_$(cat version.txt)-macOS-x86_64-0.${{ matrix.micro }}.${{ steps.setup-vars.outputs.build-number }}_macOS_${{ matrix.target }}.dmg" 715 | mkdir -p dist 716 | mv "${{ github.workspace }}/output/Minecraft Bedrock Launcher.dmg" "dist/${DMG_FILENAME}" 717 | - name: Upload Build Artifact 718 | uses: actions/upload-artifact@v4 719 | with: 720 | name: dmg-${{ matrix.target }} 721 | path: dist 722 | publish: 723 | runs-on: macos-15-intel 724 | needs: build 725 | # Eventually extend this job to be able to run on other repositories, otherwise replace the owner and repository name in this job 726 | if: ${{ !cancelled() && inputs.publish }} 727 | steps: 728 | - uses: actions/checkout@v3 729 | - name: Setup Env 730 | run: | 731 | echo "DMG_VERSION=$(cat version.txt)" >> $GITHUB_ENV 732 | - name: Setup Vars 733 | id: setup-vars 734 | uses: actions/github-script@v7 735 | with: 736 | script: | 737 | core.setOutput("owner", context.repo.owner); 738 | core.setOutput("repo", context.repo.repo); 739 | core.setOutput("build-number", "" + (${{ github.run_number }} + ${{ inputs.offset }})); 740 | - name: Download everything 741 | uses: actions/download-artifact@v4 742 | with: 743 | path: sparkle 744 | pattern: dmg-* 745 | - name: Download sparkle 746 | run: | 747 | curl -L -C - -o sparkle.tar.xz https://github.com/sparkle-project/Sparkle/releases/download/1.26.0/Sparkle-1.26.0.tar.xz 748 | tar -xf ./sparkle.tar.xz 749 | - name: Set up Python 3.9 750 | uses: actions/setup-python@v5 751 | with: 752 | python-version: 3.9 753 | - name: Download some old dmg's and generate deltas 754 | shell: python 755 | run: | 756 | from os import makedirs, fsencode, fsdecode, listdir, path, rename, getenv 757 | import xml.etree.ElementTree as ET 758 | from subprocess import check_call 759 | makedirs('dist') 760 | makedirs('dist2') 761 | check_call(['curl', '-L', '-o', path.abspath(path.join('sparkle', 'appcast.xml')), 'https://github.com/${{ github.repository }}/releases/download/ng.dmg/appcast.xml']) 762 | tree = ET.parse(path.join('sparkle', 'appcast.xml')) 763 | root = tree.getroot() 764 | i = 0 765 | for rank in root.iter('item'): 766 | enc = rank.find('enclosure') 767 | url = enc.get('url') 768 | check_call(['curl', '-L', '-o', path.abspath(path.join('sparkle', url[url.rfind('/')+1:])), url]) 769 | 770 | directory = fsencode('sparkle') 771 | for file in listdir(directory): 772 | filename = fsdecode(file) 773 | if filename.endswith(".dmg"): 774 | print(filename) 775 | macindex = filename.rindex('macOS_') + 6 776 | if macindex == 5: 777 | continue 778 | destdirname = path.join('sparkle', filename[macindex:len(filename)-4]) 779 | print(destdirname) 780 | if not path.isdir(destdirname): 781 | makedirs(destdirname) 782 | rename(path.join('sparkle', filename), path.join(destdirname, filename)) 783 | 784 | tagname = 'invalid' 785 | with open('version.txt', 'r') as file: 786 | tagname = file.read().replace('\n', '') + '-' + getenv('BUILD_NUMBER') 787 | 788 | print(tagname) 789 | def dumpfile(f): 790 | print('dumpfile: ' + f) 791 | with open(f, 'r') as file: 792 | print(file.read()) 793 | 794 | for file in listdir(directory): 795 | ver = path.join('sparkle', fsdecode(file)) 796 | if not path.isdir(ver): 797 | continue 798 | founddmg = False 799 | for file in listdir(ver): 800 | filename = fsdecode(file) 801 | if filename.endswith(".dmg"): 802 | founddmg = True 803 | break 804 | if not founddmg: 805 | continue 806 | print(ver) 807 | dumpfile(path.join('sparkle', 'appcast.xml')) 808 | rename(path.join('sparkle', 'appcast.xml'), path.join(ver, 'appcast.xml')) 809 | dumpfile(path.join(ver, 'appcast.xml')) 810 | check_call(['./bin/generate_appcast', '-s', '${{ secrets.SPARKLE_ECDSA }}', '--download-url-prefix', 'https://github.com/${{ github.repository }}/releases/download/' + tagname + '/', ver ]) 811 | dumpfile(path.join(ver, 'appcast.xml')) 812 | rename(path.join(ver, 'appcast.xml'), path.join('sparkle', 'appcast.xml')) 813 | dumpfile(path.join('sparkle', 'appcast.xml')) 814 | for file in listdir(ver): 815 | filename = fsdecode(file) 816 | if filename.endswith(".delta") or (filename.endswith(".dmg") and filename.find(getenv('BUILD_NUMBER') + '_macOS_') != -1): 817 | print(filename) 818 | rename(path.join(ver, filename), path.join('dist2', filename)) 819 | 820 | def register_all_namespaces(filename): 821 | namespaces = dict([node for _, node in ET.iterparse(filename, events=['start-ns'])]) 822 | for ns in namespaces: 823 | ET.register_namespace(ns, namespaces[ns]) 824 | 825 | dumpfile(path.join('sparkle', 'appcast.xml')) 826 | register_all_namespaces(path.join('sparkle', 'appcast.xml')) 827 | # Revert url changes 828 | tree2 = ET.parse(path.join('sparkle', 'appcast.xml')) 829 | root2 = tree2.getroot() 830 | for rank in root2.iter('item'): 831 | enc = rank.find('enclosure') 832 | title = rank.find('title').text 833 | for rank2 in root.iter('item'): 834 | if title == rank2.find('title').text: 835 | enc.set('url', rank2.find('enclosure').get('url')) 836 | print(enc.get('url')) 837 | break 838 | tree2.write(path.join('dist', 'appcast.xml'), encoding='utf-8', xml_declaration=True) 839 | dumpfile(path.join('dist', 'appcast.xml')) 840 | tree2.write(path.join('dist2', 'appcast.xml'), encoding='utf-8', xml_declaration=True) 841 | if: env.HAVE_SECRET 842 | id: files-updated 843 | env: 844 | HAVE_SECRET: ${{ secrets.SPARKLE_ECDSA && '1' || '' }} 845 | BUILD_NUMBER: ${{ steps.setup-vars.outputs.build-number }} 846 | - name: download ghr 847 | run: | 848 | curl -L https://github.com/tcnksm/ghr/releases/download/v0.13.0/ghr_v0.13.0_darwin_amd64.zip --output ghr.zip 849 | unzip ghr.zip 850 | - name: Upload ${{ github.ref == 'refs/heads/main' && !contains(github.event.head_commit.message, '[DRAFT]' && !inputs.draft) && 'Latest' || 'Draft' }} 851 | if: steps.files-updated.result != 'skipped' 852 | run: | 853 | ./ghr*/ghr -c ${{ github.sha }} -t ${{ secrets.GITHUB_TOKEN }} -u ${{ steps.setup-vars.outputs.owner }} -r ${{ steps.setup-vars.outputs.repo }} ${{ !(github.ref == 'refs/heads/main' && !contains(github.event.head_commit.message, '[DRAFT]') && !inputs.draft) && '-draft ' || '' }}-b "$LAUNCHER_RELEASE_DESCRIPTION$(cat changelog.txt)" "$(cat version.txt)-${{ steps.setup-vars.outputs.build-number }}" dist2/ 854 | env: 855 | LAUNCHER_RELEASE_DESCRIPTION: | 856 | Links for linux flatpak or AppImage can be found on our wiki https://minecraft-linux.github.io. 857 | 858 | > [!WARNING] 859 | > The current macOS port is about to stop receiving Minecraft updates in March 2025 860 | > mojang is going to make OpenGL ES 3.1 required 861 | 862 | > [!CAUTION] 863 | > - You need to own Minecraft on the google play store and login with your google account to use this launcher 864 | > - Only mac models first sold in 2012 or later can run versions after Minecraft 1.20.15 865 | 866 | > [!IMPORTANT] 867 | > - There is no arm64 dmg file 868 | > - use the intel dmg for macOS 10.13 or newer 869 | > - the game itself will run on arm64 870 | > - Hi CPU Load 871 | > - VSync is broken when not opt in to Metal in Profile Editor 872 | > - Metal Mode may cause a black Screen on game versions after 1.18.15 873 | > - The performance is better for linux, because we don't have to translate the Graphic Api 874 | 875 | [Download link for intel or amd based 64bit systems ( known as amd64, intel64 and x86_64 e.g. most PC's or Laptops )](https://github.com/${{ github.repository }}/releases/download/${{env.DMG_VERSION}}-${{ steps.setup-vars.outputs.build-number }}/Minecraft_Bedrock_Launcher_${{env.DMG_VERSION}}-macOS-x86_64-0.2.${{ steps.setup-vars.outputs.build-number }}_macOS_10.13.0.dmg) 876 | 877 | We don't support macOS 10.10 - 10.12, but are still providing releases for them under assets. 878 | 879 | macOS x86_64 has no native OpenGL ES 2 or 3 framework 880 | - translating the api via google/angle to OpenGL (Metal opt in, due to bug reports) 881 | - possible more frame drops compared to linux 882 | 883 | No sound on unsupported ancient mac's from pre 2012 in i386 compatibility mode 884 | 885 | macOS/m1 mode is experimental and is very unstable, **since macOS 14 you are no longer able to use the intel game client and have to use the m1/arm64-v8 game client** 886 | Please leave a comment https://github.com/minecraft-linux/mcpelauncher-manifest/discussions/819 if the arm64 game launcher doesn't work at all on your m1/m2 mac, together with the whole log file of the crash or the log after a force quit 887 | 888 | # Not available Features you may miss 889 | - Xbox live friend joining 890 | - usually times out or crashs the game in both directions 891 | - consider using the offical server software 892 | - connect all by ip as external server 893 | - Xbox live login 894 | - a lot of devices seem to get error code "drowned" without beeing asked for login 895 | - error code "drowned" has more meanings like you closed the webview window without sign in 896 | - there is no resolution for those getting this error 897 | - programs that rewrite http requests sent by this launcher could also cause this problem 898 | - all xbox http requests are signed by an ecdsa key 899 | - the second request using the token for sisu auth are always rejected by Xbox Live Servers with http code 403 Forbidden 900 | - this problem is not reproducable for developers 901 | 902 | ### Changelog 903 | - name: Publish release 904 | if: steps.files-updated.result != 'skipped' && !contains(github.event.head_commit.message, '[DRAFT]') && !inputs.draft 905 | run: | 906 | ./ghr*/ghr -t ${{ secrets.GITHUB_TOKEN }} -u ${{ steps.setup-vars.outputs.owner }} -r ${{ steps.setup-vars.outputs.repo }} -replace ng.dmg dist/ 907 | --------------------------------------------------------------------------------