Support Apple Silicon via Rosetta2 on MacOS Sequoia and Above (#3754)

This commit is contained in:
Tyler Wilding 2024-11-10 11:06:56 -05:00 committed by GitHub
parent e3efede029
commit f8058f2138
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 120 additions and 17 deletions

View File

@ -52,11 +52,9 @@ jobs:
cmakePreset: "Release-macos-clang"
cachePrefix: ""
# Q4 2023 there will hopefully be native arm64 runners
# https://github.com/github/roadmap/issues/528
# build_macos_arm:
# name: "🍎 MacOS"
# uses: ./.github/workflows/macos-build-arm.yaml
# with:
# cmakePreset: "Release-macos-clang"
# cachePrefix: ""
build_macos_arm:
name: "🍎 MacOS"
uses: ./.github/workflows/macos-build-arm.yaml
with:
cmakePreset: "Release-macos-rosetta-clang"
cachePrefix: ""

View File

@ -13,18 +13,15 @@ on:
jobs:
build:
name: ARM
runs-on: macos-12
runs-on: macos-15
timeout-minutes: 120
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Set up ARM64 environment
run: sudo softwareupdate --install-rosetta --agree-to-license
- name: Install Package Dependencies
run: arch -arm64 brew install cmake ninja
run: brew install cmake ninja nasm
- name: Setup sccache
uses: hendrikmuhs/ccache-action@v1.2.14
@ -52,7 +49,7 @@ jobs:
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: opengoal-macos-${{ inputs.cachePrefix }}
name: opengoal-macos-arm-${{ inputs.cachePrefix }}
if-no-files-found: error
path: |
./build/goalc/goalc

View File

@ -79,6 +79,17 @@ jobs:
uploadArtifacts: true
secrets: inherit
build_macos_arm:
needs:
- cut_release
name: "🍎 MacOS"
uses: ./.github/workflows/macos-build.yaml
with:
cmakePreset: "Release-macos-rosetta-clang-static"
cachePrefix: "static"
uploadArtifacts: true
secrets: inherit
# Upload the Artifacts
upload_artifacts:
if: github.repository == 'open-goal/jak-project'
@ -87,6 +98,7 @@ jobs:
- build_windows_clang
- build_linux_clang
- build_macos_intel
- build_macos_arm
name: "Upload Artifacts"
runs-on: ubuntu-latest
steps:
@ -124,7 +136,7 @@ jobs:
7z a -tzip ./ci-artifacts/final/opengoal-windows-${TAG_VAL}.zip ./ci-artifacts/windows/*
cp ./ci-artifacts/opengoal-windows-static/lsp.exe ./ci-artifacts/final/opengoal-lsp-windows-${TAG_VAL}.exe
- name: Prepare macOS Build Assets
- name: Prepare Intel macOS Build Assets
run: |
mkdir -p ./ci-artifacts/macos
./.github/scripts/releases/extract_build_unix.sh ./ci-artifacts/macos ./ci-artifacts/opengoal-macos-static ./
@ -135,6 +147,17 @@ jobs:
chmod +x ./ci-artifacts/opengoal-macos-static/lsp/lsp
cp ./ci-artifacts/opengoal-macos-static/lsp/lsp ./ci-artifacts/final/opengoal-lsp-macos-intel-${TAG_VAL}.bin
- name: Prepare ARM macOS Build Assets
run: |
mkdir -p ./ci-artifacts/macos-arm
./.github/scripts/releases/extract_build_unix.sh ./ci-artifacts/macos-arm ./ci-artifacts/opengoal-macos-arm-static ./
pushd ci-artifacts/macos-arm
TAG_VAL=${{ needs.cut_release.outputs.new_tag }}
tar czf ../final/opengoal-macos-arm-${TAG_VAL}.tar.gz .
popd
chmod +x ./ci-artifacts/opengoal-macos-arm-static/lsp/lsp
cp ./ci-artifacts/opengoal-macos-arm-static/lsp/lsp ./ci-artifacts/final/opengoal-lsp-macos-arm-${TAG_VAL}.bin
- name: Upload Assets
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -2,9 +2,13 @@
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project(jak)
include(CTest)
# Options
option(BUILD_X86_ON_MACOS "Builds the project for macOS for Rosetta 2" OFF)
# Include third-party modules
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/third-party/cmake/modules/)
@ -119,7 +123,11 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
# pin to AVX for macOS, hopefully all macOS runners have atleast this architecture
# technically speaking, SSE4 is the cutoff for Apple Silicon so...only a matter of time!
if(NOT CMAKE_CXX_COMPILER_TARGET STREQUAL "arm64-apple-darwin")
if (BUILD_X86_ON_MACOS)
message("Targetting x86 on macOS via Rosetta 2 (requires Sequoia)")
set(CMAKE_OSX_ARCHITECTURES "x86_64")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx")
elseif(NOT CMAKE_CXX_COMPILER_TARGET STREQUAL "arm64-apple-darwin")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx")
endif()

View File

@ -164,6 +164,15 @@
"description": "Build with Clang as Release without Debug Symbols",
"inherits": ["base-macos-release", "base-clang"]
},
{
"name": "Release-macos-rosetta-clang",
"displayName": "MacOS Release Rosetta (clang)",
"description": "Build with Clang as Release without Debug Symbols",
"inherits": ["base-macos-release", "base-clang"],
"cacheVariables": {
"BUILD_X86_ON_MACOS": "ON"
}
},
{
"name": "Release-macos-clang-static",
"displayName": "MacOS Static Release (clang)",
@ -174,6 +183,17 @@
"ZYDIS_BUILD_SHARED_LIB": "OFF"
}
},
{
"name": "Release-macos-rosetta-clang-static",
"displayName": "MacOS Rosetta Static Release (clang)",
"description": "Build with Clang as Release without Debug Symbols but statically linked, requires MacOS Sequoia",
"inherits": ["base-macos-release", "base-clang"],
"cacheVariables": {
"BUILD_X86_ON_MACOS": "ON",
"STATICALLY_LINK": "true",
"ZYDIS_BUILD_SHARED_LIB": "OFF"
}
},
{
"name": "Release-linux-clang-asan",
"displayName": "Linux Release (clang-asan)",

View File

@ -67,6 +67,14 @@ tasks:
cmds:
- "{{.GK_BIN_RELEASE_DIR}}/gk -v --game {{.GAME}} -- -fakeiso -debug"
# DEVELOPMENT
gen-cmake:
desc: "Generate the CMake"
cmds:
- "cmake -B build --preset={{.CMAKE_PRESET}}"
build:
desc: "Build the project using the generated CMake"
cmds:
- "cmake --build build --parallel {{.CMAKE_NUM_THREADS}}"
repl:
desc: "Start the REPL"
preconditions:

View File

@ -3,6 +3,13 @@
#include "common/common_types.h"
#include "common/log/log.h"
#ifdef __APPLE__
#include <stdio.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#endif
#ifdef _WIN32
// clang-format off
#define NOMINMAX
@ -104,3 +111,23 @@ void setup_cpu_info() {
CpuInfo& get_cpu_info() {
return gCpuInfo;
}
std::optional<double> get_macos_version() {
#ifndef __APPLE__
return {};
#else
char buffer[128];
size_t bufferlen = 128;
auto ok = sysctlbyname("kern.osproductversion", &buffer, &bufferlen, NULL, 0);
if (ok != 0) {
lg::warn("Unable to check for `kern.osproductversion` to determine macOS version");
return {};
}
try {
return std::stod(buffer);
} catch (std::exception& e) {
lg::error("Error occured when attempting to convert sysctl value {} to number", buffer);
return {};
}
#endif
}

View File

@ -1,6 +1,7 @@
#pragma once
#include <cstddef>
#include <optional>
#include <string>
size_t get_peak_rss();
@ -16,3 +17,5 @@ struct CpuInfo {
};
CpuInfo& get_cpu_info();
std::optional<double> get_macos_version();

View File

@ -1,7 +1,10 @@
# Set a more convenient ARM flag
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64" AND (NOT BUILD_X86_ON_MACOS))
set(ARM64_ARCH TRUE)
message(STATUS "ARM64 architecture detected")
elseif()
set(ARM64_ARCH FALSE)
message(STATUS "Forcefully targetting x86 via Rosetta 2")
else()
set(ARM64_ARCH FALSE)
message(STATUS "Non-ARM64 architecture detected")

View File

@ -179,10 +179,26 @@ int main(int argc, char** argv) {
setup_cpu_info();
// If the CPU doesn't have AVX, GOAL code won't work and we exit.
if (!get_cpu_info().has_avx) {
// Check if we are on a modern enough version of macOS so that AVX can be
// emulated via rosetta
#ifdef __APPLE__
auto macos_version = get_macos_version();
if (macos_version < 15.0) {
lg::info(
"Your CPU does not support AVX. But the newer version of Rosetta supports it, update to "
"atleast Sequoia to run OpenGOAL!");
dialogs::create_error_message_dialog(
"Unmet Requirements",
"Your CPU does not support AVX. But the newer version of Rosetta supports it, update to "
"atleast Sequoia to run OpenGOAL!");
return -1;
}
#else
lg::info("Your CPU does not support AVX, which is required for OpenGOAL.");
dialogs::create_error_message_dialog(
"Unmet Requirements", "Your CPU does not support AVX, which is required for OpenGOAL.");
return -1;
#endif
}
// set up file paths for resources. This is the full repository when developing, and the data