当前位置: 首页 > news >正文

真机 ARM64 架构转模拟器 ARM64 架构

1fe29b3b6a6acc8ce985075bb1d1244e.jpeg

0a572c9592763eecb9ecc0c3348ec2e6.gif

本文字数:2051

预计阅读时间:15分钟

4a6a53646cc377e5e3b78b8d89da1461.png

01

需要转换架构的原因

老版 Mac 使用 Intel 芯片,是x86_64架构,相应地在老版 Mac 上运行的模拟器使用的也就是 x86_64架构。

由于模拟器的 x86_64 架构与真机的 arm64、armv7 等架构不冲突,业界为了方便库文件管理,通常会将模拟器架构与真机架构通过 lipo 命令合并为一个 fat 文件。

对于 Intel 芯片的 Mac 这样处理就很高效合理的,但是 Apple 推出了 M 系列芯片的新版 Mac,这就导致模拟器也变成了 arm64 架构,同时 lipo 命令合并二进制文件时不允许出现同名的两个不同架构。也就是只要还采用通用二进制文件(fat 文件)的库管理方式,就无法同时使用真机 arm64 架构和模拟器 arm64 架构。

对于上述的问题, Apple 提供了两个解决方案:

1、XCFramework。可以根据编译环境指定使用的库文件,不用合成就避免了架构重名的问题。但是项目使用的第三方库很多,其他部门的库内又链接了其他的第三方库,全部更换不现实。(我们项目目前只有一个部门支持了XCFramework);

2、Rosetta Simulator。在 Xcode -》Product -》Destination 选项中,可以选择显示 Rosetta 模拟器,这样模拟器运行时使用的依旧是 x86_64 架构,同时搭配 Excluded Architectures = arm64 ,可以解决大部分项目模拟器运行的问题:

但是,visionOS Simulator 被 Apple 远程禁止了 Rosetta 选项!(早期的 Xcode15 beta 版还能显示 Rosetta 的 visionOS 模拟器,更新了一次就不见了。解包下载下来的 visionOS_1_beta_7_Simulator_Runtime,在 Contents/Resources/profile.plist 文件中可以看到支持的架构是包含x86_64的,应该是在Xcode层面禁止了Rosetta选项的出现)。如果我们想要提前验证项目在visionOS上跑起来的效果的话,就需要研究能否将链接库中的真机arm64架构提供给模拟器使用。

02

真机架构与模拟器架构的区别

为了弄清楚真机架构与模拟器架构的区别,我们需要将库文件解剖并对比二进制文件中的差异。

得益于外网的这篇博文arm64-to-sim,我们可以看到博主利用llvm对同一代码分别编译了真机与模拟器架构版本,并直接对比出了差异:

# in the FirebaseAnalytics.xcframework directory 
$ otool -fahl ios-arm64_i386_x86_64-simulator/FirebaseAnalytics.framework/FirebaseAnalytics | grep -E 'cmd |\.o' > simulator_cmds 
$ otool -fahl ios-arm64_armv7/FirebaseAnalytics.framework/FirebaseAnalytics | grep -E 'cmd |\.o' > native_cmds 
$ diff -u native_cmds simulator_cmds 
-ios-arm64_armv7/FirebaseAnalytics.framework/FirebaseAnalytics(FirebaseAnalytics_vers.o): 
+ios-arm64_i386_x86_64-simulator/FirebaseAnalytics.framework/FirebaseAnalytics(FirebaseAnalytics_vers.o):
cmd LC_SEGMENT_64 
-      cmd LC_VERSION_MIN_IPHONEOS 
+      cmd LC_BUILD_VERSION      
cmd LC_SYMTAB 
(...)

从上面的结果可以看到,区别只有一处,真机架构使用的loadcommand是LC_VERSION_MIN_IPHONEOS,而模拟器是LC_BUILD_VERSION。我们使用otool命令:

otool -lV xxx.o

可以查看二进制文件中load command的内容,对比结果如下图:

