├── 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 |
--------------------------------------------------------------------------------