将Mac OS应用程序移植到Apple Silicon Appkit文档

将Mac OS应用程序移植到Apple Silicon

创建可在Apple芯片和基于Intel的Mac计算机上运行的macOS应用程序的版本


总览

通过创建通用二进制文件并修改代码以处理体系结构差异,将现有的macOS应用移植到Apple芯片。通用二进制文件看起来与常规应用程序没有什么不同,但是其可执行文件包含已编译代码的两个版本。一个版本在Apple芯片上本地运行,另一个版本在基于Intel的Mac计算机上本地运行。在运行时,系统会自动选择要在当前平台上运行的版本。

image.png

要构建通用二进制文件,您需要Xcode 12或更高版本,这会添加arm64到macOS二进制文件的构建体系结构的标准列表中。当您打开项目并执行干净的构建时,如果您的项目使用标准体系结构,则Xcode会自动创建一个通用二进制文件。如果使用自定义makefile文件或构建脚本,请将arm64体系结构添加到构建系统中。

创建通用二进制文件后,请在两种体系结构上对其进行测试,然后确定是否需要进行其他更改。macOS框架使应用程序免受平台之间的大多数体系结构差异的影响,但某些差异可能仍需要您更改代码。此外,架构上的差异可能会影响您应用的性能,并需要进行进一步的更改。

注意,在Apple芯片上,为该体系结构构建的应用程序在Rosetta转换环境下运行。有关更多信息,请参见关于Rosetta翻译环境。x86_64

要了解如何构建通用二进制文件,请参阅构建通用macOS Binary。


创建一个移植计划

在移植过程的早期,确定用于构建和测试代码的工作流程。Xcode可在所有Mac计算机上运行,​​因此可以在Apple芯片或基于Intel的Mac计算机上构建代码,并在那里进行初始测试。但是,请始终在两种计算机类型上测试,调整和验证代码,以发现特定于该体系结构的问题。

image.png

除了工作流程计划之外,还要确定在移植过程中要调查的潜在区域。移植工作arm64取决于您对硬件特定功能的依赖程度。如果您主要依靠Apple框架和技术,则移植工作可能会很少。如果您专门针对体系结构和硬件功能调整了代码,则移植到可能需要更多的精力。

要开始调查,请记下执行以下操作的所有代码:

扫描二维码关注公众号,回复: 11654087 查看本文章
  • 与您不拥有的第三方库进行交互。

  • 与内核或硬件交互。

  • 依赖于特定的GPU行为。

  • 包含汇编说明。

  • 管理线程或优化应用程序的多线程行为。

  • 包含特定于硬件的假设或性能优化。

上面的列表并不详尽,但是它为您进行调查提供了起点。硬件和体系结构的差异可能会在Apple芯片上的代码中引入错误或性能问题。及早发现潜在的问题区域可以节省您的时间。

始终有一个定义明确的测试计划,理想情况下,您可以在构建时运行一组自动化测试套件。除了测试代码的正确性之外,还要收集有关应用程序性能的指标。检查应用程序的内存使用情况,并测量在Apple芯片和基于Intel的Mac计算机上执行特定任务所需的时间。使用该信息来确定要调查的其他区域。

获取链接库的通用版本

如果您的项目依赖于任何第三方库,请与原始供应商联系,并要求他们为您提供这些库的通用版本。在同一进程中运行的所有代码必须支持相同的体系结构。没有所有链接库的通用版本,就无法生成二进制的通用版本。如果一个或多个库不是通用库,则链接器将报告错误。

image.png

要了解如何创建自己的通用二进制文件,请参阅构建通用macOS Binary

将插件更新为通用二进制文件

通用插件可以在任何Mac计算机上本地运行。如果您的应用程序支持插件模型,请创建您管理的插件的通用版本。如果您的公司允许外部开发人员提供插件,则鼓励这些开发人员创建其插件的通用版本。

如果您的应用直接将通用插件加载到其处理空间中,那么通用插件至关重要。在同一进程中运行的代码必须支持相同的体系结构。如果您的应用尝试加载具有不兼容架构的插件,则系统会在加载时报告错误。

image.png

使用XPC服务在进程外运行的插件可能会使用与应用程序本身不同的体系结构来运行。为了使您的开发人员有时间更新其插件,请提供两种非通用的XPC服务-一种用于运行arm64插件,另一种用于运行插件。单个XPC服务可以管理本机或翻译后的插件,但不能同时管理两者。创建服务时,为每个服务分配一个唯一的捆绑包标识符,以便它们可以同时运行。x86<wbr data-v-7fb764c1="" style="quotes: &quot;“&quot; &quot;”&quot;; font-style: normal;">_64

