Skip to content

Commit

Permalink
Add preliminary support for Qt for visionOS
Browse files Browse the repository at this point in the history
Qt already runs on Vision Pro as "Designed for iPad", using Qt
for iOS. This change enables building Qt for visionOS directly,
which opens the door to visionOS specific APIs and use-cases
such as volumes and immersive spaces.

The platform removes some APIs we depend on, notably UIScreen,
so some code paths have been disabled or mocked to get something
up and running.

As our current window management approach on UIKit platforms
depends on UIWindow and UIScreen there is currently no way to
bring up QWindows. This will improve once we refactor our
window management to use window scenes.

To configure for visionOS, pass -platform macx-visionos-clang,
and optionally add -sdk xrsimulator to build for the simulator.

Change-Id: I4eda55fc3fd06e12d30a188928487cf68940ee07
Reviewed-by:  Alexey Edelev <[email protected]>
  • Loading branch information
torarnv committed Apr 18, 2024
1 parent bf2ed62 commit d5bf42f
Show file tree
Hide file tree
Showing 58 changed files with 468 additions and 125 deletions.
5 changes: 5 additions & 0 deletions .cmake.conf
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,8 @@ set(QT_SUPPORTED_MIN_MACOS_XCODE_VERSION "14")
set(QT_SUPPORTED_MIN_IOS_SDK_VERSION "16")
set(QT_SUPPORTED_MAX_IOS_SDK_VERSION "17")
set(QT_SUPPORTED_MIN_IOS_XCODE_VERSION "14")

set(QT_SUPPORTED_MIN_VISIONOS_SDK_VERSION "1")
set(QT_SUPPORTED_MAX_VISIONOS_SDK_VERSION "1")
set(QT_SUPPORTED_MIN_VISIONOS_XCODE_VERSION "15")

13 changes: 8 additions & 5 deletions cmake/QtAutoDetectHelpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ function(qt_auto_detect_apple)

if("${QT_QMAKE_TARGET_MKSPEC}" STREQUAL "macx-ios-clang")
set(CMAKE_SYSTEM_NAME "iOS" CACHE STRING "")
elseif("${QT_QMAKE_TARGET_MKSPEC}" STREQUAL "macx-visionos-clang")
set(CMAKE_SYSTEM_NAME "visionOS" CACHE STRING "")
endif()

if(CMAKE_SYSTEM_NAME STREQUAL iOS)
Expand Down Expand Up @@ -226,13 +228,14 @@ function(qt_auto_detect_apple)
endif()
endif()

# For non simulator_and_device builds, we need to explicitly set the SYSROOT aka the sdk
# value.
if(QT_APPLE_SDK)
set(CMAKE_OSX_SYSROOT "${QT_APPLE_SDK}" CACHE STRING "")
endif()
set(CMAKE_OSX_ARCHITECTURES "${osx_architectures}" CACHE STRING "")
endif()

if(QT_APPLE_SDK)
set(CMAKE_OSX_SYSROOT "${QT_APPLE_SDK}" CACHE STRING "")
endif()

if(CMAKE_SYSTEM_NAME STREQUAL iOS OR CMAKE_SYSTEM_NAME STREQUAL visionOS)
if(NOT DEFINED BUILD_SHARED_LIBS)
qt_internal_ensure_static_qt_config()
endif()
Expand Down
4 changes: 4 additions & 0 deletions cmake/QtBaseGlobalTargets.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ qt_copy_or_install(DIRECTORY cmake/
PATTERN "3rdparty" EXCLUDE
PATTERN "macos" EXCLUDE
PATTERN "ios" EXCLUDE
PATTERN "visionos" EXCLUDE
PATTERN "platforms" EXCLUDE
PATTERN "QtBuildInternals" EXCLUDE
)
Expand All @@ -335,6 +336,7 @@ if(QT_WILL_INSTALL)
PATTERN "3rdparty" EXCLUDE
PATTERN "macos" EXCLUDE
PATTERN "ios" EXCLUDE
PATTERN "visionos" EXCLUDE
PATTERN "platforms" EXCLUDE
PATTERN "QtBuildInternals" EXCLUDE
)
Expand All @@ -345,6 +347,8 @@ if(APPLE)
set(platform_shortname "macos")
elseif(IOS)
set(platform_shortname "ios")
elseif(VISIONOS)
set(platform_shortname "visionos")
endif()

