From ae0a1888a4e934904a2c0682f587e06edabc85aa Mon Sep 17 00:00:00 2001 From: Mostafa Nanticock <47303284+MostafaNanticock@users.noreply.github.com> Date: Sat, 18 Apr 2026 07:43:09 +0200 Subject: [PATCH 01/21] PM-227 Fixed MacOS builds for intel using Rosetta2 --- .github/workflows/_build-shared.yml | 26 +++++++++++++++++++++++--- .github/workflows/linux.yml | 2 ++ .github/workflows/macos.yml | 7 +++++-- .github/workflows/windows.yml | 2 ++ 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/.github/workflows/_build-shared.yml b/.github/workflows/_build-shared.yml index b6f8d8b..54d0dab 100644 --- a/.github/workflows/_build-shared.yml +++ b/.github/workflows/_build-shared.yml @@ -15,6 +15,10 @@ on: qt_version: required: true type: string + qt_arch: + required: false + type: string + default: '' jobs: build: @@ -27,24 +31,40 @@ jobs: shell: bash run: echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" + - name: Install Rosetta + # Needed when running on an ARM runner but targeting x86_64 (clang_64) Qt binaries + if: runner.os == 'macOS' && runner.arch == 'ARM64' && inputs.qt_arch == 'clang_64' + run: softwareupdate --install-rosetta --agree-to-license + + - name: Set arch prefix + id: arch + shell: bash + run: | + if [[ "${{ runner.os }}" == "macOS" && "${{ runner.arch }}" == "ARM64" && "${{ inputs.qt_arch }}" == "clang_64" ]]; then + echo "cmd=arch -x86_64" >> "$GITHUB_OUTPUT" + else + echo "cmd=" >> "$GITHUB_OUTPUT" + fi + - name: Install Qt uses: jurplel/install-qt-action@v4 with: version: ${{ inputs.qt_version }} + arch: ${{ inputs.qt_arch }} install-deps: 'true' set-env: 'true' - name: Configure CMake run: > - cmake -B ${{ steps.strings.outputs.build-output-dir }} + ${{ steps.arch.outputs.cmd }} cmake -B ${{ steps.strings.outputs.build-output-dir }} -DCMAKE_C_COMPILER=${{ inputs.c_compiler }} -DCMAKE_CXX_COMPILER=${{ inputs.cpp_compiler }} -DCMAKE_BUILD_TYPE=Release -S ${{ github.workspace }} - name: Build - run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config Release + run: ${{ steps.arch.outputs.cmd }} cmake --build ${{ steps.strings.outputs.build-output-dir }} --config Release - name: Test working-directory: ${{ steps.strings.outputs.build-output-dir }} - run: ctest --build-config Release + run: ${{ steps.arch.outputs.cmd }} ctest --build-config Release diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 0900949..32173d3 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -6,11 +6,13 @@ on: branches: [main, develop] paths-ignore: - '*.md' + - 'docs/**' pull_request: branches: [main, develop] paths-ignore: - '*.md' + - 'docs/**' jobs: get-matrix: diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 87c474c..942b806 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -6,11 +6,13 @@ on: branches: [main, develop] paths-ignore: - '*.md' + - 'docs/**' pull_request: branches: [main, develop] paths-ignore: - '*.md' + - 'docs/**' jobs: get-matrix: @@ -32,10 +34,11 @@ jobs: uses: ./.github/workflows/_build-shared.yml with: - os: macos-13 # Intel-based macOS + os: macos-latest # ARM runner; Intel binaries built and run via Rosetta 2 emulation c_compiler: ${{ matrix.c_compiler }} cpp_compiler: ${{ matrix.cpp_compiler }} qt_version: ${{ matrix.qt_version }} + qt_arch: clang_64 build-macos-arm: name: macos-${{ matrix.c_compiler }}-qt${{ matrix.qt_version }}-arm @@ -51,7 +54,7 @@ jobs: - c_compiler: clang cpp_compiler: clang++ exclude: - # Exclude Qt5 versions for ARM builds + # Qt5 has no native Apple Silicon (ARM64) support; ARM macOS binaries require Qt6+ - qt_version: "5.9.*" - qt_version: "5.12.*" - qt_version: "5.15.*" diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index bab5d35..f688330 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -6,11 +6,13 @@ on: branches: [main, develop] paths-ignore: - '*.md' + - 'docs/**' pull_request: branches: [main, develop] paths-ignore: - '*.md' + - 'docs/**' jobs: get-matrix: From 514248c327fe1bc7fbde3a539bf5a753df45de07 Mon Sep 17 00:00:00 2001 From: Mostafa Nanticock <47303284+MostafaNanticock@users.noreply.github.com> Date: Sat, 18 Apr 2026 07:56:57 +0200 Subject: [PATCH 02/21] PM-227 Fixed incorrect ctest flags for intel builds --- .github/workflows/_build-shared.yml | 30 ++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/_build-shared.yml b/.github/workflows/_build-shared.yml index 54d0dab..893166f 100644 --- a/.github/workflows/_build-shared.yml +++ b/.github/workflows/_build-shared.yml @@ -29,23 +29,22 @@ jobs: - name: Set reusable strings id: strings shell: bash - run: echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" - - - name: Install Rosetta - # Needed when running on an ARM runner but targeting x86_64 (clang_64) Qt binaries - if: runner.os == 'macOS' && runner.arch == 'ARM64' && inputs.qt_arch == 'clang_64' - run: softwareupdate --install-rosetta --agree-to-license - - - name: Set arch prefix - id: arch - shell: bash run: | + echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" + # When on an ARM runner targeting x86_64 Qt (clang_64), emit x86_64 output via + # -DCMAKE_OSX_ARCHITECTURES. cmake/build tools stay as native ARM64 binaries; + # only the compiled output is x86_64. Rosetta handles running x86_64 test binaries. if [[ "${{ runner.os }}" == "macOS" && "${{ runner.arch }}" == "ARM64" && "${{ inputs.qt_arch }}" == "clang_64" ]]; then - echo "cmd=arch -x86_64" >> "$GITHUB_OUTPUT" + echo "osx_arch_flag=-DCMAKE_OSX_ARCHITECTURES=x86_64" >> "$GITHUB_OUTPUT" else - echo "cmd=" >> "$GITHUB_OUTPUT" + echo "osx_arch_flag=" >> "$GITHUB_OUTPUT" fi + - name: Install Rosetta + # Needed so macOS can execute the x86_64 binaries produced when cross-compiling for Intel + if: runner.os == 'macOS' && runner.arch == 'ARM64' && inputs.qt_arch == 'clang_64' + run: softwareupdate --install-rosetta --agree-to-license + - name: Install Qt uses: jurplel/install-qt-action@v4 with: @@ -56,15 +55,16 @@ jobs: - name: Configure CMake run: > - ${{ steps.arch.outputs.cmd }} cmake -B ${{ steps.strings.outputs.build-output-dir }} + cmake -B ${{ steps.strings.outputs.build-output-dir }} -DCMAKE_C_COMPILER=${{ inputs.c_compiler }} -DCMAKE_CXX_COMPILER=${{ inputs.cpp_compiler }} -DCMAKE_BUILD_TYPE=Release + ${{ steps.strings.outputs.osx_arch_flag }} -S ${{ github.workspace }} - name: Build - run: ${{ steps.arch.outputs.cmd }} cmake --build ${{ steps.strings.outputs.build-output-dir }} --config Release + run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config Release - name: Test working-directory: ${{ steps.strings.outputs.build-output-dir }} - run: ${{ steps.arch.outputs.cmd }} ctest --build-config Release + run: ctest --build-config Release From ba4d6124ccb0e1fafab7d247594d47829c592bc8 Mon Sep 17 00:00:00 2001 From: Mostafa Nanticock <47303284+MostafaNanticock@users.noreply.github.com> Date: Sat, 18 Apr 2026 08:10:02 +0200 Subject: [PATCH 03/21] PM-227 Simplified Intel Build process --- .github/workflows/_build-shared.yml | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/.github/workflows/_build-shared.yml b/.github/workflows/_build-shared.yml index 893166f..2df474a 100644 --- a/.github/workflows/_build-shared.yml +++ b/.github/workflows/_build-shared.yml @@ -29,21 +29,22 @@ jobs: - name: Set reusable strings id: strings shell: bash - run: | - echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" - # When on an ARM runner targeting x86_64 Qt (clang_64), emit x86_64 output via - # -DCMAKE_OSX_ARCHITECTURES. cmake/build tools stay as native ARM64 binaries; - # only the compiled output is x86_64. Rosetta handles running x86_64 test binaries. - if [[ "${{ runner.os }}" == "macOS" && "${{ runner.arch }}" == "ARM64" && "${{ inputs.qt_arch }}" == "clang_64" ]]; then - echo "osx_arch_flag=-DCMAKE_OSX_ARCHITECTURES=x86_64" >> "$GITHUB_OUTPUT" - else - echo "osx_arch_flag=" >> "$GITHUB_OUTPUT" - fi + run: echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" - - name: Install Rosetta - # Needed so macOS can execute the x86_64 binaries produced when cross-compiling for Intel + - name: Set up environment for Intel (Rosetta 2) + # ARM runner targeting x86_64 Qt (clang_64): cross-compile for Intel and install + # Rosetta so the resulting x86_64 test binaries run transparently under emulation if: runner.os == 'macOS' && runner.arch == 'ARM64' && inputs.qt_arch == 'clang_64' - run: softwareupdate --install-rosetta --agree-to-license + shell: bash + run: | + softwareupdate --install-rosetta --agree-to-license + echo "CMAKE_ARCH_FLAGS=-DCMAKE_OSX_ARCHITECTURES=x86_64" >> "$GITHUB_ENV" + + - name: Set up environment for Apple Silicon + # Native ARM64 build; set architecture explicitly for clarity + if: runner.os == 'macOS' && runner.arch == 'ARM64' && inputs.qt_arch != 'clang_64' + shell: bash + run: echo "CMAKE_ARCH_FLAGS=-DCMAKE_OSX_ARCHITECTURES=arm64" >> "$GITHUB_ENV" - name: Install Qt uses: jurplel/install-qt-action@v4 @@ -59,7 +60,7 @@ jobs: -DCMAKE_C_COMPILER=${{ inputs.c_compiler }} -DCMAKE_CXX_COMPILER=${{ inputs.cpp_compiler }} -DCMAKE_BUILD_TYPE=Release - ${{ steps.strings.outputs.osx_arch_flag }} + ${{ env.CMAKE_ARCH_FLAGS }} -S ${{ github.workspace }} - name: Build From 2cffd556f98bd80dcc6c4c3dff034cd8f4300198 Mon Sep 17 00:00:00 2001 From: Mostafa Nanticock <47303284+MostafaNanticock@users.noreply.github.com> Date: Sat, 18 Apr 2026 08:27:58 +0200 Subject: [PATCH 04/21] PM-227 build pipeline structure cleanup phase1 --- .github/workflows/_build-shared.yml | 24 ++++++++++++------------ .github/workflows/macos.yml | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/_build-shared.yml b/.github/workflows/_build-shared.yml index 2df474a..ce683d9 100644 --- a/.github/workflows/_build-shared.yml +++ b/.github/workflows/_build-shared.yml @@ -31,20 +31,20 @@ jobs: shell: bash run: echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" - - name: Set up environment for Intel (Rosetta 2) - # ARM runner targeting x86_64 Qt (clang_64): cross-compile for Intel and install - # Rosetta so the resulting x86_64 test binaries run transparently under emulation - if: runner.os == 'macOS' && runner.arch == 'ARM64' && inputs.qt_arch == 'clang_64' + - name: Set up target architecture + # Runs only when qt_arch is specified (macOS matrix entries). + # clang_64 means the x86_64 Qt variant: cross-compile for Intel and install + # Rosetta so the resulting x86_64 test binaries execute under emulation. + # Any other non-empty qt_arch value means a native ARM64 build. + if: inputs.qt_arch != '' shell: bash run: | - softwareupdate --install-rosetta --agree-to-license - echo "CMAKE_ARCH_FLAGS=-DCMAKE_OSX_ARCHITECTURES=x86_64" >> "$GITHUB_ENV" - - - name: Set up environment for Apple Silicon - # Native ARM64 build; set architecture explicitly for clarity - if: runner.os == 'macOS' && runner.arch == 'ARM64' && inputs.qt_arch != 'clang_64' - shell: bash - run: echo "CMAKE_ARCH_FLAGS=-DCMAKE_OSX_ARCHITECTURES=arm64" >> "$GITHUB_ENV" + if [[ "${{ inputs.qt_arch }}" == "clang_64" ]]; then + softwareupdate --install-rosetta --agree-to-license + echo "CMAKE_ARCH_FLAGS=-DCMAKE_OSX_ARCHITECTURES=x86_64" >> "$GITHUB_ENV" + else + echo "CMAKE_ARCH_FLAGS=-DCMAKE_OSX_ARCHITECTURES=arm64" >> "$GITHUB_ENV" + fi - name: Install Qt uses: jurplel/install-qt-action@v4 diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 942b806..bc7aec7 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -34,7 +34,7 @@ jobs: uses: ./.github/workflows/_build-shared.yml with: - os: macos-latest # ARM runner; Intel binaries built and run via Rosetta 2 emulation + os: macos-latest c_compiler: ${{ matrix.c_compiler }} cpp_compiler: ${{ matrix.cpp_compiler }} qt_version: ${{ matrix.qt_version }} @@ -61,7 +61,7 @@ jobs: uses: ./.github/workflows/_build-shared.yml with: - os: macos-latest # Apple Silicon macOS + os: macos-latest c_compiler: ${{ matrix.c_compiler }} cpp_compiler: ${{ matrix.cpp_compiler }} qt_version: ${{ matrix.qt_version }} From 8fe8c4746c2e0211b6b8b5431b6a8c90d38d0d7e Mon Sep 17 00:00:00 2001 From: Mostafa Nanticock <47303284+MostafaNanticock@users.noreply.github.com> Date: Sat, 18 Apr 2026 08:34:32 +0200 Subject: [PATCH 05/21] PM-227 build pipeline structure cleanup phase2 --- .github/workflows/_build-shared.yml | 27 +++++++++++++++------------ .github/workflows/macos.yml | 3 +++ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/.github/workflows/_build-shared.yml b/.github/workflows/_build-shared.yml index ce683d9..a03036c 100644 --- a/.github/workflows/_build-shared.yml +++ b/.github/workflows/_build-shared.yml @@ -19,6 +19,14 @@ on: required: false type: string default: '' + target_arch: + required: false + type: string + default: '' + setup_script: + required: false + type: string + default: '' jobs: build: @@ -31,20 +39,15 @@ jobs: shell: bash run: echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" + - name: Run environment setup script + if: inputs.setup_script != '' + shell: bash + run: ${{ inputs.setup_script }} + - name: Set up target architecture - # Runs only when qt_arch is specified (macOS matrix entries). - # clang_64 means the x86_64 Qt variant: cross-compile for Intel and install - # Rosetta so the resulting x86_64 test binaries execute under emulation. - # Any other non-empty qt_arch value means a native ARM64 build. - if: inputs.qt_arch != '' + if: inputs.target_arch != '' shell: bash - run: | - if [[ "${{ inputs.qt_arch }}" == "clang_64" ]]; then - softwareupdate --install-rosetta --agree-to-license - echo "CMAKE_ARCH_FLAGS=-DCMAKE_OSX_ARCHITECTURES=x86_64" >> "$GITHUB_ENV" - else - echo "CMAKE_ARCH_FLAGS=-DCMAKE_OSX_ARCHITECTURES=arm64" >> "$GITHUB_ENV" - fi + run: echo "CMAKE_ARCH_FLAGS=-DCMAKE_OSX_ARCHITECTURES=${{ inputs.target_arch }}" >> "$GITHUB_ENV" - name: Install Qt uses: jurplel/install-qt-action@v4 diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index bc7aec7..c62bffa 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -39,6 +39,8 @@ jobs: cpp_compiler: ${{ matrix.cpp_compiler }} qt_version: ${{ matrix.qt_version }} qt_arch: clang_64 + target_arch: x86_64 + setup_script: 'softwareupdate --install-rosetta --agree-to-license' build-macos-arm: name: macos-${{ matrix.c_compiler }}-qt${{ matrix.qt_version }}-arm @@ -65,3 +67,4 @@ jobs: c_compiler: ${{ matrix.c_compiler }} cpp_compiler: ${{ matrix.cpp_compiler }} qt_version: ${{ matrix.qt_version }} + target_arch: arm64 From 573fba36c990790cf42220bd7d2dbbf209d6bf03 Mon Sep 17 00:00:00 2001 From: Mostafa Nanticock <47303284+MostafaNanticock@users.noreply.github.com> Date: Sat, 18 Apr 2026 08:58:17 +0200 Subject: [PATCH 06/21] PM-227 build pipeline structure cleanup phase3 --- .github/workflows/_build-shared.yml | 23 ++++++++++++----------- .github/workflows/macos.yml | 19 +++++++++++++++++-- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/.github/workflows/_build-shared.yml b/.github/workflows/_build-shared.yml index a03036c..9ccd91d 100644 --- a/.github/workflows/_build-shared.yml +++ b/.github/workflows/_build-shared.yml @@ -15,15 +15,11 @@ on: qt_version: required: true type: string - qt_arch: - required: false - type: string - default: '' target_arch: required: false type: string default: '' - setup_script: + qt_install_script: required: false type: string default: '' @@ -39,24 +35,29 @@ jobs: shell: bash run: echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" - - name: Run environment setup script - if: inputs.setup_script != '' - shell: bash - run: ${{ inputs.setup_script }} - - name: Set up target architecture if: inputs.target_arch != '' shell: bash run: echo "CMAKE_ARCH_FLAGS=-DCMAKE_OSX_ARCHITECTURES=${{ inputs.target_arch }}" >> "$GITHUB_ENV" - name: Install Qt + if: inputs.qt_install_script == '' uses: jurplel/install-qt-action@v4 with: version: ${{ inputs.qt_version }} - arch: ${{ inputs.qt_arch }} install-deps: 'true' set-env: 'true' + - name: Install Qt (custom) + # Runs when qt_install_script is provided. The script is fully responsible for + # installing Qt and configuring the environment (PATH, QT_ROOT_DIR, Qt_DIR, etc.). + # QT_VERSION is available as an environment variable with the requested version string. + if: inputs.qt_install_script != '' + shell: bash + env: + QT_VERSION: ${{ inputs.qt_version }} + run: ${{ inputs.qt_install_script }} + - name: Configure CMake run: > cmake -B ${{ steps.strings.outputs.build-output-dir }} diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index c62bffa..0a56d96 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -38,9 +38,24 @@ jobs: c_compiler: ${{ matrix.c_compiler }} cpp_compiler: ${{ matrix.cpp_compiler }} qt_version: ${{ matrix.qt_version }} - qt_arch: clang_64 target_arch: x86_64 - setup_script: 'softwareupdate --install-rosetta --agree-to-license' + qt_install_script: | + softwareupdate --install-rosetta --agree-to-license + python3 -m pip install aqtinstall + QT_BASE="${QT_VERSION%.*}" + QT_MAJOR="${QT_VERSION%%.*}" + RESOLVED=$(aqt list-qt mac desktop --arch clang_64 2>/dev/null | tr ' ' '\n' | grep "^${QT_BASE}\." | sort -t. -k3 -n | tail -1) + if [[ -z "$RESOLVED" ]]; then + echo "::error::Could not resolve Qt version matching $QT_VERSION for clang_64" >&2 + exit 1 + fi + QT_INSTALL_DIR="$HOME/Qt" + aqt install-qt mac desktop "$RESOLVED" clang_64 --outputdir "$QT_INSTALL_DIR" + QT_DIR="$QT_INSTALL_DIR/$RESOLVED/clang_64" + echo "$QT_DIR/bin" >> "$GITHUB_PATH" + echo "QT_ROOT_DIR=$QT_DIR" >> "$GITHUB_ENV" + echo "Qt${QT_MAJOR}_DIR=$QT_DIR/lib/cmake/Qt${QT_MAJOR}" >> "$GITHUB_ENV" + echo "QT_PLUGIN_PATH=$QT_DIR/plugins" >> "$GITHUB_ENV" build-macos-arm: name: macos-${{ matrix.c_compiler }}-qt${{ matrix.qt_version }}-arm From 84dec7d6a1f2e0a55d1707b926d67920ba02d286 Mon Sep 17 00:00:00 2001 From: Mostafa Nanticock <47303284+MostafaNanticock@users.noreply.github.com> Date: Sat, 18 Apr 2026 09:11:23 +0200 Subject: [PATCH 07/21] PM-227 Fixed MacOS builds for intel --- .github/workflows/macos.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 0a56d96..8b3946f 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -41,12 +41,15 @@ jobs: target_arch: x86_64 qt_install_script: | softwareupdate --install-rosetta --agree-to-license - python3 -m pip install aqtinstall + python3 -m venv /tmp/aqt-venv + source /tmp/aqt-venv/bin/activate + pip install aqtinstall --quiet QT_BASE="${QT_VERSION%.*}" QT_MAJOR="${QT_VERSION%%.*}" - RESOLVED=$(aqt list-qt mac desktop --arch clang_64 2>/dev/null | tr ' ' '\n' | grep "^${QT_BASE}\." | sort -t. -k3 -n | tail -1) + # aqt list-qt returns all available versions; no --arch flag at the list stage + RESOLVED=$(aqt list-qt mac desktop 2>/dev/null | tr ' ' '\n' | grep "^${QT_BASE}\." | sort -t. -k3 -n | tail -1) if [[ -z "$RESOLVED" ]]; then - echo "::error::Could not resolve Qt version matching $QT_VERSION for clang_64" >&2 + echo "::error::Could not resolve a Qt version matching $QT_VERSION" >&2 exit 1 fi QT_INSTALL_DIR="$HOME/Qt" From 3ce080fafa73b5d16c1aa17c750833b7efa44589 Mon Sep 17 00:00:00 2001 From: Mostafa Nanticock <47303284+MostafaNanticock@users.noreply.github.com> Date: Sat, 18 Apr 2026 09:38:54 +0200 Subject: [PATCH 08/21] PM-227 Fixed Qt6 failed builds on MacOS for intel Prefix CMake, build and test commands with an ARCH_PREFIX env var and set that var on macOS to force x86_64 execution. The macOS workflow now installs Rosetta (ignoring the non-zero exit when already installed) and writes "ARCH_PREFIX=arch -x86_64" to GITHUB_ENV so Qt6's CMake config sees the expected host architecture and avoids ARM64/x86_64 mismatches. Build steps remain no-op when ARCH_PREFIX is unset. --- .github/workflows/_build-shared.yml | 6 +++--- .github/workflows/macos.yml | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/_build-shared.yml b/.github/workflows/_build-shared.yml index 9ccd91d..c352886 100644 --- a/.github/workflows/_build-shared.yml +++ b/.github/workflows/_build-shared.yml @@ -60,7 +60,7 @@ jobs: - name: Configure CMake run: > - cmake -B ${{ steps.strings.outputs.build-output-dir }} + ${{ env.ARCH_PREFIX }} cmake -B ${{ steps.strings.outputs.build-output-dir }} -DCMAKE_C_COMPILER=${{ inputs.c_compiler }} -DCMAKE_CXX_COMPILER=${{ inputs.cpp_compiler }} -DCMAKE_BUILD_TYPE=Release @@ -68,8 +68,8 @@ jobs: -S ${{ github.workspace }} - name: Build - run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config Release + run: ${{ env.ARCH_PREFIX }} cmake --build ${{ steps.strings.outputs.build-output-dir }} --config Release - name: Test working-directory: ${{ steps.strings.outputs.build-output-dir }} - run: ctest --build-config Release + run: ${{ env.ARCH_PREFIX }} ctest --build-config Release diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 8b3946f..e8d871f 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -40,7 +40,11 @@ jobs: qt_version: ${{ matrix.qt_version }} target_arch: x86_64 qt_install_script: | - softwareupdate --install-rosetta --agree-to-license + # Install Rosetta if not already present; exits non-zero when already installed so we swallow the error + softwareupdate --install-rosetta --agree-to-license || true + # Run cmake, build and tests under arch -x86_64 so Qt6's cmake config sees the + # correct host architecture and doesn't reject the ARM64/x86_64 mismatch + echo "ARCH_PREFIX=arch -x86_64" >> "$GITHUB_ENV" python3 -m venv /tmp/aqt-venv source /tmp/aqt-venv/bin/activate pip install aqtinstall --quiet From d12c8b7f8516f9d5a079fd7e4acf07b8d3361e0a Mon Sep 17 00:00:00 2001 From: Mostafa Nanticock <47303284+MostafaNanticock@users.noreply.github.com> Date: Sat, 18 Apr 2026 09:50:27 +0200 Subject: [PATCH 09/21] PM-227 Fix for failed builds on MacOS-intel --- .github/workflows/macos.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index e8d871f..6b9afdb 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -63,6 +63,7 @@ jobs: echo "QT_ROOT_DIR=$QT_DIR" >> "$GITHUB_ENV" echo "Qt${QT_MAJOR}_DIR=$QT_DIR/lib/cmake/Qt${QT_MAJOR}" >> "$GITHUB_ENV" echo "QT_PLUGIN_PATH=$QT_DIR/plugins" >> "$GITHUB_ENV" + echo "CMAKE_PREFIX_PATH=$QT_DIR" >> "$GITHUB_ENV" build-macos-arm: name: macos-${{ matrix.c_compiler }}-qt${{ matrix.qt_version }}-arm From 058ccb34c6c6e3fdcc8096c2925a22abf5bf0647 Mon Sep 17 00:00:00 2001 From: Mostafa Nanticock <47303284+MostafaNanticock@users.noreply.github.com> Date: Sat, 18 Apr 2026 10:01:12 +0200 Subject: [PATCH 10/21] PM-227 macos CI: enable x86_64 Qt via Rosetta Clarify Rosetta install and adjust how x86_64 Qt is used on ARM runners. Remove the previous ARCH_PREFIX approach and instead set CMAKE_ARCH_FLAGS in the environment to force CMAKE_OSX_ARCHITECTURES=x86_64 and disable Qt's architecture check (QT_NO_FORCE_ARCHITECTURE_CHECK=TRUE). This lets cmake run natively on ARM64 while producing x86_64 outputs and allowing Qt tools/tests to run under Rosetta. --- .github/workflows/macos.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 6b9afdb..2b43d0c 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -40,11 +40,9 @@ jobs: qt_version: ${{ matrix.qt_version }} target_arch: x86_64 qt_install_script: | - # Install Rosetta if not already present; exits non-zero when already installed so we swallow the error + # Install Rosetta so that the x86_64 Qt tools (moc, uic) and x86_64 test + # binaries can run on the ARM64 runner. Exits non-zero when already installed. softwareupdate --install-rosetta --agree-to-license || true - # Run cmake, build and tests under arch -x86_64 so Qt6's cmake config sees the - # correct host architecture and doesn't reject the ARM64/x86_64 mismatch - echo "ARCH_PREFIX=arch -x86_64" >> "$GITHUB_ENV" python3 -m venv /tmp/aqt-venv source /tmp/aqt-venv/bin/activate pip install aqtinstall --quiet @@ -64,6 +62,11 @@ jobs: echo "Qt${QT_MAJOR}_DIR=$QT_DIR/lib/cmake/Qt${QT_MAJOR}" >> "$GITHUB_ENV" echo "QT_PLUGIN_PATH=$QT_DIR/plugins" >> "$GITHUB_ENV" echo "CMAKE_PREFIX_PATH=$QT_DIR" >> "$GITHUB_ENV" + # cmake runs natively as ARM64; the cross-compilation target is x86_64 via + # CMAKE_OSX_ARCHITECTURES. Qt6 checks that the host arch matches the installed + # Qt's arch (clang_64 = x86_64) and rejects the ARM64 host — suppress that check. + # The compiled output and Qt tools are x86_64 and run automatically via Rosetta. + echo "CMAKE_ARCH_FLAGS=-DCMAKE_OSX_ARCHITECTURES=x86_64 -DQT_NO_FORCE_ARCHITECTURE_CHECK=TRUE" >> "$GITHUB_ENV" build-macos-arm: name: macos-${{ matrix.c_compiler }}-qt${{ matrix.qt_version }}-arm From d60ed4d615e0b1af4bbfd517b299c108d32ba323 Mon Sep 17 00:00:00 2001 From: Mostafa Nanticock <47303284+MostafaNanticock@users.noreply.github.com> Date: Sat, 18 Apr 2026 12:56:14 +0200 Subject: [PATCH 11/21] PM-227 Change CMake Configure step to use bash --- .github/workflows/_build-shared.yml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/_build-shared.yml b/.github/workflows/_build-shared.yml index c352886..8096c4f 100644 --- a/.github/workflows/_build-shared.yml +++ b/.github/workflows/_build-shared.yml @@ -59,13 +59,15 @@ jobs: run: ${{ inputs.qt_install_script }} - name: Configure CMake - run: > - ${{ env.ARCH_PREFIX }} cmake -B ${{ steps.strings.outputs.build-output-dir }} - -DCMAKE_C_COMPILER=${{ inputs.c_compiler }} - -DCMAKE_CXX_COMPILER=${{ inputs.cpp_compiler }} - -DCMAKE_BUILD_TYPE=Release - ${{ env.CMAKE_ARCH_FLAGS }} - -S ${{ github.workspace }} + shell: bash + run: | + cmake -B "${{ steps.strings.outputs.build-output-dir }}" \ + -DCMAKE_C_COMPILER=${{ inputs.c_compiler }} \ + -DCMAKE_CXX_COMPILER=${{ inputs.cpp_compiler }} \ + -DCMAKE_BUILD_TYPE=Release \ + ${{ env.CMAKE_ARCH_FLAGS }} \ + ${CMAKE_PREFIX_PATH:+-DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH"} \ + -S "${{ github.workspace }}" - name: Build run: ${{ env.ARCH_PREFIX }} cmake --build ${{ steps.strings.outputs.build-output-dir }} --config Release From 20f41e0253df44b4b24c25480a1e39a8f8fc4488 Mon Sep 17 00:00:00 2001 From: Mostafa Nanticock <47303284+MostafaNanticock@users.noreply.github.com> Date: Sat, 18 Apr 2026 14:29:35 +0200 Subject: [PATCH 12/21] PM-227 Used macos-26-intel to build for intel on MacOS --- .github/workflows/macos.yml | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 2b43d0c..73ba09a 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -34,39 +34,10 @@ jobs: uses: ./.github/workflows/_build-shared.yml with: - os: macos-latest + os: macos-26-intel c_compiler: ${{ matrix.c_compiler }} cpp_compiler: ${{ matrix.cpp_compiler }} qt_version: ${{ matrix.qt_version }} - target_arch: x86_64 - qt_install_script: | - # Install Rosetta so that the x86_64 Qt tools (moc, uic) and x86_64 test - # binaries can run on the ARM64 runner. Exits non-zero when already installed. - softwareupdate --install-rosetta --agree-to-license || true - python3 -m venv /tmp/aqt-venv - source /tmp/aqt-venv/bin/activate - pip install aqtinstall --quiet - QT_BASE="${QT_VERSION%.*}" - QT_MAJOR="${QT_VERSION%%.*}" - # aqt list-qt returns all available versions; no --arch flag at the list stage - RESOLVED=$(aqt list-qt mac desktop 2>/dev/null | tr ' ' '\n' | grep "^${QT_BASE}\." | sort -t. -k3 -n | tail -1) - if [[ -z "$RESOLVED" ]]; then - echo "::error::Could not resolve a Qt version matching $QT_VERSION" >&2 - exit 1 - fi - QT_INSTALL_DIR="$HOME/Qt" - aqt install-qt mac desktop "$RESOLVED" clang_64 --outputdir "$QT_INSTALL_DIR" - QT_DIR="$QT_INSTALL_DIR/$RESOLVED/clang_64" - echo "$QT_DIR/bin" >> "$GITHUB_PATH" - echo "QT_ROOT_DIR=$QT_DIR" >> "$GITHUB_ENV" - echo "Qt${QT_MAJOR}_DIR=$QT_DIR/lib/cmake/Qt${QT_MAJOR}" >> "$GITHUB_ENV" - echo "QT_PLUGIN_PATH=$QT_DIR/plugins" >> "$GITHUB_ENV" - echo "CMAKE_PREFIX_PATH=$QT_DIR" >> "$GITHUB_ENV" - # cmake runs natively as ARM64; the cross-compilation target is x86_64 via - # CMAKE_OSX_ARCHITECTURES. Qt6 checks that the host arch matches the installed - # Qt's arch (clang_64 = x86_64) and rejects the ARM64 host — suppress that check. - # The compiled output and Qt tools are x86_64 and run automatically via Rosetta. - echo "CMAKE_ARCH_FLAGS=-DCMAKE_OSX_ARCHITECTURES=x86_64 -DQT_NO_FORCE_ARCHITECTURE_CHECK=TRUE" >> "$GITHUB_ENV" build-macos-arm: name: macos-${{ matrix.c_compiler }}-qt${{ matrix.qt_version }}-arm From 431614ebd4e451714b66d499bcfef3b3be248361 Mon Sep 17 00:00:00 2001 From: Mostafa Nanticock <47303284+MostafaNanticock@users.noreply.github.com> Date: Sat, 18 Apr 2026 14:49:07 +0200 Subject: [PATCH 13/21] PM-227 Add cmake_extra_flags and weak-link AGL on macOS Introduce a new workflow input cmake_extra_flags (string, default empty) in .github/workflows/_build-shared.yml and pass it through to the cmake configure command. Update .github/workflows/macos.yml to set cmake_extra_flags to add -weak_framework AGL for executable and shared linker flags so builds using Qt6 prebuilt binaries won't fail when AGL.framework is missing on newer macOS versions. --- .github/workflows/_build-shared.yml | 5 +++++ .github/workflows/macos.yml | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/.github/workflows/_build-shared.yml b/.github/workflows/_build-shared.yml index 8096c4f..014b752 100644 --- a/.github/workflows/_build-shared.yml +++ b/.github/workflows/_build-shared.yml @@ -23,6 +23,10 @@ on: required: false type: string default: '' + cmake_extra_flags: + required: false + type: string + default: '' jobs: build: @@ -67,6 +71,7 @@ jobs: -DCMAKE_BUILD_TYPE=Release \ ${{ env.CMAKE_ARCH_FLAGS }} \ ${CMAKE_PREFIX_PATH:+-DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH"} \ + ${{ inputs.cmake_extra_flags }} \ -S "${{ github.workspace }}" - name: Build diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 73ba09a..a7e9a53 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -38,6 +38,11 @@ jobs: c_compiler: ${{ matrix.c_compiler }} cpp_compiler: ${{ matrix.cpp_compiler }} qt_version: ${{ matrix.qt_version }} + # Qt6 pre-built binaries reference AGL.framework which was removed in macOS 10.15. + # Weak-linking allows the build to succeed on macOS 26 when AGL is absent at link time. + cmake_extra_flags: >- + -DCMAKE_EXE_LINKER_FLAGS="-weak_framework AGL" + -DCMAKE_SHARED_LINKER_FLAGS="-weak_framework AGL" build-macos-arm: name: macos-${{ matrix.c_compiler }}-qt${{ matrix.qt_version }}-arm From 54ba9c631fc6a0c72e20886a0df6ba0d7bad0fd5 Mon Sep 17 00:00:00 2001 From: Mostafa Nanticock <47303284+MostafaNanticock@users.noreply.github.com> Date: Sat, 18 Apr 2026 14:59:00 +0200 Subject: [PATCH 14/21] PM-227 Install Qt via aqtinstall and strip AGL refs Replace the previous weak-link workaround with a scripted Qt install using aqtinstall in the macOS CI workflow. The job now creates a venv, installs aqtinstall, resolves the best matching Qt release for the requested version, installs Qt into $HOME/Qt, and exports QT paths to the environment. For Qt 6, it also patches installed CMake files to remove embedded "-framework AGL" references (AGL was removed from macOS 10.15 and is absent on newer runners) so builds do not link against a missing framework. This keeps Qt5 behavior unchanged and avoids linker-time weak-linking hacks. --- .github/workflows/macos.yml | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index a7e9a53..ac1c725 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -38,11 +38,33 @@ jobs: c_compiler: ${{ matrix.c_compiler }} cpp_compiler: ${{ matrix.cpp_compiler }} qt_version: ${{ matrix.qt_version }} - # Qt6 pre-built binaries reference AGL.framework which was removed in macOS 10.15. - # Weak-linking allows the build to succeed on macOS 26 when AGL is absent at link time. - cmake_extra_flags: >- - -DCMAKE_EXE_LINKER_FLAGS="-weak_framework AGL" - -DCMAKE_SHARED_LINKER_FLAGS="-weak_framework AGL" + qt_install_script: | + python3 -m venv /tmp/aqt-venv + source /tmp/aqt-venv/bin/activate + pip install aqtinstall --quiet + QT_BASE="${QT_VERSION%.*}" + QT_MAJOR="${QT_VERSION%%.*}" + RESOLVED=$(aqt list-qt mac desktop 2>/dev/null | tr ' ' '\n' | grep "^${QT_BASE}\." | sort -t. -k3 -n | tail -1) + if [[ -z "$RESOLVED" ]]; then + echo "::error::Could not resolve a Qt version matching $QT_VERSION" >&2 + exit 1 + fi + QT_INSTALL_DIR="$HOME/Qt" + aqt install-qt mac desktop "$RESOLVED" clang_64 --outputdir "$QT_INSTALL_DIR" + QT_DIR="$QT_INSTALL_DIR/$RESOLVED/clang_64" + echo "$QT_DIR/bin" >> "$GITHUB_PATH" + echo "QT_ROOT_DIR=$QT_DIR" >> "$GITHUB_ENV" + echo "Qt${QT_MAJOR}_DIR=$QT_DIR/lib/cmake/Qt${QT_MAJOR}" >> "$GITHUB_ENV" + echo "QT_PLUGIN_PATH=$QT_DIR/plugins" >> "$GITHUB_ENV" + echo "CMAKE_PREFIX_PATH=$QT_DIR" >> "$GITHUB_ENV" + # Qt6 pre-built binaries embed a reference to AGL.framework in their cmake target + # files. AGL was removed in macOS 10.15 and is absent on macos-26-intel. + # Patch it out of the installed cmake files before cmake runs so it never + # appears as a link dependency. Qt5 does not reference AGL so this is a no-op there. + if [[ "$QT_MAJOR" == "6" ]]; then + find "$QT_DIR/lib/cmake" -name "*.cmake" -print0 \ + | xargs -0 sed -i '' 's/-framework AGL//g' + fi build-macos-arm: name: macos-${{ matrix.c_compiler }}-qt${{ matrix.qt_version }}-arm From 294a6cc8dea710f0cf791c12f69cbb381972b3f7 Mon Sep 17 00:00:00 2001 From: Mostafa Nanticock <47303284+MostafaNanticock@users.noreply.github.com> Date: Sat, 18 Apr 2026 15:03:50 +0200 Subject: [PATCH 15/21] Update macos.yml --- .github/workflows/macos.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index ac1c725..7ecf749 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -49,9 +49,16 @@ jobs: echo "::error::Could not resolve a Qt version matching $QT_VERSION" >&2 exit 1 fi + # Qt5 aqt arch identifier is "clang_64" (x86_64 only). + # Qt6 aqt arch identifier is "macos" (universal x86_64+ARM64). + if [[ "$QT_MAJOR" == "6" ]]; then + QT_ARCH="macos" + else + QT_ARCH="clang_64" + fi QT_INSTALL_DIR="$HOME/Qt" - aqt install-qt mac desktop "$RESOLVED" clang_64 --outputdir "$QT_INSTALL_DIR" - QT_DIR="$QT_INSTALL_DIR/$RESOLVED/clang_64" + aqt install-qt mac desktop "$RESOLVED" "$QT_ARCH" --outputdir "$QT_INSTALL_DIR" + QT_DIR="$QT_INSTALL_DIR/$RESOLVED/$QT_ARCH" echo "$QT_DIR/bin" >> "$GITHUB_PATH" echo "QT_ROOT_DIR=$QT_DIR" >> "$GITHUB_ENV" echo "Qt${QT_MAJOR}_DIR=$QT_DIR/lib/cmake/Qt${QT_MAJOR}" >> "$GITHUB_ENV" From e73049b3f613a5f5e2c25b5e12f6681822c0e07c Mon Sep 17 00:00:00 2001 From: Mostafa Nanticock <47303284+MostafaNanticock@users.noreply.github.com> Date: Sat, 18 Apr 2026 15:12:55 +0200 Subject: [PATCH 16/21] PM-227 Remove Qt6 for MacOs-intel for now --- .github/workflows/_build-shared.yml | 5 --- .github/workflows/macos.yml | 47 ++++++++--------------------- 2 files changed, 13 insertions(+), 39 deletions(-) diff --git a/.github/workflows/_build-shared.yml b/.github/workflows/_build-shared.yml index 014b752..8096c4f 100644 --- a/.github/workflows/_build-shared.yml +++ b/.github/workflows/_build-shared.yml @@ -23,10 +23,6 @@ on: required: false type: string default: '' - cmake_extra_flags: - required: false - type: string - default: '' jobs: build: @@ -71,7 +67,6 @@ jobs: -DCMAKE_BUILD_TYPE=Release \ ${{ env.CMAKE_ARCH_FLAGS }} \ ${CMAKE_PREFIX_PATH:+-DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH"} \ - ${{ inputs.cmake_extra_flags }} \ -S "${{ github.workspace }}" - name: Build diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 7ecf749..9518daf 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -31,6 +31,19 @@ jobs: cpp_compiler: g++ - c_compiler: clang cpp_compiler: clang++ + exclude: + # Qt6 pre-built binaries link against AGL.framework, which was removed in + # macOS 10.15. The macos-26-intel runner does not ship AGL, so all Qt6 builds + # fail at link time with "ld: framework 'AGL' not found". + # + # Patching Qt's installed cmake files to strip the AGL reference is fragile + # and outside the scope of this project. The practical alternatives are: + # 1. Use an older runner image that still ships AGL (e.g. macos-13). + # 2. Cross-compile for x86_64 from the ARM mac runner (macos-latest) + # using CMAKE_OSX_ARCHITECTURES=x86_64 — Qt6 supports this natively. + - qt_version: "6.2.*" + - qt_version: "6.5.*" + - qt_version: "6.8.*" uses: ./.github/workflows/_build-shared.yml with: @@ -38,40 +51,6 @@ jobs: c_compiler: ${{ matrix.c_compiler }} cpp_compiler: ${{ matrix.cpp_compiler }} qt_version: ${{ matrix.qt_version }} - qt_install_script: | - python3 -m venv /tmp/aqt-venv - source /tmp/aqt-venv/bin/activate - pip install aqtinstall --quiet - QT_BASE="${QT_VERSION%.*}" - QT_MAJOR="${QT_VERSION%%.*}" - RESOLVED=$(aqt list-qt mac desktop 2>/dev/null | tr ' ' '\n' | grep "^${QT_BASE}\." | sort -t. -k3 -n | tail -1) - if [[ -z "$RESOLVED" ]]; then - echo "::error::Could not resolve a Qt version matching $QT_VERSION" >&2 - exit 1 - fi - # Qt5 aqt arch identifier is "clang_64" (x86_64 only). - # Qt6 aqt arch identifier is "macos" (universal x86_64+ARM64). - if [[ "$QT_MAJOR" == "6" ]]; then - QT_ARCH="macos" - else - QT_ARCH="clang_64" - fi - QT_INSTALL_DIR="$HOME/Qt" - aqt install-qt mac desktop "$RESOLVED" "$QT_ARCH" --outputdir "$QT_INSTALL_DIR" - QT_DIR="$QT_INSTALL_DIR/$RESOLVED/$QT_ARCH" - echo "$QT_DIR/bin" >> "$GITHUB_PATH" - echo "QT_ROOT_DIR=$QT_DIR" >> "$GITHUB_ENV" - echo "Qt${QT_MAJOR}_DIR=$QT_DIR/lib/cmake/Qt${QT_MAJOR}" >> "$GITHUB_ENV" - echo "QT_PLUGIN_PATH=$QT_DIR/plugins" >> "$GITHUB_ENV" - echo "CMAKE_PREFIX_PATH=$QT_DIR" >> "$GITHUB_ENV" - # Qt6 pre-built binaries embed a reference to AGL.framework in their cmake target - # files. AGL was removed in macOS 10.15 and is absent on macos-26-intel. - # Patch it out of the installed cmake files before cmake runs so it never - # appears as a link dependency. Qt5 does not reference AGL so this is a no-op there. - if [[ "$QT_MAJOR" == "6" ]]; then - find "$QT_DIR/lib/cmake" -name "*.cmake" -print0 \ - | xargs -0 sed -i '' 's/-framework AGL//g' - fi build-macos-arm: name: macos-${{ matrix.c_compiler }}-qt${{ matrix.qt_version }}-arm From f8cfbe9694a0ccf1fc8f00ab4d64fcf22c600ec5 Mon Sep 17 00:00:00 2001 From: Mostafa Nanticock <47303284+MostafaNanticock@users.noreply.github.com> Date: Sat, 18 Apr 2026 15:25:34 +0200 Subject: [PATCH 17/21] PM-227 Support building against qt6 intel on macos-latest --- .github/workflows/macos.yml | 72 +++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 9518daf..6af8e3a 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -52,6 +52,78 @@ jobs: cpp_compiler: ${{ matrix.cpp_compiler }} qt_version: ${{ matrix.qt_version }} + # Cross-compile Qt6 for Intel (x86_64) from the ARM64 runner via Rosetta 2. + # This covers the Qt6 versions excluded from build-macos-intel due to the missing + # AGL.framework on macos-26-intel. Qt 6.0-6.2 ship a clang_64 (x86_64-only) binary; + # Qt 6.3+ ship a universal "macos" binary (x86_64 + ARM64), both work with + # CMAKE_OSX_ARCHITECTURES=x86_64 on an ARM64 host. + build-macos-intel-qt6-rosetta: + name: macos-${{ matrix.c_compiler }}-qt${{ matrix.qt_version }}-intel-rosetta + needs: get-matrix + strategy: + fail-fast: false + matrix: + c_compiler: ${{ fromJson(needs.get-matrix.outputs.compilers_macos) }} + qt_version: ${{ fromJson(needs.get-matrix.outputs.qt_versions) }} + include: + - c_compiler: gcc + cpp_compiler: g++ + - c_compiler: clang + cpp_compiler: clang++ + exclude: + # Qt5 is not Qt6; the native Intel job already covers Qt5 on Intel. + - qt_version: "5.9.*" + - qt_version: "5.12.*" + - qt_version: "5.15.*" + + uses: ./.github/workflows/_build-shared.yml + with: + os: macos-latest + c_compiler: ${{ matrix.c_compiler }} + cpp_compiler: ${{ matrix.cpp_compiler }} + qt_version: ${{ matrix.qt_version }} + qt_install_script: | + # Rosetta 2 lets x86_64 Qt tools (moc, uic) and test binaries run on ARM64. + softwareupdate --install-rosetta --agree-to-license || true + python3 -m venv /tmp/aqt-venv + source /tmp/aqt-venv/bin/activate + pip install aqtinstall --quiet + QT_BASE="${QT_VERSION%.*}" + QT_MAJOR="${QT_VERSION%%.*}" + RESOLVED=$(aqt list-qt mac desktop 2>/dev/null | tr ' ' '\n' | grep "^${QT_BASE}\." | sort -t. -k3 -n | tail -1) + if [[ -z "$RESOLVED" ]]; then + echo "::error::Could not resolve a Qt version matching $QT_VERSION" >&2 + exit 1 + fi + # Qt 6.0-6.2 use "clang_64" (x86_64-only); Qt 6.3+ use "macos" (universal). + AVAILABLE_ARCHS=$(aqt list-qt mac desktop --arch "$RESOLVED" 2>/dev/null) + if echo "$AVAILABLE_ARCHS" | tr ' ' '\n' | grep -q '^clang_64$'; then + QT_ARCH="clang_64" + elif echo "$AVAILABLE_ARCHS" | tr ' ' '\n' | grep -q '^macos$'; then + QT_ARCH="macos" + else + echo "::error::Could not determine Qt arch for $RESOLVED. Available: $AVAILABLE_ARCHS" >&2 + exit 1 + fi + QT_INSTALL_DIR="$HOME/Qt" + aqt install-qt mac desktop "$RESOLVED" "$QT_ARCH" --outputdir "$QT_INSTALL_DIR" + QT_DIR="$QT_INSTALL_DIR/$RESOLVED/$QT_ARCH" + echo "$QT_DIR/bin" >> "$GITHUB_PATH" + echo "QT_ROOT_DIR=$QT_DIR" >> "$GITHUB_ENV" + echo "Qt${QT_MAJOR}_DIR=$QT_DIR/lib/cmake/Qt${QT_MAJOR}" >> "$GITHUB_ENV" + echo "QT_PLUGIN_PATH=$QT_DIR/plugins" >> "$GITHUB_ENV" + echo "CMAKE_PREFIX_PATH=$QT_DIR" >> "$GITHUB_ENV" + # Target x86_64 via CMake cross-compilation. + # For clang_64 (x86_64-only Qt), Qt6's cmake config rejects an ARM64 host; + # QT_NO_FORCE_ARCHITECTURE_CHECK suppresses that check (available since Qt 6.3, + # but clang_64 is only used for Qt 6.0-6.2 so this flag is a best-effort). + # For the universal "macos" arch both slices are present, so no flag is needed. + ARCH_FLAGS="-DCMAKE_OSX_ARCHITECTURES=x86_64" + if [[ "$QT_ARCH" == "clang_64" ]]; then + ARCH_FLAGS="$ARCH_FLAGS -DQT_NO_FORCE_ARCHITECTURE_CHECK=TRUE" + fi + echo "CMAKE_ARCH_FLAGS=$ARCH_FLAGS" >> "$GITHUB_ENV" + build-macos-arm: name: macos-${{ matrix.c_compiler }}-qt${{ matrix.qt_version }}-arm needs: get-matrix From 8d54b36518e051c3cbfe93b7f9fce027184ca479 Mon Sep 17 00:00:00 2001 From: Mostafa Nanticock <47303284+MostafaNanticock@users.noreply.github.com> Date: Sat, 18 Apr 2026 15:34:34 +0200 Subject: [PATCH 18/21] Update macos.yml --- .github/workflows/macos.yml | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 6af8e3a..9349931 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -54,9 +54,9 @@ jobs: # Cross-compile Qt6 for Intel (x86_64) from the ARM64 runner via Rosetta 2. # This covers the Qt6 versions excluded from build-macos-intel due to the missing - # AGL.framework on macos-26-intel. Qt 6.0-6.2 ship a clang_64 (x86_64-only) binary; - # Qt 6.3+ ship a universal "macos" binary (x86_64 + ARM64), both work with - # CMAKE_OSX_ARCHITECTURES=x86_64 on an ARM64 host. + # AGL.framework on macos-26-intel. Qt 6.3+ ship a universal "macos" binary + # (x86_64 + ARM64) whose cmake config accepts any host; Qt 6.0-6.2 ship a + # "clang_64" (x86_64-only) binary used as a fallback for those older versions. build-macos-intel-qt6-rosetta: name: macos-${{ matrix.c_compiler }}-qt${{ matrix.qt_version }}-intel-rosetta needs: get-matrix @@ -95,12 +95,17 @@ jobs: echo "::error::Could not resolve a Qt version matching $QT_VERSION" >&2 exit 1 fi - # Qt 6.0-6.2 use "clang_64" (x86_64-only); Qt 6.3+ use "macos" (universal). + # Prefer "macos" (universal x86_64+ARM64) over "clang_64" (x86_64-only). + # The universal binary's Qt6Config.cmake accepts any host architecture, so it + # works on the ARM64 runner with CMAKE_OSX_ARCHITECTURES=x86_64 to target Intel. + # "clang_64" (x86_64-only) rejects an ARM64 host in its cmake config even with + # QT_NO_FORCE_ARCHITECTURE_CHECK, so it is only used as a fallback for older Qt + # versions (6.0-6.2) that predate the universal "macos" package. AVAILABLE_ARCHS=$(aqt list-qt mac desktop --arch "$RESOLVED" 2>/dev/null) - if echo "$AVAILABLE_ARCHS" | tr ' ' '\n' | grep -q '^clang_64$'; then - QT_ARCH="clang_64" - elif echo "$AVAILABLE_ARCHS" | tr ' ' '\n' | grep -q '^macos$'; then + if echo "$AVAILABLE_ARCHS" | tr ' ' '\n' | grep -q '^macos$'; then QT_ARCH="macos" + elif echo "$AVAILABLE_ARCHS" | tr ' ' '\n' | grep -q '^clang_64$'; then + QT_ARCH="clang_64" else echo "::error::Could not determine Qt arch for $RESOLVED. Available: $AVAILABLE_ARCHS" >&2 exit 1 From 291c89fb0acd0f591e117ae0728f675b1a1c3fdf Mon Sep 17 00:00:00 2001 From: Mostafa Nanticock <47303284+MostafaNanticock@users.noreply.github.com> Date: Sat, 18 Apr 2026 15:48:04 +0200 Subject: [PATCH 19/21] Update macos.yml --- .github/workflows/macos.yml | 47 +++++++++++++------------------------ 1 file changed, 16 insertions(+), 31 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 9349931..46ab686 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -55,8 +55,10 @@ jobs: # Cross-compile Qt6 for Intel (x86_64) from the ARM64 runner via Rosetta 2. # This covers the Qt6 versions excluded from build-macos-intel due to the missing # AGL.framework on macos-26-intel. Qt 6.3+ ship a universal "macos" binary - # (x86_64 + ARM64) whose cmake config accepts any host; Qt 6.0-6.2 ship a - # "clang_64" (x86_64-only) binary used as a fallback for those older versions. + # (x86_64 + ARM64) whose Qt6Config.cmake accepts any host architecture, making + # cross-compilation with CMAKE_OSX_ARCHITECTURES=x86_64 work transparently. + # Qt 6.2 only has the "clang_64" (x86_64-only) package whose cmake config + # actively rejects an ARM64 host, so it is excluded here. build-macos-intel-qt6-rosetta: name: macos-${{ matrix.c_compiler }}-qt${{ matrix.qt_version }}-intel-rosetta needs: get-matrix @@ -71,10 +73,14 @@ jobs: - c_compiler: clang cpp_compiler: clang++ exclude: - # Qt5 is not Qt6; the native Intel job already covers Qt5 on Intel. + # Qt5 is covered by the native Intel job. - qt_version: "5.9.*" - qt_version: "5.12.*" - qt_version: "5.15.*" + # Qt 6.2 has no universal "macos" package; cross-compilation from ARM64 is + # not possible. It is also excluded from build-macos-intel due to AGL, so + # Qt 6.2 Intel builds are simply not feasible on modern macOS runners. + - qt_version: "6.2.*" uses: ./.github/workflows/_build-shared.yml with: @@ -83,7 +89,7 @@ jobs: cpp_compiler: ${{ matrix.cpp_compiler }} qt_version: ${{ matrix.qt_version }} qt_install_script: | - # Rosetta 2 lets x86_64 Qt tools (moc, uic) and test binaries run on ARM64. + # Rosetta 2 lets x86_64 Qt tools (moc, uic) and test binaries run on the ARM64 runner. softwareupdate --install-rosetta --agree-to-license || true python3 -m venv /tmp/aqt-venv source /tmp/aqt-venv/bin/activate @@ -95,39 +101,18 @@ jobs: echo "::error::Could not resolve a Qt version matching $QT_VERSION" >&2 exit 1 fi - # Prefer "macos" (universal x86_64+ARM64) over "clang_64" (x86_64-only). - # The universal binary's Qt6Config.cmake accepts any host architecture, so it - # works on the ARM64 runner with CMAKE_OSX_ARCHITECTURES=x86_64 to target Intel. - # "clang_64" (x86_64-only) rejects an ARM64 host in its cmake config even with - # QT_NO_FORCE_ARCHITECTURE_CHECK, so it is only used as a fallback for older Qt - # versions (6.0-6.2) that predate the universal "macos" package. - AVAILABLE_ARCHS=$(aqt list-qt mac desktop --arch "$RESOLVED" 2>/dev/null) - if echo "$AVAILABLE_ARCHS" | tr ' ' '\n' | grep -q '^macos$'; then - QT_ARCH="macos" - elif echo "$AVAILABLE_ARCHS" | tr ' ' '\n' | grep -q '^clang_64$'; then - QT_ARCH="clang_64" - else - echo "::error::Could not determine Qt arch for $RESOLVED. Available: $AVAILABLE_ARCHS" >&2 - exit 1 - fi QT_INSTALL_DIR="$HOME/Qt" - aqt install-qt mac desktop "$RESOLVED" "$QT_ARCH" --outputdir "$QT_INSTALL_DIR" - QT_DIR="$QT_INSTALL_DIR/$RESOLVED/$QT_ARCH" + # Always install the universal "macos" package (x86_64 + ARM64). Its cmake + # config accepts any host architecture, so CMAKE_OSX_ARCHITECTURES=x86_64 + # cross-compiles to Intel without any host-arch rejection. + aqt install-qt mac desktop "$RESOLVED" macos --outputdir "$QT_INSTALL_DIR" + QT_DIR="$QT_INSTALL_DIR/$RESOLVED/macos" echo "$QT_DIR/bin" >> "$GITHUB_PATH" echo "QT_ROOT_DIR=$QT_DIR" >> "$GITHUB_ENV" echo "Qt${QT_MAJOR}_DIR=$QT_DIR/lib/cmake/Qt${QT_MAJOR}" >> "$GITHUB_ENV" echo "QT_PLUGIN_PATH=$QT_DIR/plugins" >> "$GITHUB_ENV" echo "CMAKE_PREFIX_PATH=$QT_DIR" >> "$GITHUB_ENV" - # Target x86_64 via CMake cross-compilation. - # For clang_64 (x86_64-only Qt), Qt6's cmake config rejects an ARM64 host; - # QT_NO_FORCE_ARCHITECTURE_CHECK suppresses that check (available since Qt 6.3, - # but clang_64 is only used for Qt 6.0-6.2 so this flag is a best-effort). - # For the universal "macos" arch both slices are present, so no flag is needed. - ARCH_FLAGS="-DCMAKE_OSX_ARCHITECTURES=x86_64" - if [[ "$QT_ARCH" == "clang_64" ]]; then - ARCH_FLAGS="$ARCH_FLAGS -DQT_NO_FORCE_ARCHITECTURE_CHECK=TRUE" - fi - echo "CMAKE_ARCH_FLAGS=$ARCH_FLAGS" >> "$GITHUB_ENV" + echo "CMAKE_ARCH_FLAGS=-DCMAKE_OSX_ARCHITECTURES=x86_64" >> "$GITHUB_ENV" build-macos-arm: name: macos-${{ matrix.c_compiler }}-qt${{ matrix.qt_version }}-arm From de57ab6f0916b7b718bded010d8d5a9c56631755 Mon Sep 17 00:00:00 2001 From: Mostafa Nanticock <47303284+MostafaNanticock@users.noreply.github.com> Date: Sat, 18 Apr 2026 16:42:28 +0200 Subject: [PATCH 20/21] PM-227 Fix CI: use qt_arch:clang_64 on macos-latest for intel builds Replace the broken qt_install_script conditional approach with the proven qt_arch:clang_64 approach using jurplel/install-qt-action@v4. The qt_install_script == '' condition in GitHub Actions reusable workflows incorrectly evaluates to false for unset optional inputs, causing Install Qt (custom) to run instead of Install Qt for all build-macos-intel jobs. The working approach: - Use macos-latest (ARM64) for all Intel builds - Pass qt_arch: clang_64 to install x86_64 Qt via jurplel - Install Rosetta 2 on ARM64 runners to execute x86_64 test binaries - Set CMAKE_OSX_ARCHITECTURES=x86_64 via osx_arch_flag step output - Remove build-macos-intel-qt6-rosetta (no longer needed) - Remove macos-26-intel runner dependency --- .github/workflows/_build-shared.yml | 57 +++++++++----------- .github/workflows/macos.yml | 81 ++--------------------------- 2 files changed, 28 insertions(+), 110 deletions(-) diff --git a/.github/workflows/_build-shared.yml b/.github/workflows/_build-shared.yml index 8096c4f..372f22b 100644 --- a/.github/workflows/_build-shared.yml +++ b/.github/workflows/_build-shared.yml @@ -15,11 +15,7 @@ on: qt_version: required: true type: string - target_arch: - required: false - type: string - default: '' - qt_install_script: + qt_arch: required: false type: string default: '' @@ -33,45 +29,42 @@ jobs: - name: Set reusable strings id: strings shell: bash - run: echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" + run: | + echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" + # When cross-compiling for Intel x86_64 on an ARM64 runner, pass the + # architecture flag so CMake emits x86_64 binaries. Rosetta 2 runs them. + if [[ "${{ runner.os }}" == "macOS" && "${{ runner.arch }}" == "ARM64" && "${{ inputs.qt_arch }}" == "clang_64" ]]; then + echo "osx_arch_flag=-DCMAKE_OSX_ARCHITECTURES=x86_64" >> "$GITHUB_OUTPUT" + else + echo "osx_arch_flag=" >> "$GITHUB_OUTPUT" + fi - - name: Set up target architecture - if: inputs.target_arch != '' - shell: bash - run: echo "CMAKE_ARCH_FLAGS=-DCMAKE_OSX_ARCHITECTURES=${{ inputs.target_arch }}" >> "$GITHUB_ENV" + - name: Install Rosetta + # Required so macOS can execute the x86_64 binaries built when cross-compiling + # for Intel on an ARM64 runner. + if: runner.os == 'macOS' && runner.arch == 'ARM64' && inputs.qt_arch == 'clang_64' + run: softwareupdate --install-rosetta --agree-to-license - name: Install Qt - if: inputs.qt_install_script == '' uses: jurplel/install-qt-action@v4 with: version: ${{ inputs.qt_version }} + arch: ${{ inputs.qt_arch }} install-deps: 'true' set-env: 'true' - - name: Install Qt (custom) - # Runs when qt_install_script is provided. The script is fully responsible for - # installing Qt and configuring the environment (PATH, QT_ROOT_DIR, Qt_DIR, etc.). - # QT_VERSION is available as an environment variable with the requested version string. - if: inputs.qt_install_script != '' - shell: bash - env: - QT_VERSION: ${{ inputs.qt_version }} - run: ${{ inputs.qt_install_script }} - - name: Configure CMake - shell: bash - run: | - cmake -B "${{ steps.strings.outputs.build-output-dir }}" \ - -DCMAKE_C_COMPILER=${{ inputs.c_compiler }} \ - -DCMAKE_CXX_COMPILER=${{ inputs.cpp_compiler }} \ - -DCMAKE_BUILD_TYPE=Release \ - ${{ env.CMAKE_ARCH_FLAGS }} \ - ${CMAKE_PREFIX_PATH:+-DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH"} \ - -S "${{ github.workspace }}" + run: > + cmake -B ${{ steps.strings.outputs.build-output-dir }} + -DCMAKE_C_COMPILER=${{ inputs.c_compiler }} + -DCMAKE_CXX_COMPILER=${{ inputs.cpp_compiler }} + -DCMAKE_BUILD_TYPE=Release + ${{ steps.strings.outputs.osx_arch_flag }} + -S ${{ github.workspace }} - name: Build - run: ${{ env.ARCH_PREFIX }} cmake --build ${{ steps.strings.outputs.build-output-dir }} --config Release + run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config Release - name: Test working-directory: ${{ steps.strings.outputs.build-output-dir }} - run: ${{ env.ARCH_PREFIX }} ctest --build-config Release + run: ctest --build-config Release diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 46ab686..28b984b 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -31,88 +31,14 @@ jobs: cpp_compiler: g++ - c_compiler: clang cpp_compiler: clang++ - exclude: - # Qt6 pre-built binaries link against AGL.framework, which was removed in - # macOS 10.15. The macos-26-intel runner does not ship AGL, so all Qt6 builds - # fail at link time with "ld: framework 'AGL' not found". - # - # Patching Qt's installed cmake files to strip the AGL reference is fragile - # and outside the scope of this project. The practical alternatives are: - # 1. Use an older runner image that still ships AGL (e.g. macos-13). - # 2. Cross-compile for x86_64 from the ARM mac runner (macos-latest) - # using CMAKE_OSX_ARCHITECTURES=x86_64 — Qt6 supports this natively. - - qt_version: "6.2.*" - - qt_version: "6.5.*" - - qt_version: "6.8.*" - - uses: ./.github/workflows/_build-shared.yml - with: - os: macos-26-intel - c_compiler: ${{ matrix.c_compiler }} - cpp_compiler: ${{ matrix.cpp_compiler }} - qt_version: ${{ matrix.qt_version }} - - # Cross-compile Qt6 for Intel (x86_64) from the ARM64 runner via Rosetta 2. - # This covers the Qt6 versions excluded from build-macos-intel due to the missing - # AGL.framework on macos-26-intel. Qt 6.3+ ship a universal "macos" binary - # (x86_64 + ARM64) whose Qt6Config.cmake accepts any host architecture, making - # cross-compilation with CMAKE_OSX_ARCHITECTURES=x86_64 work transparently. - # Qt 6.2 only has the "clang_64" (x86_64-only) package whose cmake config - # actively rejects an ARM64 host, so it is excluded here. - build-macos-intel-qt6-rosetta: - name: macos-${{ matrix.c_compiler }}-qt${{ matrix.qt_version }}-intel-rosetta - needs: get-matrix - strategy: - fail-fast: false - matrix: - c_compiler: ${{ fromJson(needs.get-matrix.outputs.compilers_macos) }} - qt_version: ${{ fromJson(needs.get-matrix.outputs.qt_versions) }} - include: - - c_compiler: gcc - cpp_compiler: g++ - - c_compiler: clang - cpp_compiler: clang++ - exclude: - # Qt5 is covered by the native Intel job. - - qt_version: "5.9.*" - - qt_version: "5.12.*" - - qt_version: "5.15.*" - # Qt 6.2 has no universal "macos" package; cross-compilation from ARM64 is - # not possible. It is also excluded from build-macos-intel due to AGL, so - # Qt 6.2 Intel builds are simply not feasible on modern macOS runners. - - qt_version: "6.2.*" uses: ./.github/workflows/_build-shared.yml with: - os: macos-latest + os: macos-latest # ARM runner; Intel x86_64 binaries built and run via Rosetta 2 c_compiler: ${{ matrix.c_compiler }} cpp_compiler: ${{ matrix.cpp_compiler }} qt_version: ${{ matrix.qt_version }} - qt_install_script: | - # Rosetta 2 lets x86_64 Qt tools (moc, uic) and test binaries run on the ARM64 runner. - softwareupdate --install-rosetta --agree-to-license || true - python3 -m venv /tmp/aqt-venv - source /tmp/aqt-venv/bin/activate - pip install aqtinstall --quiet - QT_BASE="${QT_VERSION%.*}" - QT_MAJOR="${QT_VERSION%%.*}" - RESOLVED=$(aqt list-qt mac desktop 2>/dev/null | tr ' ' '\n' | grep "^${QT_BASE}\." | sort -t. -k3 -n | tail -1) - if [[ -z "$RESOLVED" ]]; then - echo "::error::Could not resolve a Qt version matching $QT_VERSION" >&2 - exit 1 - fi - QT_INSTALL_DIR="$HOME/Qt" - # Always install the universal "macos" package (x86_64 + ARM64). Its cmake - # config accepts any host architecture, so CMAKE_OSX_ARCHITECTURES=x86_64 - # cross-compiles to Intel without any host-arch rejection. - aqt install-qt mac desktop "$RESOLVED" macos --outputdir "$QT_INSTALL_DIR" - QT_DIR="$QT_INSTALL_DIR/$RESOLVED/macos" - echo "$QT_DIR/bin" >> "$GITHUB_PATH" - echo "QT_ROOT_DIR=$QT_DIR" >> "$GITHUB_ENV" - echo "Qt${QT_MAJOR}_DIR=$QT_DIR/lib/cmake/Qt${QT_MAJOR}" >> "$GITHUB_ENV" - echo "QT_PLUGIN_PATH=$QT_DIR/plugins" >> "$GITHUB_ENV" - echo "CMAKE_PREFIX_PATH=$QT_DIR" >> "$GITHUB_ENV" - echo "CMAKE_ARCH_FLAGS=-DCMAKE_OSX_ARCHITECTURES=x86_64" >> "$GITHUB_ENV" + qt_arch: clang_64 # x86_64 Qt; triggers Rosetta install + CMAKE_OSX_ARCHITECTURES=x86_64 build-macos-arm: name: macos-${{ matrix.c_compiler }}-qt${{ matrix.qt_version }}-arm @@ -135,8 +61,7 @@ jobs: uses: ./.github/workflows/_build-shared.yml with: - os: macos-latest + os: macos-latest # Apple Silicon macOS c_compiler: ${{ matrix.c_compiler }} cpp_compiler: ${{ matrix.cpp_compiler }} qt_version: ${{ matrix.qt_version }} - target_arch: arm64 From 540f20dcb0ab8d0d5121ecb3fb2153405466c1c1 Mon Sep 17 00:00:00 2001 From: Mostafa Nanticock <47303284+MostafaNanticock@users.noreply.github.com> Date: Sat, 18 Apr 2026 17:08:13 +0200 Subject: [PATCH 21/21] Add setup_env_script input and macOS setup Expose a qt_arch input and add a new optional setup_env_script input to the reusable workflow so callers can run an environment setup script after Qt install and before CMake configure. Remove the previous osx_arch_flag logic and the built-in Rosetta install; instead the workflow runs setup_env_script only when provided. Update the macOS workflow to set qt_arch to clang_64 and supply a setup_env_script that installs Rosetta and sets CMAKE_OSX_ARCHITECTURES via GITHUB_ENV for Intel cross-compilation on ARM runners. --- .github/workflows/_build-shared.yml | 32 ++++++++++++++--------------- .github/workflows/macos.yml | 6 +++++- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/.github/workflows/_build-shared.yml b/.github/workflows/_build-shared.yml index 372f22b..7e645c9 100644 --- a/.github/workflows/_build-shared.yml +++ b/.github/workflows/_build-shared.yml @@ -15,7 +15,16 @@ on: qt_version: required: true type: string - qt_arch: + qt_arch: # get rid of this, eventually, by detecting the correct Qt architecture based on the OS and compiler- + description: Qt architecture passed to jurplel/install-qt-action (e.g. clang_64 for macOS Intel). + required: false + type: string + default: '' + setup_env_script: + description: > + Optional shell script run after Qt is installed and before CMake configure. + Use this to configure the build environment (e.g. install Rosetta, export + CMAKE_OSX_ARCHITECTURES). When omitted the step is skipped entirely. required: false type: string default: '' @@ -29,22 +38,13 @@ jobs: - name: Set reusable strings id: strings shell: bash - run: | - echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" - # When cross-compiling for Intel x86_64 on an ARM64 runner, pass the - # architecture flag so CMake emits x86_64 binaries. Rosetta 2 runs them. - if [[ "${{ runner.os }}" == "macOS" && "${{ runner.arch }}" == "ARM64" && "${{ inputs.qt_arch }}" == "clang_64" ]]; then - echo "osx_arch_flag=-DCMAKE_OSX_ARCHITECTURES=x86_64" >> "$GITHUB_OUTPUT" - else - echo "osx_arch_flag=" >> "$GITHUB_OUTPUT" - fi - - - name: Install Rosetta - # Required so macOS can execute the x86_64 binaries built when cross-compiling - # for Intel on an ARM64 runner. - if: runner.os == 'macOS' && runner.arch == 'ARM64' && inputs.qt_arch == 'clang_64' - run: softwareupdate --install-rosetta --agree-to-license + run: echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" + - name: Set up environment + if: ${{ inputs.setup_env_script }} + shell: bash + run: ${{ inputs.setup_env_script }} + - name: Install Qt uses: jurplel/install-qt-action@v4 with: diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 28b984b..a0a44b8 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -38,7 +38,11 @@ jobs: c_compiler: ${{ matrix.c_compiler }} cpp_compiler: ${{ matrix.cpp_compiler }} qt_version: ${{ matrix.qt_version }} - qt_arch: clang_64 # x86_64 Qt; triggers Rosetta install + CMAKE_OSX_ARCHITECTURES=x86_64 + qt_arch: clang_64 # x86_64 Qt binary for Intel cross-compilation + setup_env_script: | + # Install Rosetta 2 so x86_64 test binaries can run on the ARM64 runner. + softwareupdate --install-rosetta --agree-to-license || true + echo "CMAKE_OSX_ARCHITECTURES=x86_64" >> "$GITHUB_ENV" build-macos-arm: name: macos-${{ matrix.c_compiler }}-qt${{ matrix.qt_version }}-arm