1189538595f439c4c9c9bd71c16e3137.png

03

如何修改

知道了区别在于load command,自然是要将LC_VERSION_MIN_IPHONEOS改为LC_BUILD_VERSION。但是Mach-O是一种很紧凑的文件格式,Mach-O中的三个区域Header & Load Commands & Data,其中Header记录了平台、文件类型、指令数、指令总大小等信息,Load Commands紧跟Header,其中部分Load Command包含了Data中数据段的起始位置和数据大小:

2283880617b714dd93a458eedabc5b07.png

修改LC_VERSION_MIN_IPHONEOS为LC_BUILD_VERSION会导致Mach-O整体大小发生变化(如图所示,cmdsize不同),Header中的大小信息需要同步修改,由于Data处于Load Commands位置后面,Data所在位置也就发生了偏移,部分load command所指向的位置也需要进行对应的偏移。

体现到代码上,参照arm64-to-sim开源命令行工具。

1、提取静态库中的arm64架构:

private static func extract(inputFileAtUrl url: URL, withArch arch: String, toURL: URL) throws {try shellOut(to: "lipo", arguments: ["-thin",arch,url.path,"-output","lib.\(arch)"], at: toURL.path)
}

2、将提取出的文件切为最小组成成分,并依次处理:

try shellOut(to: "ar", arguments: ["x", extractionUrl.appendingPathComponent("lib.arm64").path])
if let emulator = FileManager.default.enumerator(atPath: extractionUrl.path) {for file in emulator {if let fileString = file as? String {if fileString.hasSuffix(".o") {Transmogrifier.processBinary(atPath: extractionUrl.appendingPathComponent(fileString).path, minos: minos, sdk: sdk)}}}
}

3、更新Header中数据大小:

var header: mach_header_64 = headerData.asStruct()
header.sizeofcmds = UInt32(editedCommandsData.count)

4、替换LC_VERSION_MIN_IPHONEOS,根据cmdsize变化更新其他load command:

static func updatePreiOS12ObjectFile(lc: Data, minos: UInt32, sdk: UInt32) -> Data {let offset = UInt32(abs(MemoryLayout<build_version_command>.stride - MemoryLayout<version_min_command>.stride))let cmd = Int32(bitPattern: lc.loadCommand)switch  cmd {case LC_SEGMENT_64:return updateSegment64(lc, offset)case LC_VERSION_MIN_IPHONEOS:return createVersionMin(lc, offset, minos: minos, sdk: sdk)case LC_DATA_IN_CODE, LC_LINKER_OPTIMIZATION_HINT:return updateDataInCode(lc, offset)case LC_SYMTAB:return updateSymTab(lc, offset)case LC_BUILD_VERSION:return updateVersionMin(lc, offset, minos: minos, sdk: sdk)default:return lc}
}

5、将处理后的切片合并组装:

try shellOut(to: "ar", arguments: ["cr", "lib.arm64", "*.o"])

04

踩坑&进阶

arm64-to-sim在计算LC_BUILD_VERSION大小时没有考虑build_tool_version:

Load command 11cmd LC_BUILD_VERSIONcmdsize 32platform IOSSIMULATORminos 15.5sdk 15.5ntools 1tool LDversion 764.0
Load command 34cmd LC_BUILD_VERSIONcmdsize 24platform IOSSIMULATORminos 13.0sdk 13.0ntools 0

参照MachOView源码:

struct build_tool_version {uint32_t tool;uint32_t version;
};struct build_version_command {uint32_t cmd;       // LC_BUILD_VERSIONuint32_t cmdsize;   // sizeof(build_version_command) + (ntools * sizeof(build_tool_version)uint32_t platform;  // MachoPlatformuint32_t minos;     // X.Y.Z is encoded in nibbles xxxx.yy.zzuint32_t sdk;       // X.Y.Z is encoded in nibbles xxxx.yy.zzuint32_t ntools;    // number build_tool_version entries
};