有关如何使用XPC与进程外插件进行通信的信息,请参见XPC

解决架构差异

除了处理器和图形硬件的大规模更改之外,Apple芯片和基于Intel的Mac计算机之间还存在细微的体系结构差异。在移植过程中,审核您的代码以识别针对任何潜在体系结构问题的修复程序。例如,寻找代码依赖特定硬件功能或配置的地方。

下表列出了Apple芯片和基于Intel的Mac计算机之间的几种已知体系结构差异。更新依赖于以下任何一项的代码:

  • 虚拟内存页面大小

  • 缓存行大小

  • 可变函数

  • 同时可写和可执行的内存

  • 即时编译器

  • 实时线程

  • 显式线程优先级

  • 特定于硬件的详细信息

  • 汇编语言说明或内置内在函数

  • 向量单位说明

  • C ++ ABI详细信息

注意

苹果芯片和基于Intel的Mac计算机都使用低字节序格式的数据,因此您无需在代码中进行字节序转换。但是,继续尽量减少您创建的自定义数据格式中的字节序转换的需求。

有关架构差异的其他信息,请参阅《解决macOS代码中的架构差异》

更新GPU专用代码

Apple硅上的Metal支持基于Intel的Mac计算机和iOS设备的功能。如果您的应用程序采用仅在基于Intel的Mac计算机上发现的Metal功能,请考虑在arm64代码中也采用iOS特定的功能。采用这些功能可以提高许多应用程序的性能。

如果您的应用程序使用Metal,OpenGL或OpenCL,请注意以下区别:

  • 苹果芯片上的GPU和CPU共享内存。

  • OpenGL已弃用,但可在Apple芯片上使用。

  • OpenCL已过时,但在以GPU为目标时可在Apple芯片上使用。OpenCL CPU设备不可用于arm64应用程序。

有关如何更新图形代码的信息,请参阅将金属代码移植到Apple Silicon

更新驱动程序,系统扩展和内核扩展

将代码移植到macOS 11时,请注意与内核交互的代码的以下要求:

  • 使用DriverKit实现硬件驱动程序。如果支持macOS 11,则需要使用DriverKit扩展。现在,大多数驱动程序类型都支持DriverKit,但仍然只有少数几种类型需要创建内核扩展。

  • 内核扩展必须支持本机体系结构。内核扩展在内核中运行,并且内核始终作为本机进程运行。您不能使用Rosetta转换运行内核扩展。

  • 内核扩展的安装和卸载需要重新启动。当您安装内核扩展时,系统直到重新启动后才会加载您的扩展。

有关内核扩展和驱动程序更改的更多信息,请参见实施驱动程序,系统扩展和Kexts

从特定技术迁移

macOS包含了一些不推荐使用或不建议积极开发的技术。如果您的应用使用以下技术之一,请尽快迁移到适当的替代产品:

Apple芯片仍然提供对先前技术的支持,您可以继续在macOS 11中使用它们。但是,在将来的macOS版本中可能会删除此支持,因此建议迁移到较新的技术。

调试和测试您的代码

Apple芯片支持基于Intel的Mac计算机上找到的所有调试和测试工具。使用Xcode IDE设置和监视断点以及监视应用程序行为的其他方面。lldb从命令行使用可以在Xcode界面之外执行类似的任务。

有关如何调试和测试代码的更多信息,请参见Xcode

调整应用程序的性能

苹果芯片可运行基于Intel的Mac计算机上的所有性能工具。使用Instruments和其他性能工具为您的应用收集不同类型的指标,包括有关其内存使用,速度,能源使用等的信息。您还可以使用命令行工具,如leaksheaptop和识别潜在的性能问题。

体系结构差异arm64和平均是技术,还有一个系统的工作可能没有很好地对其他工作.

  • 不要以为独立的GPU意味着更好的性能。Apple处理器中集成的GPU已针对高性能图形任务进行了优化。请参阅将金属代码移植到Apple Silicon

  • 不要假设所有处理器内核都是相同的。苹果芯片上的处理器包含性能核心(P核心)和效率核心(E核心)的混合,它们执行具有不同性能特征的任务。使用服务质量(QoS)类可帮助系统在正确的核心类型上安排任务。

在移植过程中,请评估您的应用程序在Apple芯片和基于Intel的Mac计算机上的性能,并调查任何差异。在一个平台上运行需要更长时间的任务可能需要其他调整。

有关调整通用二进制文件的特定技巧,请参阅《调整Apple Silicon的代码性能》

加入我们一起学习SwiftUI

QQ:3365059189
SwiftUI技术交流QQ群:518696470

猜你喜欢

转载自blog.csdn.net/iCloudEnd/article/details/108559796