build: SG-42130: XCode26 support#1091
build: SG-42130: XCode26 support#1091mcoliver wants to merge 8 commits intoAcademySoftwareFoundation:mainfrom
Conversation
Signed-off-by: Michael Oliver <mcoliver@gmail.com>
XCode26 was refusing to build Qt 6.5.3 and 6.8.3 because it lacks AGL. AGL is no longer used and newer versions of Qt have patched. This is a backport to patch 6.5.3 and 6.8.3. For reference: https://qt-project.atlassian.net/browse/QTBUG-137687 qt/qtbase@cdb33c3 Homebrew/homebrew-core@9ef0937 Signed-off-by: Michael Oliver <mcoliver@gmail.com>
updated cmake/dependencies/python3.cmake to use the IMPORTED_NO_SYSTEM property for the Python::Python target. This ensures that the Python include paths are treated as regular include paths (-I) rather than system include paths (-isystem), which resolves search order issues on newer Xcode versions. Signed-off-by: Michael Oliver <mcoliver@gmail.com>
Signed-off-by: Michael Oliver <mcoliver@gmail.com>
cmake-format -i CMakeLists.txt cmake/**/*.cmake Signed-off-by: Michael Oliver <mcoliver@gmail.com>
See this link for more details https://cmake.org/cmake/help/v3.31/prop_tgt/IMPORTED_NO_SYSTEM.html Signed-off-by: Michael Oliver <mcoliver@gmail.com>
cedrik-fuoco-adsk
left a comment
There was a problem hiding this comment.
Thank you for fixing that! Did you encounter any other build issue or warning that came with using XCode 26?
There was a problem hiding this comment.
Pull request overview
Adds an automated workaround to build with Xcode 26+ on macOS by patching community Qt installs to avoid AGL, and updates docs/config accordingly.
Changes:
- Auto-detect Xcode 26+ in
rvcmds.shand run a Qt patching script. - Add
apply_qt_fix.shandqt_fix.patchto remove AGL references from Qt files. - Update macOS build documentation and tweak Python CMake target properties.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| rvcmds.sh | Detects Xcode 26+ on macOS and invokes Qt patch application automatically. |
| apply_qt_fix.sh | New script to apply an AGL-removal patch to specific Qt versions. |
| qt_fix.patch | Patch content that removes AGL framework/header usage from Qt config files. |
| docs/build_system/config_macos.md | Documents the new Xcode 26+ Qt patch requirement and how it’s applied. |
| cmake/dependencies/python3.cmake | Alters properties of the imported Python::Python target (potentially to affect system include handling). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if [ -n "$XCODE_MAJOR_VERSION" ] && [ "$XCODE_MAJOR_VERSION" -ge 26 ]; then | ||
| QT_BASE_DIR=$(dirname $(dirname "$QT_HOME")) |
There was a problem hiding this comment.
QT_BASE_DIR=$(dirname $(dirname "$QT_HOME")) is vulnerable to word-splitting/globbing if QT_HOME contains spaces, and the -ge comparison will emit “integer expression expected” (and may misbehave) if xcodebuild returns a non-numeric token (e.g., beta/dev strings). Quote the nested dirname substitutions and validate the version is numeric (e.g., [[ ... =~ ^[0-9]+$ ]]) before doing -ge.
| if [ -n "$XCODE_MAJOR_VERSION" ] && [ "$XCODE_MAJOR_VERSION" -ge 26 ]; then | |
| QT_BASE_DIR=$(dirname $(dirname "$QT_HOME")) | |
| if [[ -n "$XCODE_MAJOR_VERSION" && "$XCODE_MAJOR_VERSION" =~ ^[0-9]+$ && "$XCODE_MAJOR_VERSION" -ge 26 ]]; then | |
| QT_BASE_DIR="$(dirname "$(dirname "$QT_HOME")")" |
docs/build_system/config_macos.md
Outdated
| In the meantime, you can use Xcode 16.4 on the latest macOS Tahoe 26 to build Open RV. | ||
| If you are using >= Xcode 26 you will need to patch Qt 6.5.3 and 6.8.3 to implement the fix for [QTBUG-137687](https://bugreports.qt.io/browse/QTBUG-137687). | ||
|
|
||
| This patch is ran during the sourcing of rvcmds.sh. You can also run it directly via `sh apply_qt_fix.sh` |
There was a problem hiding this comment.
The docs recommend running sh apply_qt_fix.sh, but apply_qt_fix.sh uses Bash-only features (notably the QT_VERSIONS=("6.5.3" "6.8.3") array). Running with sh will fail on systems where sh is not Bash; update the command to bash apply_qt_fix.sh or ./apply_qt_fix.sh.
| This patch is ran during the sourcing of rvcmds.sh. You can also run it directly via `sh apply_qt_fix.sh` | |
| This patch is ran during the sourcing of rvcmds.sh. You can also run it directly via `bash apply_qt_fix.sh` |
|
|
||
| if [[ "$(uname)" != "Darwin" ]]; then | ||
| echo "Error: This script is only intended for macOS (Darwin)." | ||
| exit 0 |
There was a problem hiding this comment.
The script prints an error but exits with status 0 on non-macOS, which makes failures look like success in CI/automation. Return a non-zero exit code (e.g., exit 1) or change the message to be non-error informational if you intend this to be a no-op.
| exit 0 | |
| exit 1 |
| # Check if patch applies cleanly | ||
| if patch -p1 -d "$QT_DIR" --dry-run --batch < "$PATCH_FILE" >/dev/null 2>&1; then | ||
| echo "Applying patch to $version..." | ||
| patch -p1 -d "$QT_DIR" --batch < "$PATCH_FILE" | ||
| echo "Successfully patched $version." | ||
| else | ||
| echo "Error: Could not apply patch for version $version. It might be incompatible or already modified." | ||
| echo "Please check the files in $QT_DIR manually." | ||
| # Show dry run output for debugging | ||
| patch -p1 -d "$QT_DIR" --dry-run --batch < "$PATCH_FILE" | ||
| fi |
There was a problem hiding this comment.
If the patch cannot be applied, the script logs an error but continues and still ends with echo "Done.", producing a successful overall exit status. Consider tracking a failure flag and exiting non-zero at the end when any version fails to patch, so automated builds don’t silently proceed with an unpatched Qt.
|
|
||
| # Check if patch is already applied (by checking if AGL is still in FindWrapOpenGL.cmake) | ||
| if ! grep -q "AGL" "$QT_DIR/lib/cmake/Qt6/FindWrapOpenGL.cmake"; then | ||
| echo "Patch is already applied for version $version. Skipping." | ||
| continue | ||
| fi | ||
|
|
||
| # Check if patch applies cleanly | ||
| if patch -p1 -d "$QT_DIR" --dry-run --batch < "$PATCH_FILE" >/dev/null 2>&1; then | ||
| echo "Applying patch to $version..." | ||
| patch -p1 -d "$QT_DIR" --batch < "$PATCH_FILE" | ||
| echo "Successfully patched $version." | ||
| else | ||
| echo "Error: Could not apply patch for version $version. It might be incompatible or already modified." | ||
| echo "Please check the files in $QT_DIR manually." | ||
| # Show dry run output for debugging | ||
| patch -p1 -d "$QT_DIR" --dry-run --batch < "$PATCH_FILE" |
There was a problem hiding this comment.
The “already applied” detection is overly broad: grep -q "AGL" could match unrelated text and cause false positives/negatives across Qt point releases. Prefer checking for a more specific removed token (e.g., WrapOpenGL_AGL or -framework AGL) and/or validate both files touched by the patch (the CMake module and mkspecs/common/mac.conf) before declaring the patch applied.
| # Check if patch is already applied (by checking if AGL is still in FindWrapOpenGL.cmake) | |
| if ! grep -q "AGL" "$QT_DIR/lib/cmake/Qt6/FindWrapOpenGL.cmake"; then | |
| echo "Patch is already applied for version $version. Skipping." | |
| continue | |
| fi | |
| # Check if patch applies cleanly | |
| if patch -p1 -d "$QT_DIR" --dry-run --batch < "$PATCH_FILE" >/dev/null 2>&1; then | |
| echo "Applying patch to $version..." | |
| patch -p1 -d "$QT_DIR" --batch < "$PATCH_FILE" | |
| echo "Successfully patched $version." | |
| else | |
| echo "Error: Could not apply patch for version $version. It might be incompatible or already modified." | |
| echo "Please check the files in $QT_DIR manually." | |
| # Show dry run output for debugging | |
| patch -p1 -d "$QT_DIR" --dry-run --batch < "$PATCH_FILE" | |
| FIND_MODULE="$QT_DIR/lib/cmake/Qt6/FindWrapOpenGL.cmake" | |
| MAC_CONF="$QT_DIR/mkspecs/common/mac.conf" | |
| # Ensure expected Qt files exist before proceeding | |
| if [ ! -f "$FIND_MODULE" ] || [ ! -f "$MAC_CONF" ]; then | |
| echo "Warning: Required Qt files not found for version $version. Skipping." | |
| continue | |
| fi | |
| # Check if patch is already applied: | |
| # - WrapOpenGL_AGL removed from FindWrapOpenGL.cmake | |
| # - -framework AGL removed from mkspecs/common/mac.conf | |
| if ! grep -q "WrapOpenGL_AGL" "$FIND_MODULE" && \ | |
| ! grep -q -- "-framework AGL" "$MAC_CONF"; then | |
| echo "Patch is already applied for version $version. Skipping." | |
| continue | |
| fi | |
| # Check if patch applies cleanly | |
| if patch -p1 -d "$QT_DIR" --dry-run --batch < "$PATCH_FILE" >/dev/null 2>&1; then | |
| echo "Applying patch to $version..." | |
| patch -p1 -d "$QT_DIR" --batch < "$PATCH_FILE" | |
| echo "Successfully patched $version." | |
| else | |
| echo "Error: Could not apply patch for version $version. It might be incompatible or already modified." | |
| echo "Please check the files in $QT_DIR manually." | |
| # Show dry run output for debugging | |
| patch -p1 -d "$QT_DIR" --dry-run --batch < "$PATCH_FILE" |
There was a problem hiding this comment.
LGTM
Thank you @mcoliver for this great contribution !
non code changes. Grammatical fixes to docs. Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Michael Oliver <mcoliver@gmail.com>
|
I updated your branch to main to test it locally on my MacBook, but there are some issues with pre-commit again. |
|
Hi @mcoliver, we would be ready to merge the PR. Do you have time to fix the various issues? |
[ 1090: Build with Xcode26 ]
Linked issues
Fixes #1090
Summarize your change.
Backported a patch to Qt 6.5.3 and 6.8.3 which are the community versions available and do not have the patch in commercial versions
Describe the reason for the change.
Want to build with Xcode26. Was annoying to constantly have to switch with xcode-select. Additionally xcode26 should bring some compiler optimizations that may improve performance.
Describe what you have tested and on which operating system.
macos26.2 with Xcode26.2. RV CY2025