build_version_command的cmdsize 需要加上build_tool_version 的大小,不然会读取失败。

有些库中包含bitcode文件,bitcode文件与Mach-O文件结构并不相同,上述的处理过程并不能完成架构转换。

llvm提供了llvm-dis、llvm-as工具,llvm-dis可以将bitcode文件转换为文本格式的 .ll文件,llvm-as工具可以将 .ll文件转换为bitcode文件。

打开一个转换好的 .ll 文件,我们可以看到target triple对应的就是架构信息:

0af03a955810876670ab703731ab53e2.png

参照Xcode Build Log:

-Xlinker -reproducible -target arm64-apple-ios9.0-simulator -isysroot

此处target triple改为arm64-apple-ios8.0.0-simulator即可。

由于bitcode是llvm编译过程的中间产物,不同版本的llvm所生成的bitcode格式并不兼容,需要采用和Xcodecommand line tool所使用的llvm相近的版本。

05

结尾

如果你顺利地完成了以上所有步骤,将项目中的链接库全部转换完成,那么你就可以直接在arm64架构的模拟器上运行你们的项目了。

参考文档:

1、https://bogo.wtf/arm64-to-sim.html

2、https://github.com/luosheng/arm64-to-sim

d472d44fee03f30a6461e5f72da8a172.png

相关文章:

真机 ARM64 架构转模拟器 ARM64 架构

本文字数&#xff1a;2051字 预计阅读时间&#xff1a;15分钟 01 需要转换架构的原因 老版 Mac 使用 Intel 芯片&#xff0c;是x86_64架构&#xff0c;相应地在老版 Mac 上运行的模拟器使用的也就是 x86_64架构。 由于模拟器的 x86_64 架构与真机的 arm64、armv7 等架构不冲突&…...

敏捷教练CSM认证考了有没有用,谁说了算?

敏捷教练CSM证书是近年来备受关注的一项证书&#xff0c;它被认为可以提升敏捷开发团队的管理能力和项目执行效率。然而&#xff0c;对于这个证书的价值和含金量&#xff0c;人们的观点却不尽相同。那么&#xff0c;CSM证书到底有没有用&#xff0c;谁来说了算呢&#xff1f; 首…...

Docker-Container

Docker ①什么是容器②为什么需要容器③容器的生命周期容器 OOM容器异常退出容器暂停 ④容器命令清单总览docker createdocker rundocker psdocker logsdocker attachdocker execdocker startdocker stopdocker restartdocker killdocker topdocker statsdocker container insp…...

下载安装anaconda和pytorch的详细方法,以及遇到的问题和解决办法

下载安装Anaconda 首先需要下载Anaconda&#xff0c;可以到官网Anaconda官网或者这里提供一个镜像网站去下载anaconda镜像网站 安装步骤可参考该文章&#xff1a;Anaconda安装步骤&#xff0c;本篇不再赘述 注意环境变量的配置&#xff0c;安装好Anaconda之后一定要在环境变量…...

2020年天津市二级分类土地利用数据(矢量)

天津市&#xff0c;位于华北平原海河五大支流汇流处&#xff0c;东临渤海&#xff0c;北依燕山。地势以平原和洼地为主&#xff0c;北部有低山丘陵&#xff0c;海拔由北向南逐渐下降&#xff0c;地貌总轮廓为西北高而东南低。天津有山地、丘陵和平原三种地形&#xff0c;平原约…...

设计模式——结构型——外观模式Facade

