Qt for macOS

macOS(之前称为 OS X 或 Mac OS X)是 Apple 为 Mac 电脑系列设计的操作系统。它是一个基于 Darwin 内核的 UNIX 平台,在很大程度上与其他类 UNIX 平台类似。主要区别在于不使用 X11 作为窗口系统。相反,macOS 使用自己的原生窗口系统,通过 Cocoa API 可访问。

要下载和安装 Qt for macOS,请按照Qt 入门页面上的说明进行操作。要从源码构建 Qt,请参阅macOS - 从源码构建 Qt

支持版本

在谈论 macOS 上的版本支持时,区分构建环境(构建的平台或使用平台)和目标平台(构建的平台)是非常重要的。以下 macOS 版本得到支持。

目标平台架构构建环境注意
macOS 11、12、13、14x86_64x86_64harm64Xcode 14(macOS 13 SDK)、Xcode 15(macOS 14 SDK)

构建环境

macOS 上的构建环境完全由您构建应用程序使用的 Xcode 版本来定义。Xcode 包含工具链(编译器、链接器和其他工具)和 macOS 平台 SDK(头文件和库)。这些共同定义了应用程序的构建方式。

注意:您在 Xcode 上运行 macOS 版本无关紧要。只要 Apple 为您的操作系统提供可运行的给定 Xcode 版本,构建环境将由该 Xcode 版本定义。

可以从 Apple 的开发者网站(包括旧版本的 Xcode)下载 Xcode。

您应该始终使用 Apple 提供的最新版本的 Xcode,并且已经根据您使用的 Qt 版本进行了测试。通过始终针对最新的平台 SDK 进行构建,您可以确保 Qt 可以利用 macOS 新版本中引入的新功能。

安装后,使用xcode-select工具选择 Xcode 安装。

$ sudo xcode-select --switch /Applications/Xcode.app

您可以使用相同的工具检查全局选择的 Xcode 安装。

$ xcode-select -print-path
/Applications/Xcode.app/Contents/Developer

然后可以使用xcrun命令在工具链中查找特定工具。

$ xcrun -sdk macosx -find clang
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang

或显示构建时使用的平台 SDK 路径。

$ xcrun -sdk macosx --show-sdk-path
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk

目标平台

为 macOS 构建使用了一种称为弱链接的技术,该技术允许您针对最新平台 SDK 的头文件和库构建应用程序,同时您的应用程序仍可部署到低于 SDK 版本的 macOS 版本。当在低于构建 SDK 版本的 macOS 版本上运行二进制文件时,Qt 将在运行时检查是否可用平台功能,然后再使用它。

从理论上讲,这将允许您在发布的每个macOS版本上运行您的应用程序,但由于实际(和技术)原因,这个范围有一个下限,称为应用程序的部署目标。如果二进制文件在低于部署目标的macOS版本上启动,Qt将显示错误消息,应用程序将无法运行。

Qt通过CMAKE_OSX_DEPLOYMENT_TARGETQMAKE_MACOSX_DEPLOYMENT_TARGET变量来表示部署目标,默认情况下,这是Qt支持的最小部署目标。

只有在您的代码使用了在macOS版本中添加的API,并且您在运行时没有使用@available检查来保护它们的使用时,您才需要提高部署目标。

使用CMake提高部署目标

set(CMAKE_OSX_DEPLOYMENT_TARGET "13.0")

或使用qmake

QMAKE_MACOSX_DEPLOYMENT_TARGET = 13.0

注意:您不应将部署目标降低到Qt设置的默认值以下。这样做可能会导致在部署到低于Qt预期运行的macOS版本时,二进制文件在运行时崩溃。

有关在macOS上基于SDK的开发更多信息,请参阅Apple的开发者文档

选择不采用macOS行为变化

使用最新版本的Xcode和SDK构建应用程序的一个局限性是,macOS的系统框架有时会根据您用于构建应用程序的SDK来决定是否启用行为变化。

例如,当macOS 10.14 Mojave引入暗黑模式时,macOS仅将针对10.14 SDK构建的应用程序视为支持暗黑模式,而将针对较早SDK构建的应用程序保留为默认亮模式外观。这种技术允许Apple确保在新macOS版本推出之前构建的二进制文件仍然可以继续无回归地运行。

针对较旧SDK构建是最后一个解决方案,并且仅在您的应用程序没有其他方法来解决该问题时才应用。

架构

