为什么我在 Apple Silicon 上编译的本机应用程序有时构建为 arm64,有时构建为 x86_64?

2024-01-31

我有一个基本的 C 程序:

#include <stdio.h>

int main() {
  printf("Hello, world!\n");
}

当我直接使用它编译时cc在 Apple Silicon 设备上,它会产生arm64可执行文件:

% cc hello.c -o hello

% file hello
hello: Mach-O 64-bit executable arm64

% ./hello
Hello, world!

但是,当我通过 CMake 或 Ninja 等构建系统构建它时,它会生成 x86_64 二进制文件:

% ./my-build-system

% file hello
hello: Mach-O 64-bit executable x86_64

我已经验证构建脚本运行的命令与我自己运行的命令相同。如果我复制并粘贴该命令并自己运行它,生成的可执行文件仍然是arm64。


当您的构建命令不包含要构建的架构的特定标志时,Apple 提供的编译器工具,例如cc,根据架构进行某种内省调用过程。这意味着如果您的构建系统尚未进行本机编译arm64,您可能会看到此行为,因为编译器会假设您要针对 x86_64 进行构建!

您可以通过使用来演示这一点arch工具来运行cc在 x86_64 模式下可执行:

% arch -x86_64 cc hello.c -o hello

% file hello
hello: Mach-O 64-bit executable x86_64

作为解决方法,您可以引入一个始终重置为本机体系结构的 shim 编译器。将此另存为force-arm64-cc并使其可执行:

#!/usr/bin/env bash

# Note we are using arm64e because `cc` does not have an arm64 binary!
exec arch -arm64e cc "$@"

然后您可以使用这个垫片代替cc:

% CC=$PWD/force-arm64-cc ./my-build-system

% file hello
hello: Mach-O 64-bit executable arm64

正确的长期解决方案是在编译时指定目标架构:

% arch -x86_64 cc -arch arm64 hello.c -o hello

% file hello
hello: Mach-O 64-bit executable arm64

但是,当前,当您rebuild二进制文件,这在编辑-编译-运行周期中很常见:

% ./hello
zsh: killed     ./hello

也可以看看:

  • 为什么使用 x86_64 构建系统构建的本机 arm64 应用程序无法进行代码签名,除非我删除以前的可执行文件? https://stackoverflow.com/q/64830671/155423
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我在 Apple Silicon 上编译的本机应用程序有时构建为 arm64,有时构建为 x86_64? 的相关文章

  • 实现 `memcpy()`:需要 `unsigned char *`,还是只需要 `char *`?

    我正在实施一个版本memcpy 能够与它一起使用volatile 使用安全吗char 或者我需要unsigned char volatile void memcpy v volatile void dest const volatile v
  • LINQ TO ENTITY 无法与枚举类型进行比较

    下面是枚举叶子 public enum Leaves Annual 0 Medical 1 Hospitalization 2 Unpaid 3 下面是linq查询 public ActionResult ApproveLeave int
  • Microsoft Graph API 授权错误:无效受众

    我知道这是一个很长的问题 但如果有人能与我分享他们的想法或经验 我真的很感激 因为我已经解决这个问题几天了 现在正在尝试很多事情 我有一个 ASP Net Core 3 1 Web API 应用程序和一个 ASP NET Core 3 1
  • 在运行时配置 ASP.NET 会话状态

    我们有一个使用 SQL Server 会话状态的 ASP NET 网站 状态配置在Web config like
  • 如何将 list 对象附加到另一个对象

    在 C 中 我有两个list
  • 这个对象的内存会是什么样子?

    我想知道这个类 它的对象 的内存布局是什么样的 class MyClass string myString int myInt public MyClass string str int i myString str myInt i MyC
  • 将 size_t 变量添加到指针

    我想向指针添加 size t 类型 有些像这样 void function size t sizeA size t sizeB void pointer pointer malloc sizeA pointer pointer sizeB
  • 使用 .NET Core Razor Pages 将文件下载到浏览器

    使用 ASP NET Razor Pages 我尝试将文件下载到浏览器 在页面 html 中 使用这样的链接效果很好 href DownloadableFiles testB csv download newname gt Download
  • 委托:方法名称预期错误

    我正在尝试让以下简单的委托示例正常工作 根据我从中取出的一本书 应该没问题 但我得到了Method name expected error namespace TestConsoleApp class Program private del
  • 更改子进程中的 iostream

    现在 我正在开发一个项目 其中我需要启动一个子进程来使用 C 在 Linux 中执行一个新程序 并且我需要重定向标准输入和输出 就像在 C 中一样 它们是cin and cout 到一个文件 这意味着在子进程中 标准输入和输出都是文件 子进
  • 拦截C# HttpClient GetAsync

    我有一个 Web 项目 C MVC5 但没有 WebAPI 和一个简单的 HTTP REST 客户端 该客户端调用外部 REST 服务并获取 accessToken 等 我想检查所有 Get PostAsync 调用对 statusCode
  • ASP.NET MVC - 路由 - 具有文件扩展名的操作

    有没有办法实现调用URLhttp mywebsite myarea mycontroller myaction xml这基本上是 假 请求文件 但结果将是一个为动态创建的文件提供服务的操作操作 我试过这个 context MapRoute
  • C# 中的自定义按钮:如何删除悬停背景?

    我正在尝试使用 Visual Studio 2005 对我的表单 其 FormBorderStyle none 执行自定义按钮 我在链接到该按钮的 ImageList 中有我的 3 种状态按钮图像 this btnClose AutoSiz
  • 初学者友好的方法来获取所有文件和目录的列表

    使用 NET 3 0 我得到了下面的方法 它可以正确返回指定目录的所有文件和目录 以及子目录 的集合 如果可能的话 我想将其简化为仅使用我非常熟悉的结构 具体来说 有以下几点我不太清楚 1 IEnumerable
  • OpenMP 动态调度与引导调度

    我正在研究 OpenMP 的调度 特别是不同的类型 我了解每种类型的一般行为 但澄清一下何时进行选择会很有帮助dynamic and guided调度 英特尔的文档 https software intel com en us articl
  • C++ 头文件包含

    我正在开发一个项目 每个头文件都有一个预处理器包含防护 我的包含是这样的 文件 gt 包含 main cpp gt header h 字符 h header h gt 矢量 iostream DataFiles h Character h
  • 虚拟键盘(类似 Swype 键盘)Windows 窗体应用程序 C#

    我正在尝试使用 c 在 Windows 窗体中创建一个类似 swype 的键盘 我有两个问题 A 我无法重现手指滑动动作 b 我无法识别不同按键下的字母 对于第一个问题 我使用了 Graphics 类和 Pen 类 并像这样使用它 bool
  • 有C语言的解释器吗? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话
  • 在.Net中使用ObjectCache缓存对象并设置过期时间

    我陷入了一个场景 我的代码如下 更新 它不是关于如何使用数据缓存 我已经在使用它及其工作 它是关于扩展它 以便该方法在到期时间和从外部源获取新数据之间不会进行调用 object string this GetDataFromCache ca
  • 我该怎么做才能完全关闭与mcu的tcpClient连接?

    我现在正在研究与 ESP32 中运行的 tcp 服务器的 tcp 套接字连接 通信工作正常 但我无法关闭连接 在搜索关闭 重置 tcpClient 上的解决方案后 似乎关闭 tcpClient 的正确方法应该是 tcpClient GetS

随机推荐