# Info.plist
Expand Down
2 changes: 2 additions & 0 deletions cmake/QtBuildPathsHelpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ macro(qt_internal_set_qt_apple_support_files_path)
set(__qt_internal_cmake_apple_support_files_path "${QT_CMAKE_DIR}/macos")
elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS")
set(__qt_internal_cmake_apple_support_files_path "${QT_CMAKE_DIR}/ios")
elseif(CMAKE_SYSTEM_NAME STREQUAL "visionOS")
set(__qt_internal_cmake_apple_support_files_path "${QT_CMAKE_DIR}/visionos")
endif()
endif()
endmacro()
Expand Down
2 changes: 2 additions & 0 deletions cmake/QtConfig.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ if(APPLE)
set(__qt_internal_cmake_apple_support_files_path "${_qt_import_prefix}/macos")
elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS")
set(__qt_internal_cmake_apple_support_files_path "${_qt_import_prefix}/ios")
elseif(CMAKE_SYSTEM_NAME STREQUAL "visionOS")
set(__qt_internal_cmake_apple_support_files_path "${_qt_import_prefix}/visionos")
endif()
endif()

Expand Down
3 changes: 2 additions & 1 deletion cmake/QtPlatformSupport.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ qt_set01(BSD APPLE OR OPENBSD OR FREEBSD OR NETBSD)
qt_set01(IOS APPLE AND CMAKE_SYSTEM_NAME STREQUAL "iOS")
qt_set01(TVOS APPLE AND CMAKE_SYSTEM_NAME STREQUAL "tvOS")
qt_set01(WATCHOS APPLE AND CMAKE_SYSTEM_NAME STREQUAL "watchOS")
qt_set01(UIKIT APPLE AND (IOS OR TVOS OR WATCHOS))
qt_set01(VISIONOS APPLE AND CMAKE_SYSTEM_NAME STREQUAL "visionOS")
qt_set01(UIKIT APPLE AND (IOS OR TVOS OR WATCHOS OR VISIONOS))
qt_set01(MACOS APPLE AND NOT UIKIT)