处理器类 public class Cpu {public void start() {System.out.println("处理器启动了...");} } 内存类 public class Memory {public void start() {System.out.println("内存启动了...");} } 硬盘类 public class Disk {public void start() {Syste…...

OpenGL的MVP矩阵理解

OpenGL的MVP矩阵理解 右手坐标系 右手坐标系与左手坐标系都是三维笛卡尔坐标系&#xff0c;他们唯一的不同在于z轴的方向&#xff0c;如下图&#xff0c;左边是左手坐标系&#xff0c;右边是右手坐标系 OpenGL中一般用的是右手坐标系 1.模型坐标系&#xff08;Local Space&…...

前端超分辨率技术应用:图像质量提升与场景实践探索-设计篇

超分辨率&#xff01; 引言 在数字化时代&#xff0c;图像质量对于用户体验的重要性不言而喻。随着显示技术的飞速发展&#xff0c;尤其是移动终端视网膜屏幕的广泛应用&#xff0c;用户对高分辨率、高质量图像的需求日益增长。然而&#xff0c;受限于网络流量、存储空间和图像…...

C++11入门手册第一节,学完直接上手Qt(共两节)

入门 hello.cpp #include <iostream>int main() { std::cout << "Hello Quick Reference\n"<<endl; return 0;} 编译运行 $ g hello.cpp -o hello$ ./hello​Hello Quick Reference 变量 int number 5; // 整数float f 0.95; //…...

Docker部署MinIO对象存储服务

1. 拉取MinIO镜像 # 下载镜像 docker pull minio/minio#查看镜像 docker images2. 创建目录 # 文件存储目录 mkdir -p /opt/minio/data# 配置文件 mkdir -p /opt/minio/config# 日志文件 mkdir -p /opt/minio/logs3. 创建Minio容器并运行 docker run \ -p 9000:9000 \ -p 90…...

基于Echarts的超市销售可视化分析系统(数据+程序+论文)

本论文旨在研究Python技术和ECharts可视化技术在超市销售数据分析系统中的应用。本系统通过对超市销售数据进行分析和可视化展示&#xff0c;帮助决策层更好地了解销售情况和趋势&#xff0c;进而做出更有针对性的决策。本系统主要包括数据处理、数据可视化和系统测试三个模块。…...

使用ai智能写作场景之gpt整理资料,如何ai智能写作整理资料

Ai智能写作助手&#xff1a;Ai智能整理资料小助手 Ai智能整理资料小助手可试用3天&#xff01; 通俗的解释一下怎么用ChatGPT来进行资料整理&#xff1a; 搜寻并获取指定数量的特定领域文章&#xff1a; 想像你在和我说话一样&#xff0c;告诉我你想要多少篇关于某个话题的文…...

C/C++ 内存管理

1、C/C内存分布 首先我们来了解在一个程序中&#xff0c;代码主要存储在哪些地方&#xff1b; 1.栈&#xff1a;又叫堆栈&#xff0c;其中一般存储非静态局部变量、函数参数、返回值等&#xff0c;栈的增长是向下的。 2.内存映射段&#xff1a;是高效的 I/O 映射方式&#xff0…...

android pdf框架-10,相册浏览

MupdfViewer 这是最后apk,源码在前面的文章已经贴过了本站下载地址,只是不是最新的.可能不少是旧的内容. subsampling-scale-image-view这是一个大图片的分块加载的实现.比较不错的.滑动方面我觉得使用flinger的效果比它要流畅,惯性要好. 也有人把这个作成pdf渲染器.但翻页就…...

基于SSM的高校普法系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的高校普法系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring Spri…...

数据结构刷题篇 之 【力扣二叉树基础OJ】详细讲解(含每道题链接及递归图解)

有没有一起拼用银行卡的&#xff0c;取钱的时候我用&#xff0c;存钱的时候你用 1、相同的树 难度等级&#xff1a;⭐ 直达链接&#xff1a;相同的树 2、单值二叉树 难度等级&#xff1a;⭐ 直达链接&#xff1a;单值二叉树 3、对称二叉树 难度等级&#xff1a;⭐⭐ 直达…...

Jackson 2.x 系列【6】注解大全篇二

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Jackson 版本 2.17.0 源码地址&#xff1a;https://gitee.com/pearl-organization/study-jaskson-demo 文章目录 注解大全2.11 JsonValue2.12 JsonKey2.13 JsonAnySetter2.14 JsonAnyGetter2.15 …...

在低成本loT mcu上实现深度神经网络端到端自动部署-深度神经网络、物联网、边缘计算、DNN加速——文末完整资料

目录 前言 DNN 量化神经网络 并行超低功耗计算范式 面向内存的部署 结果 原文与源码下载链接 REFERENCES 前言 在物联网极端边缘的终端节点上部署深度神经网络( Deep Neural Networks&#xff0c;DNNs )是支持普适深度学习增强应用的关键手段。基于低成本MCU的终端节点…...

【linux】基础IO |文件操作符

需要掌握&#xff1a;操作文件&#xff0c;本质&#xff1a;进程操作文件。进程和文件的关系 向文件中写入&#xff0c;本质上向硬件中写入->用户没有权利直接写入->操作系统是硬件的管理者&#xff0c;我们可以通过操作系统往硬件写入->操作系统必须提供系统调用&…...

探索 2024 年 Web 开发最佳前端框架

前端框架通过简化和结构化的网站开发过程改变了 Web 开发人员设计和实现用户界面的方法。随着 Web 应用程序变得越来越复杂&#xff0c;交互和动画功能越来越多&#xff0c;这是开发前端框架的初衷之一。 在网络的早期&#xff0c;网页相当简单。它们主要以静态 HTML 为特色&a…...

解决: MAC ERROR [internal] load metadata for docker.io/library/openjdk:17

错误信息&#xff1a; ERROR [internal] load metadata for docker.io/library/openjdk:17 ERROR: failed to solve: openjdk:17: error getting credentials - err: exit status 1, out: 解决方法&#xff1a; running this command rm ~/.docker/config.json before …...

View事件分发

MotionEvent 1.简介 MotionEvent 是Android系统中一个非常重要的类&#xff0c;它代表了屏幕上发生的触摸事件。当用户在屏幕上触摸、滑动或者长按时&#xff0c;都会生成一个MotionEvent对象&#xff0c;这个对象包含了触摸动作的各种信息。 2.事件类型 ACTION_DOWN&#x…...

监听页面的使用时间

如果是比较新的vue架构&#xff08;推荐&#xff0c;参考若依&#xff09; 监听create&#xff08;&#xff09;和destory&#xff08;&#xff09;两个函数&#xff0c;写通用的js调用函数&#xff0c;在路由守卫的时候使用&#xff0c;就可以获取到每个页面停留时间 如果是比…...

【 yolo红外微小无人机-直升机-飞机-飞鸟目标检测】

yolo无人机-直升机-飞机-飞鸟目标检测 1. 小型旋翼无人机目标检测2. yolo红外微小无人机-直升机-飞机-飞鸟目标检测3. yolo细分类型飞机-鸟类-无人机检测4. yolo红外大尺度无人机检测5. 小型固定翼无人机检测6. 大型固定翼无人机检测7. yolo航空俯视场景下机场飞机检测 1. 小型…...

Redis与数据库的一致性

Redis与数据库的数据一致性 在使用Redis作为应用缓存来提高数据的读性能时&#xff0c;经常会遇到Redis与数据库的数据一致性问题。简单来说&#xff0c;就是同一份数据同时存在于Redis和数据库&#xff0c;如何在数据更新的时候&#xff0c;保证两边数据的一致性。首先&#…...

使用maxwell实时同步mysql数据到kafka

一、软件环境&#xff1a; 操作系统&#xff1a;CentOS release 6.5 (Final) java版本: jdk1.8 zookeeper版本: zookeeper-3.4.11 kafka 版本: kafka_2.11-1.1.0.tgz maxwell版本&#xff1a;maxwell-1.16.0.tar.gz 注意 &#xff1a; 关闭所有机器的防火墙&#xff0c;同时注意…...

知识图谱与大数据:区别、联系与应用

目录 前言1 知识图谱1.1 定义1.2 特点1.3 应用 2 大数据2.1 定义2.2 应用 3. 区别与联系3.1 区别3.2 联系 结语 前言 在当今信息爆炸的时代&#xff0c;数据成为了我们生活和工作中不可或缺的资源。知识图谱和大数据是两个关键概念&#xff0c;它们在人工智能、数据科学和信息…...

Nagios工具

一 nagios 相关概念 Nagios 是一款开源的免费网络监视工具&#xff0c;能有效监控 Windows、Linux 和 Unix 的主机状态&#xff0c;交换机路由器等网络设置&#xff0c;打印机等。在系统或服务状态异常时发出邮件或短信报警第 一时间通知网站运维人员&#xff0c;在状态恢复后…...

微信小程序全局数据共享

文章目录 安装MobX相关的包根目录创建store文件夹&#xff0c;添加store.js文件绑定到页面中绑定到组件 mobx-miniprogram和mobx-miniprogram-bindings实现全局数据共享 mobx-miniprogram用来创建Store实例对象 mobx-miniprogram-bindings用来把Store中的共享数据或方法&…...

算法训练营第24天|回溯算法理论基础 LeetCode 77.组合

终于把二叉树做完了&#xff01;开始新的篇章&#xff0c;回溯&#xff01; 回溯算法理论基础 回溯算法题目分类&#xff1a; 1.组合 2.分割 3.子集 4.排列 5.棋盘问题 什么是回溯&#xff1f; 回溯叫做回溯搜索法&#xff0c;是一种搜索方式。回溯是递归的副产品&…...

二级建造师考试试题/整站优化的公司

refs: http://blog.chinaunix.net/uid-26404201-id-3334234.html 先看下面的Makefile&#xff1a; #exampleB : $(A)A laterall: echo $(B) 执行make命令&#xff0c;我们发现什么都没输出,我们将第3行的:换成。#exampleB $(A)A laterall: echo $(B) 执行make&#x…...

一个公司完整的组织架构/宁波seo网络推广

#python中的堆排序peapq模块 heapq模块实现了python中的堆排序&#xff0c;并提供了有关方法。让用Python实现排序算法有了简单快捷的方式。 heapq的官方文档和源码&#xff1a;8.4.heapq-Heap queue algorithm 下面通过举例的方式说明heapq的应用方法 ##实现堆排序 Python#! /…...

wordpress全站启用ssl/深圳营销策划公司十强

2019独角兽企业重金招聘Python工程师标准>>> KafkaOffsetMonitor 博客分类&#xff1a; MQ 1.概述 前面给大家介绍了Kafka的背景以及一些应用场景&#xff0c;并附带上演示了Kafka的简单示例。然后&#xff0c;在开发的过程当中&#xff0c;我们会发现一些问题&…...

网站建设方案书怎么写样版/seo怎样

1、HDUOJ 4675 题意&#xff1a;给定数n, m, k和数列{an}&#xff08;1 < ai < m&#xff09;&#xff0c;求改变数列{an}中的k个数的值&#xff08;不改变位置&#xff0c;且新值范围为1 < ai < m&#xff0c;ai ! ai&#xff09;&#xff0c;使得数列的最大公约数…...

网站制作的流程包括哪些/互联网营销推广渠道

开发环境(蓝色粗体字为特别注意内容) 1、软件环境&#xff1a; Win7 Ultimate sp1、jdk7u45 2、参考文献&#xff1a;https://www.cnblogs.com/jack1208-rose0203/p/5713210.html private static final byte[] ARRAY_CIRCLE { 0x3c, 0x7e, 0xff, 0xff, 0xff, 0xff…...

设计制作个人网站/国内网络销售平台有哪些

学习内容简单查询汇总分析复杂查询多表查询如何提高SQL查询效率简单查询创建学校数据库的表查找学生查询姓‘猴’的学生名单查询姓名中最后一个字是‘猴’的学生名单查询姓名中带‘猴’的学生名单select * from student where 姓名 like 猴%;select * from student where 姓名 …...