默认情况下,Qt将为开发机的架构进行构建 - 如果您使用的是Intel Mac,则为x86_64,如果您使用的是Apple Silicon Mac,则为arm64

要为其他架构进行构建,您可以使用项目文件或命令行中的CMAKE_OSX_ARCHITECTURESQMAKE_APPLE_DEVICE_ARCHS变量。这允许您针对不同架构进行交叉编译,并构建通用(多架构)二进制文件。例如,使用CMake为x86_64arm64构建您的应用程序

cmake ~/src/myapp -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"

或使用qmake

qmake ~/src/myapp QMAKE_APPLE_DEVICE_ARCHS="x86_64 arm64"

在项目文件中指定架构时,不应添加引号,例如。

TEMPLATE = app
SOURCES = main.cpp
QMAKE_APPLE_DEVICE_ARCHS = x86_64 arm64

Intel Mac上的子架构支持

除了基础的x86_64架构外,Qt还支持x86_64h(“Haswell”)子架构,它可以提高Intel Mac的性能。

生成Xcode项目文件

默认情况下,CMake和qmake以Makefile格式生成项目文件。如果您希望从Xcode内部构建和调试应用程序,可以要求生成Xcode项目文件。

cmake ~/src/myapp -GXcode

或使用qmake

qmake ~/src/myapp -spec macx-xcode

在macOS上部署应用程序

macOS应用程序通常以独立的程序包的形式部署。程序包包含应用程序的可执行文件以及Qt库、插件、翻译和其他你需要的资源。像Qt这样的第三方库通常不会系统级安装;每个应用程序都提供自己的副本。

要使用CMake将你的应用程序作为程序包构建,请在你的可执行目标上设置MACOSX_BUNDLE属性,如下所示

qt_add_executable(app)
if(APPLE)
    set_target_properties(tst_manual_ios_assets PROPERTIES MACOSX_BUNDLE TRUE)
endif()

使用qmake,程序包是默认选项。在你的项目文件(.pro)中设置CONFIG -= app_bundle来禁用它。

分发应用程序的一种常见方式是提供可以由用户在Finder中挂载的压缩磁盘镜像(.dmg文件)。部署工具macdeployqt(可在macOS安装程序中获得)可用于创建自包含的程序包,并可选择创建.dmg存档。

应用程序也可以通过Mac App Store分发。macdeployqt(bin/macdeployqt)可以用作App Store部署的起点。为确保Qt符合App Store沙盒规则,Qt必须使用-feature-appstore-compliant参数进行配置。

有关macOS上的部署详细信息,请参阅Qt for macOS - Deployment

注意:对于在macOS App Store上销售应用,有特殊规则适用。为了通过验证,应用程序必须在执行任何代码之前验证有效收据的存在。由于这是一个复制保护机制,应采取措施避免常见模式,尽可能模糊验证收据的代码。因此,这不能通过Qt自动化,需要为应用程序本身编写一些特定平台代码。更多信息可参考Apple的文档

使用Objective-C代码在Qt应用程序中

Clang,用于Apple平台应用程序的编译器,允许混合C++和Objective-C代码。为了启用此模式,请在相关源文件中使用.mm扩展名,并将它们按常规添加到项目中。

使用CMake

target_sources(myapp PRIVATE objc_code.mm)

使用qmake

SOURCES += objc_code.mm

然后你可以在Qt应用程序中使用来自Apple开发者库的Objective-C框架。

为了在不重新命名所有源文件的情况下将功能暴露给应用程序的其他部分,请在一个头文件中声明辅助函数,并在Objective-C++源文件中实现功能。

// objc_code.h
QString localizedHostName();

// objc_code.mm
#include <Foundation/NSHost.h>
QString localizedHostName()
{
    return QString::fromNSString(NSHost.currentHost.localizedName);
}

macOS问题

以下页面涵盖了创建macOS应用程序的具体问题和推荐。

从这里开始

我们邀请您探索Qt的其他部分。我们准备了概述以帮助您决定使用哪些API,我们的示例演示了如何使用我们的API。

Qt的充满活力和积极参与的社区网站,http://qt.io是包含维基、论坛以及额外的学习指南和演示文稿的地方。

© 2024 Qt公司有限公司。在此包含的文档贡献的版权归其各自的所有者。在此提供的文档是根据Free Software Foundation发布的GNU自由文档许可版本1.3的条款许可的。Qt和相关标志是芬兰和/或其他国家/地区的Qt公司有限责任公司的商标。所有其他商标均为其各自所有者的财产。