macOS universal binary, take 2

- Add new target `macos-lipo`.
   - Created by compiling a universal x86 binary (no PGO) and a standard Apple silicon binary (with PGO), then combining them into a Mach-O fat binary
   - To keep only one copy of the net, we add custom loading logic in the x86 section. The executable reads its own path and mmaps the net that's in the ARM section.
       - The offset and size (from the executable base) of the mapping is injected after compilation in `patch_x86_slice.sh`
   - avx512 on macOS isn't advertised in the xcr0 register by default. The simple solution I came up with is to execute a dummy AVX512 instruction, which sets up the register, before calling `__builtin_cpu_init`.

Some housekeeping as well:
- Rename `armv8-universal` -> `arm64-universal`.
- Add standard copyright headers to the files we've added recently.

Potential follow-ups:
- Disservin's Makefile cleanup
- Alternative ideas for the net loading. In particular, this will error out if the user strips the binary (since that'll invalidate the offset).

closes https://github.com/official-stockfish/Stockfish/pull/6860

No functional change

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
anematode
2026-05-29 19:05:53 +02:00
committed by Joost VandeVondele
co-authored by Copilot Autofix powered by AI
parent 24a551899e
commit 8cbca11a53
14 changed files with 441 additions and 198 deletions
+2 -2
View File
@@ -22,12 +22,12 @@
}
],
"binaries": [
"armv8-universal",
"arm64-universal",
"armv7-neon"
],
"exclude": [
{
"binaries": "armv8-universal",
"binaries": "arm64-universal",
"config": {
"compiler": "armv7a-linux-androideabi29-clang++"
}
-28
View File
@@ -1,28 +0,0 @@
{
"include": [
{
"config": {
"name": "macOS 15 Apple Clang",
"os": "macos-15-intel",
"simple_name": "macos",
"compiler": "clang++",
"comp": "clang",
"shell": "bash",
"archive_ext": "tar.gz"
},
"binaries": "x86-64-bmi2"
},
{
"config": {
"name": "macOS 15 Apple Clang M1",
"os": "macos-15",
"simple_name": "macos-m1",
"compiler": "clang++",
"comp": "clang",
"shell": "bash",
"archive_ext": "tar.gz"
},
"binaries": "apple-silicon"
}
]
}
+9
View File
@@ -37,6 +37,15 @@
"archive_ext": "zip"
},
"binaries": "arm64-universal"
},
{
"config": {
"name": "macOS 15 Apple Clang Universal",
"os": "macos-15",
"simple_name": "macos",
"archive_ext": "tar.gz"
},
"binaries": "universal"
}
]
}
-94
View File
@@ -1,94 +0,0 @@
name: Compilation
on:
workflow_call:
inputs:
matrix:
type: string
required: true
jobs:
Compilation:
name: ${{ matrix.config.name }} ${{ matrix.binaries }}
runs-on: ${{ matrix.config.os }}
env:
COMPCXX: ${{ matrix.config.compiler }}
COMP: ${{ matrix.config.comp }}
EXT: ${{ matrix.config.ext }}
NAME: ${{ matrix.config.simple_name }}
BINARY: ${{ matrix.binaries }}
SDE: ${{ matrix.config.sde }}
strategy:
fail-fast: false
matrix: ${{ fromJson(inputs.matrix) }}
defaults:
run:
working-directory: src
shell: ${{ matrix.config.shell }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Install fixed GCC on Linux
if: runner.os == 'Linux'
uses: egor-tensin/setup-gcc@a2861a8b8538f49cf2850980acccf6b05a1b2ae4 # v2.0
with:
version: 11
- name: Setup msys and install required packages
if: runner.os == 'Windows'
uses: msys2/setup-msys2@e9898307ac31d1a803454791be09ab9973336e1c # v2.31.1
with:
msystem: ${{ matrix.config.msys_sys }}
install: mingw-w64-${{ matrix.config.msys_env }} make git zip
- name: Download SDE package
if: ${{ matrix.config.sde }}
uses: petarpetrovt/setup-sde@d230e06df0ca06ced70000e4a7fa62afc9a2001e # v4.0
with:
environmentVariableName: SDE_DIR
sdeVersion: 9.58.0
- name: Download the used network from the fishtest framework
run: make net
- name: Check compiler
run: $COMPCXX -v
- name: Test help target
run: make help
- name: Check git
run: git --version
- name: Check compiler
run: $COMPCXX -v
- name: Show compiler cpu info
run: |
if [[ "$COMPCXX" == clang* ]]; then
$COMPCXX -E - -march=native -###
else
$COMPCXX -Q -march=native --help=target
fi
# Compile the configured release binary.
- name: Compile ${{ matrix.config.binaries }} build
run: |
make clean
make -j4 profile-build ARCH=$BINARY COMP=$COMP RUN_PREFIX="$SDE"
make strip ARCH=$BINARY COMP=$COMP
RUN_PREFIX="$SDE" ../tests/signature.sh $benchref
mv ./stockfish$EXT ../stockfish-$NAME-$BINARY$EXT
- name: Remove non src files
run: git clean -fxd
- name: Upload artifact for (pre)-release
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ matrix.config.simple_name }} ${{ matrix.binaries }}
path: |
.
!.git
!.output
+1 -23
View File
@@ -21,7 +21,7 @@ jobs:
name: Prerelease
if: github.repository == 'official-stockfish/Stockfish' && (github.ref == 'refs/heads/master' || (startsWith(github.ref_name, 'sf_') && github.ref_type == 'tag'))
runs-on: ubuntu-latest
needs: [Matrix, Compilation, ARMCompilation, UniversalCompilation]
needs: [Matrix, ARMCompilation, UniversalCompilation]
permissions:
contents: write # For deleting/creating a prerelease
steps:
@@ -112,17 +112,12 @@ jobs:
name: Prepare matrices
runs-on: ubuntu-latest
outputs:
macos_matrix: ${{ steps.set-macos-matrix.outputs.macos_matrix }}
arm_matrix: ${{ steps.set-arm-matrix.outputs.arm_matrix }}
universal_matrix: ${{ steps.set-universal-matrix.outputs.universal_matrix }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- id: set-macos-matrix
run: |
MACOS_MATRIX=$(jq -c '.' .github/ci/macos_matrix.json)
echo "MACOS_MATRIX=$MACOS_MATRIX" >> $GITHUB_OUTPUT
- id: set-arm-matrix
run: |
ARM_MATRIX=$(jq -c '.' .github/ci/arm_matrix.json)
@@ -156,12 +151,6 @@ jobs:
if: ${{ always() }}
uses: ./.github/workflows/avx2_compilers.yml
# Release Jobs
Compilation:
name: macOS builds
needs: [Matrix, Sanitizers, Tests, Matetrack, Games, CompilerCheck]
uses: ./.github/workflows/compilation.yml
with:
matrix: ${{ needs.Matrix.outputs.macos_matrix }}
ARMCompilation:
name: Android builds
needs: [Matrix, Sanitizers, Tests, Matetrack, Games, CompilerCheck]
@@ -172,17 +161,6 @@ jobs:
name: "Universal builds"
needs: [Matrix, Sanitizers, Tests, Matetrack, Games, CompilerCheck]
uses: ./.github/workflows/universal_compilation.yml
Binaries:
if: github.repository == 'official-stockfish/Stockfish'
name: macOS uploads
needs: [Prerelease, Matrix]
uses: ./.github/workflows/upload_binaries.yml
with:
matrix: ${{ needs.Matrix.outputs.macos_matrix }}
permissions:
contents: write # For deleting/creating a (pre)release
secrets:
token: ${{ secrets.GITHUB_TOKEN }}
ARM_Binaries:
if: github.repository == 'official-stockfish/Stockfish'
name: Android uploads
@@ -217,3 +217,40 @@ jobs:
.
!.git
!.output
UniversalMacOS:
name: macOS
runs-on: macos-15
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
fetch-depth: 0
# macos-15 is Apple silicon; Rosetta 2 is needed to exercise the x86-64 slice
- name: Install Rosetta 2
run: softwareupdate --install-rosetta --agree-to-license
- name: Build universal binary
run: make -j4 -C src macos-lipo COMP=clang
- name: Rename binary
run: mv src/stockfish stockfish-macos-universal
- name: Verify binary runs natively and under Rosetta
run: ./scripts/check_universal_macos.sh ./stockfish-macos-universal
- name: Remove non-src files
run: git clean -fxd -- src
- name: Upload artifact for (pre)-release
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: macos universal
path: |
.
!.git
!.output