qt_set01(GCC CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
Expand Down
22 changes: 21 additions & 1 deletion cmake/QtPublicAppleHelpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,12 @@ function(_qt_internal_export_apple_sdk_and_xcode_version_requirements out_var)
QT_SUPPORTED_MAX_IOS_SDK_VERSION
QT_SUPPORTED_MIN_IOS_XCODE_VERSION
)
elseif(VISIONOS)
set(vars_to_assign
QT_SUPPORTED_MIN_VISIONOS_SDK_VERSION
QT_SUPPORTED_MAX_VISIONOS_SDK_VERSION
QT_SUPPORTED_MIN_VISIONOS_XCODE_VERSION
)
else()
set(vars_to_assign
QT_SUPPORTED_MIN_MACOS_SDK_VERSION
Expand All @@ -707,6 +713,8 @@ function(_qt_internal_get_apple_sdk_version out_var)
if(APPLE)
if(CMAKE_SYSTEM_NAME STREQUAL iOS)
set(sdk_name "iphoneos")
elseif(CMAKE_SYSTEM_NAME STREQUAL visionOS)
set(sdk_name "xros")
else()
# Default to macOS
set(sdk_name "macosx")
Expand Down Expand Up @@ -804,6 +812,10 @@ function(_qt_internal_check_apple_sdk_and_xcode_versions)
set(min_sdk_version "${QT_SUPPORTED_MIN_IOS_SDK_VERSION}")
set(max_sdk_version "${QT_SUPPORTED_MAX_IOS_SDK_VERSION}")
set(min_xcode_version "${QT_SUPPORTED_MIN_IOS_XCODE_VERSION}")
elseif(VISIONOS)
set(min_sdk_version "${QT_SUPPORTED_MIN_VISIONOS_SDK_VERSION}")
set(max_sdk_version "${QT_SUPPORTED_MAX_VISIONOS_SDK_VERSION}")
set(min_xcode_version "${QT_SUPPORTED_MIN_VISIONOS_XCODE_VERSION}")
else()
set(min_sdk_version "${QT_SUPPORTED_MIN_MACOS_SDK_VERSION}")
set(max_sdk_version "${QT_SUPPORTED_MAX_MACOS_SDK_VERSION}")
Expand Down Expand Up @@ -885,7 +897,7 @@ function(_qt_internal_check_apple_sdk_and_xcode_versions)
endfunction()

function(_qt_internal_finalize_apple_app target)
# Shared between macOS and iOS apps
# Shared between macOS and UIKit apps

_qt_internal_copy_info_plist("${target}")
_qt_internal_set_apple_localizations("${target}")
Expand All @@ -905,6 +917,14 @@ function(_qt_internal_finalize_apple_app target)
_qt_internal_set_placeholder_apple_bundle_version("${target}")
endfunction()

function(_qt_internal_finalize_uikit_app target)
if(CMAKE_SYSTEM_NAME STREQUAL iOS)
_qt_internal_finalize_ios_app("${target}")
else()
_qt_internal_finalize_apple_app("${target}")
endif()
endfunction()

function(_qt_internal_finalize_ios_app target)
# Must be called before we generate the Info.plist
_qt_internal_handle_ios_launch_screen("${target}")
Expand Down
2 changes: 1 addition & 1 deletion cmake/QtWrapperScriptHelpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function(qt_internal_create_wrapper_scripts)
set(extra_qt_cmake_code "")
if(generate_unix)

if(IOS)
if(UIKIT)
set(extra_qt_cmake_code [=[
# Specify Xcode as the default generator by assigning it to the CMAKE_GENERATOR env var.
# An explicit -G or -D CMAKE_GENERATOR given on the command line will still take precedence.
Expand Down
42 changes: 42 additions & 0 deletions cmake/visionos/Info.plist.app.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>

<key>CFBundlePackageType</key>
<string>APPL</string>

<key>CFBundleName</key>
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>

<key>CFBundleDisplayName</key>
<string>${QT_INTERNAL_DOLLAR_VAR}{PRODUCT_NAME}</string>

<key>CFBundleIdentifier</key>
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>

<key>CFBundleExecutable</key>
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>

<key>CFBundleVersion</key>
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>

<key>CFBundleShortVersionString</key>
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>

<key>CFBundleIconFile</key>
<string>${MACOSX_BUNDLE_ICON_FILE}</string>

<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleAllowMixedLocalizations</key>
<true/>

<key>CFBundleSupportedPlatforms</key>
<array>
<string>XROS</string>
</array>
</dict>
</plist>
14 changes: 14 additions & 0 deletions cmake/visionos/PrivacyInfo.xcprivacy
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypes</key>
<array/>
<key>NSPrivacyTrackingDomains</key>
<array/>
<key>NSPrivacyAccessedAPITypes</key>
<array/>
</dict>
</plist>
2 changes: 1 addition & 1 deletion configure.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ if(APPLE)
endif()
qt_feature("simulator_and_device" PUBLIC
LABEL "Build for both simulator and device"
CONDITION UIKIT AND NOT QT_APPLE_SDK
CONDITION IOS AND NOT QT_APPLE_SDK
)
qt_feature_config("simulator_and_device" QMAKE_PUBLIC_QT_CONFIG)
qt_feature("rpath" PUBLIC
Expand Down
24 changes: 16 additions & 8 deletions mkspecs/features/mac/default_post.prf
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,12 @@ macx-xcode {

QMAKE_XCODE_ARCHS =

arch_device.name = "ARCHS[sdk=$${device.sdk}*]"
arch_device.value = $$QMAKE_APPLE_DEVICE_ARCHS
QMAKE_XCODE_ARCHS += $$QMAKE_APPLE_DEVICE_ARCHS
QMAKE_MAC_XCODE_SETTINGS += arch_device
!isEmpty(QMAKE_APPLE_DEVICE_ARCHS) {
arch_device.name = "ARCHS[sdk=$${device.sdk}*]"
arch_device.value = $$QMAKE_APPLE_DEVICE_ARCHS
QMAKE_XCODE_ARCHS += $$QMAKE_APPLE_DEVICE_ARCHS
QMAKE_MAC_XCODE_SETTINGS += arch_device
}

ios:simulator {
arch_simulator.name = "ARCHS[sdk=$${simulator.sdk}*]"
Expand Down Expand Up @@ -224,10 +226,16 @@ macx-xcode {
platform_identifier = $$device.sdk
sysroot_path = $$xcodeSDKInfo(Path, $$device.sdk)
}
version_min_flag = -m$${version_identifier}-version-min=$$deployment_target
QMAKE_CFLAGS += -isysroot $$sysroot_path $$version_min_flag
QMAKE_CXXFLAGS += -isysroot $$sysroot_path $$version_min_flag
QMAKE_LFLAGS += -isysroot $$sysroot_path $$version_min_flag
QMAKE_CFLAGS += -isysroot $$sysroot_path
QMAKE_CXXFLAGS += -isysroot $$sysroot_path
QMAKE_LFLAGS += -isysroot $$sysroot_path

!isEmpty(version_identifier):!isEmpty(deployment_target) {
version_min_flag = -m$${version_identifier}-version-min=$$deployment_target
QMAKE_CFLAGS += $$version_min_flag
QMAKE_CXXFLAGS += $$version_min_flag
QMAKE_LFLAGS += $$version_min_flag
}
}

# Enable precompiled headers for multiple architectures
Expand Down
2 changes: 1 addition & 1 deletion mkspecs/features/toolchain.prf
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ isEmpty($${target_prefix}.INCDIRS) {
# UIKit simulator platforms will see the device SDK's sysroot in
# QMAKE_DEFAULT_*DIRS, because they're handled in a single build pass.
darwin {
uikit {
uikit:!isEmpty(QMAKE_APPLE_DEVICE_ARCHS) {
# Clang doesn't automatically pick up the architecture, just because
# we're passing the iOS sysroot below, and we will end up building the
# test for the host architecture, resulting in linker errors when
Expand Down
39 changes: 39 additions & 0 deletions mkspecs/macx-visionos-clang/Info.plist.app
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>

<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>

<key>CFBundleIconFile</key>
<string>${ASSETCATALOG_COMPILER_APPICON_NAME}</string>

<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>

<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>

<key>CFBundlePackageType</key>
<string>APPL</string>

<key>CFBundleShortVersionString</key>
<string>${QMAKE_SHORT_VERSION}</string>

<key>CFBundleVersion</key>
<string>${QMAKE_FULL_VERSION}</string>

<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleAllowMixedLocalizations</key>
<true/>

<key>CFBundleSupportedPlatforms</key>
<array>
<string>XROS</string>
</array>
</dict>
</plist>
18 changes: 18 additions & 0 deletions mkspecs/macx-visionos-clang/Info.plist.dSYM.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
<plist version=\"1.0\">
<dict>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.$${BUNDLEIDENTIFIER}</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
!!IF !isEmpty(VERSION)
<key>CFBundleShortVersionString</key>
<string>$${VER_MAJ}.$${VER_MIN}</string>
<key>CFBundleVersion</key>
<string>$${VER_MAJ}.$${VER_MIN}.$${VER_PAT}</string>
!!ENDIF
</dict>
</plist>
20 changes: 20 additions & 0 deletions mkspecs/macx-visionos-clang/Info.plist.lib
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>${QMAKE_SHORT_VERSION}</string>
<key>CFBundleSignature</key>
<string>${QMAKE_PKGINFO_TYPEINFO}</string>
<key>CFBundleVersion</key>
<string>${QMAKE_FULL_VERSION}</string>
<key>NOTE</key>
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
</dict>
</plist>
29 changes: 29 additions & 0 deletions mkspecs/macx-visionos-clang/qmake.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#
# qmake configuration for visionOS
#

QMAKE_PLATFORM += visionos
QMAKE_MAC_SDK = xros

device.sdk = xros
device.target = device
device.dir_affix = $${device.sdk}
device.CONFIG = $${device.sdk}
device.deployment_identifier =

simulator.sdk = xrsimulator
simulator.target = simulator
simulator.dir_affix = $${simulator.sdk}
simulator.CONFIG = $${simulator.sdk}
simulator.deployment_identifier =

QMAKE_APPLE_TARGETED_DEVICE_FAMILY = 7

include(../common/uikit.conf)
include(../common/gcc-base-mac.conf)
include(../common/clang.conf)
include(../common/clang-mac.conf)
include(../common/uikit/clang.conf)
include(../common/uikit/qmake.conf)

load(qt_config)
4 changes: 4 additions & 0 deletions mkspecs/macx-visionos-clang/qplatformdefs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

#include "../common/mac/qplatformdefs.h"
Loading

0 comments on commit d5bf42f

Please sign in to comment.