如果你正在维护一个编译型开源项目,并且已经发布了 amd64 版本,那么随着 ARM 云服务器、Apple Silicon 和各类开发板的普及,“要不要支持 arm64”这个问题早晚会摆到面前。最近围绕 “omarchy 添加 arm64 支持” 这类架构适配任务的讨论越来越多,本质上就是一次典型的跨架构工程改造。本文结合 Codex 命令行工具,以 omarchy 项目为示例,完整讲解从环境准备、构建脚本改造、CI 多架构发布到常见问题排查的全过程。
无论你是刚开始接触跨架构编译的新手,还是已经有 x86 项目需要扩展 ARM 发布的开发者,这篇文章都可以作为一份可落地的操作笔记。文中会给出完整的命令、代码和排错思路,你可以直接照着跑一遍,再把方法迁移到自己的项目里。
1. 背景:Codex、omarchy 与 arm64
1.1 Codex 是什么
Codex 是 OpenAI 推出的 AI 编码助手,近期更受关注的是它的命令行形态 Codex CLI。它可以在终端中读取仓库代码、定位问题、生成修改建议,甚至直接修改文件并执行命令。你可以把它理解成一个“能看懂整个工程的编程搭档”。
这里需要区分两个概念:早期 OpenAI 做过名为 Codex 的代码模型,主要用于代码补全;而现在大家常说的 Codex,更多是指可以在终端安装使用的 Codex CLI 工具。本文提到的 Codex 均指后者。
Codex CLI 的典型使用方式是在仓库根目录启动一个交互会话,然后输入自然语言指令。例如:
codex > 帮我看看当前仓库里哪些文件与 CPU 架构相关它会扫描代码、给出结论,并询问是否执行修改。这种“先分析、后动手”的工作方式,非常适合架构适配这类跨文件、跨环节的改造任务。
1.2 omarchy 是什么
omarchy 是一个开源项目,从常见资料来看,它与 Linux 环境的定制化体验有关,可能是桌面主题、工具集或系统配置方案。由于项目的安装方式、构建方案会随版本持续变化,本文不把重点放在 omarchy 的具体功能上,而是把它当作一个需要适配 arm64 的示例项目。
换句话说,本文展示的“用 Codex 分析工程、添加 arm64 构建目标、验证产物”这套流程,适用于各类需要同时发布 amd64 和 arm64 版本的项目,不管底层用的是 C/C++、Go、Rust 还是其他编译型语言。
1.3 为什么要支持 arm64
arm64 全称是 AArch64,是 64 位 ARM 指令集架构。过去它主要出现在手机、路由器等嵌入式设备里,但近几年它的应用范围迅速扩大:
- Apple Silicon 的 Mac 全面转向 arm64;
- AWS Graviton、阿里云倚天等 ARM 架构云服务器逐渐普及;
- 树莓派、各类 RK 开发板、边缘网关设备都在跑 Linux;
- 国产化芯片平台大多基于 ARM 或类 ARM 架构。
对一个发布型项目来说,如果只提供 amd64 产物,就意味着这些设备上的用户无法直接安装使用。所以“支持 arm64”不是锦上添花,而是扩大用户覆盖面的必要动作。
1.4 amd64 与 arm64 的核心区别
在动手改造之前,先理清两个架构的本质区别:
| 对比项 | amd64 / x86_64 | arm64 / AArch64 |
|---|---|---|
| 指令集类型 | CISC,指令复杂、长度不固定 | RISC,指令精简、长度固定 |
| 典型设备 | 传统 PC、服务器 | Apple Silicon Mac、ARM 云主机、开发板 |
| 功耗表现 | 相对较高 | 相对较低 |
| 软件生态 | 最成熟,几乎全覆盖 | 快速增长,仍有少数软件缺包 |
| 构建方式 | 在 x86 机器直接构建 | 需要交叉编译或使用 ARM 构建机 |
| 常见判读结果 | uname -m输出x86_64 | uname -m输出aarch64 |
同一份源代码,在不同架构上编译出的机器码完全不同。所以架构适配的关键,不是改业务代码,而是保证构建系统、依赖库、CI 发布链路都能为不同架构产出正确产物。
2. 准备工作:安装 Codex、确认架构、搭建编译环境
2.1 安装 Codex CLI
Codex CLI 的安装方式以官方 README 为准,常见途径是 npm 全局安装。在终端执行:
npm install -g @openai/codex安装完成后,验证一下:
codex --version如果能看到版本号,说明安装成功。
如果你的机器没有安装 Node.js,或者更习惯用预编译二进制,可以直接从 Codex 的 GitHub Releases 页面下载对应平台的可执行文件,解压后放到PATH目录中。无论用哪种方式,最终目标是让codex命令可以在终端中直接调用。
2.2 配置 API Key 或完成登录
Codex 在工作时需要调用后端模型服务,因此需要配置访问凭据。环境变量方式如下:
export OPENAI_API_KEY=sk-your-key-here或者使用 Codex 自带的登录流程完成认证。如果你使用的是第三方 OpenAI 兼容服务,则需要在配置文件中修改 API endpoint 和模型名,并确保该服务支持你配置的模型。
需要注意,密钥属于敏感信息,不要写进仓库。本地开发时可以放在 shell 配置文件中,CI 环境则应该使用 GitHub Secrets 等机密管理能力。
2.3 确认当前系统架构
在 Linux/macOS 上执行:
uname -m- 输出
x86_64:当前是 amd64 架构; - 输出
aarch64:当前是 arm64 架构。
在 Windows PowerShell 中执行:
echo $env:PROCESSOR_ARCHITECTURE- 输出
AMD64:表示 x64; - 输出
ARM64:表示 arm64。
下载安装包时也容易踩这个坑,很多软件会区分“Windows amd64”和“Windows arm64”两个版本:amd64 是给 Intel/AMD x64 处理器用的,arm64 是给骁龙、苹果 M 系列等 ARM 处理器用的。选错版本会导致“安装后无法启动”或“运行不兼容”的报错。
2.4 准备交叉编译工具链
要给 omarchy 添加 arm64 支持,常见的做法是在 x86 机器上做“交叉编译”,也就是生成目标架构为 arm64 的二进制,然后拷贝到 ARM 设备或 ARM 云主机上运行。
不同技术栈的工具链不一样:
| 技术栈 | 关键工具/参数 |
|---|---|
| C/C++ | gcc-aarch64-linux-gnu、aarch64-linux-gnu-gcc |
| Go | 直接支持GOOS=linux GOARCH=arm64 |
| Rust | rustup target add aarch64-unknown-linux-gnu |
| Python | 需要编译扩展模块,或用pip安装 arm64 的 wheel 包 |
如果是 C/C++ 项目,在 Ubuntu/Debian 上可以安装:
sudo apt update sudo apt install gcc-aarch64-linux-gnu如果项目使用了 CGO 或外部 C 库,交叉编译时需要指定对应的交叉编译器路径。如果项目是纯 Go,且没有依赖 CGO,那么CGO_ENABLED=0会让交叉编译简单很多。
2.5 准备一个最小示例工程
为了让后续步骤可复现,这里准备一个模拟 omarchy 的最小 Go 工程。Go 的交叉编译非常直观,适合用来演示架构适配思路。
omarchy/ ├── main.go ├── Makefile ├── Dockerfile └── .github/ └── workflows/ └── release.ymlmain.go内容:
package main import ( "fmt" "runtime" ) func main() { fmt.Printf("omarchy running on %s/%s\n", runtime.GOOS, runtime.GOARCH) }这个程序本身没有业务逻辑,但它可以在运行时输出当前平台信息,方便我们验证编译出的 arm64 产物是否真的跑在 ARM 架构上。
3. 架构适配的核心思路
3.1 架构适配要改什么
很多开发者以为“支持 arm64”就是把代码放到 ARM 机器上重新编译一遍,实际上一个完整的架构适配往往涉及多个层面:
- 编译产物:需要产出 amd64 和 arm64 两类二进制;
- 构建脚本:Makefile、Shell 脚本中的架构变量不能写死;
- CI 流程:GitHub Actions、Jenkins 等流水线需要加入多架构构建任务;
- 容器镜像:Docker 镜像需要支持
linux/amd64和linux/arm64; - 运行时逻辑:代码里如果有 CPU 指令集判断、汇编代码、依赖库加载路径,也需要适配。
其中 2、3、4 是绝大多数项目最容易忽略的部分。改业务代码往往很快,真正的坑都在构建和发布链路里。
3.2 构建脚本中的架构硬编码
观察一个典型的 Makefile,可以很直观地看到问题。比如下面的写法,就把架构写死了:
BINARY=omarchy build: GOOS=linux GOARCH=amd64 go build -o bin/$(BINARY) .这个 Makefile 只能构建 amd64 版本。它的问题有两个:
GOARCH被写死为amd64;- 产物文件名没有区分架构,后续如果同时构建两个架构,文件会互相覆盖。
更合理的做法是让架构可以作为参数传入。例如:
BINARY=omarchy GOOS ?= linux GOARCH ?= amd64 build: GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o bin/$(BINARY)-$(GOOS)-$(GOARCH) .这样,我在 x86 机器上执行:
make build GOARCH=arm64就能生成bin/omarchy-linux-arm64,不需要改任何代码。
3.3 CI 与发布链路中的架构配置
构建脚本只是第一步,CI 流水线同样需要调整。很多项目在 GitHub Actions 中只会在ubuntu-latest上构建一次,然后直接发布。这样的流水线天然不具备多架构发布能力。
改造思路有两种:
- 使用矩阵构建(matrix),在多个任务里分别执行不同
GOARCH; - 使用 Docker buildx 一次构建多平台镜像。
矩阵构建的优势是每个任务彼此独立,一个问题架构不影响其他架构;buildx 的优势是一条命令搞定多平台镜像发布。实际项目中通常两者结合使用。
3.4 Codex 能帮我们做什么
传统做法是人工搜索代码里的x86_64、amd64、uname -m等关键字,逐个项目排查。而 Codex 可以一次性读取整个工程,定位所有架构相关逻辑,甚至直接给出修改方案。
Codex 适合做的三类事:
- 仓库扫描:找出构建脚本、CI 配置、源码中与架构相关的硬编码;
- 代码生成:为 Makefile、workflow、Dockerfile 生成多架构版本;
- 解释答疑:解释某个编译报错的架构原因,并给出修复建议。
但它并不能完全替代人工 review。尤其在 CI、发布这类影响面较大的环节,AI 生成的修改仍然需要人工确认。
4. 完整实战:使用 Codex 为 omarchy 添加 arm64 支持
4.1 分析现有工程
进入示例工程目录,先看一下整体结构:
cd omarchy ls -la cat Makefile cat .github/workflows/release.yml假设初始的 Makefile 是“只能构建 amd64”的版本:
BINARY=omarchy build: GOOS=linux GOARCH=amd64 go build -o bin/$(BINARY) .初始 CI 配置也只有一个构建任务:
name: release on: push: tags: - "v*" jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version: "1.22" - name: Build run: make build这个配置的问题很明显:产物只覆盖linux/amd64。
4.2 让 Codex 定位架构相关代码
在仓库根目录启动 Codex 交互会话:
codex然后在会话里输入:
请分析当前仓库中的 Makefile、CI 配置和源代码,找出所有与 CPU 架构相关的内容,特别是硬编码 amd64 / x86_64 的地方,然后整理成一份需要修改的文件清单。Codex 给出的结果一般会包含:
Makefile中GOARCH=amd64是硬编码,建议参数化;release.yml中没有矩阵构建,只构建了一种架构;- 源码
main.go没有架构相关逻辑,不需要修改。
有了这份清单,后续改动就有了明确范围。这里也体现了一个好处:AI 先做全量扫描,人工再针对性复核,比一上来就翻文件高效得多。
4.3 改造构建脚本
下面手动给出一个完整的参数化 Makefile,这也是 Codex 通常会建议的写法:
BINARY=omarchy VERSION=0.1.0 GO ?= go build: $(GO) build -o bin/$(BINARY) . build-all: GOOS=linux GOARCH=amd64 $(GO) build -o bin/$(BINARY)-linux-amd64 . GOOS=linux GOARCH=arm64 $(GO) build -o bin/$(BINARY)-linux-arm64 . GOOS=darwin GOARCH=arm64 $(GO) build -o bin/$(BINARY)-darwin-arm64 . GOOS=darwin GOARCH=amd64 $(GO) build -o bin/$(BINARY)-darwin-amd64 . GOOS=windows GOARCH=amd64 $(GO) build -o bin/$(BINARY)-windows-amd64.exe GOOS=windows GOARCH=arm64 $(GO) build -o bin/$(BINARY)-windows-arm64.exe这里有几个关键点:
- 产物文件名加入
GOOS和GOARCH,避免多架构产物互相覆盖; build-all目标一次性产出 Linux、macOS、Windows 的常见架构版本;- 如果某个项目依赖 CGO,需要额外设置
CGO_ENABLED=0,并在命令中指定交叉编译器。
执行构建:
make build-all然后检查产物:
ls -lh bin/ file bin/omarchy-linux-arm64file命令的预期输出类似:
bin/omarchy-linux-arm64: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, Go BuildID=xxx, stripped看到ARM aarch64,就说明这个二进制确实是 arm64 版本的。
4.4 更新 CI 多架构构建
接下来的改动进入 CI 环节。把 GitHub Actions 的构建任务改成矩阵模式:
name: release on: push: tags: - "v*" jobs: build: runs-on: ubuntu-latest strategy: matrix: goarch: [amd64, arm64] steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version: "1.22" - name: Build run: | GOOS=linux GOARCH=${{ matrix.goarch }} make build - name: Upload artifact uses: actions/upload-artifact@v4 with: name: omarchy-linux-${{ matrix.goarch }} path: bin/矩阵构建意味着goarch: [amd64, arm64]会生成两个并行任务,分别执行一次构建。这样做的好处是:
- 架构之间互不影响,一个失败不会阻塞另一个;
- 构建产物通过
upload-artifact分开保存,发布时可以选择合并; - 后续想增加
386、riscv64等架构,只需要在矩阵数组里加一项。
需要注意,如果你的项目依赖 CGO 或外部原生库,那么 CI 构建机还需要额外安装对应架构的交叉编译工具链,矩阵里也要增加goos等维度。
4.5 添加 Docker 多架构镜像
如果 omarchy 用 Docker 发布,镜像也需要支持多架构。Docker 官方方案是 buildx。先准备一个支持多阶段构建的 Dockerfile:
FROM golang:1.22 AS builder ARG TARGETARCH WORKDIR /src COPY . . RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build -o /out/omarchy . FROM alpine:3.20 COPY --from=builder /out/omarchy /usr/local/bin/omarchy ENTRYPOINT ["omarchy"]关键点在于ARG TARGETARCH。buildx 在构建多平台镜像时,会自动把目标架构写入TARGETARCH变量,因此我们不需要在 Dockerfile 里写死架构。
构建并推送多架构镜像:
docker buildx create --use docker buildx build \ --platform linux/amd64,linux/arm64 \ -t your-registry/omarchy:0.1.0 \ --push .执行完后,可以用docker buildx imagetools inspect查看镜像支持的平台:
docker buildx imagetools inspect your-registry/omarchy:0.1.0输出会列出linux/amd64和linux/arm64两个条目,说明镜像已经支持双架构。用户在 amd64 或 arm64 机器上执行docker pull时,Docker 会自动拉取对应架构的镜像层。
4.6 运行与验证
构建出 arm64 二进制后,需要验证它确实能运行。最简单的方式是把产物拷贝到一台 ARM 机器上执行:
./omarchy # 预期输出: # omarchy running on linux/arm64如果没有现成的 ARM 机器,在 x86 的 Linux 环境下可以用 qemu-user 来模拟运行:
sudo apt install qemu-user-static ./bin/omarchy-linux-arm64qemu 会为不匹配的 ELF 文件自动启动用户态模拟,从而在 amd64 机器上运行为 arm64 编译的程序。这个方式非常适合做冒烟测试,确认程序没有在架构层出现问题。
5. 常见问题与排查思路
5.1 Codex CLI 无法启动或找不到二进制
热词中经常出现这样一条报错:
Unable to locate the Codex CLI binary. Set Codex CLI path or ensure the executable exists on PATH.这个报错通常出现在桌面端应用尝试调用 Codex CLI 时,根本原因是系统找不到codex可执行文件。
排查步骤:
# 1. 检查 codex 是否存在 which codex # 2. 查看版本号,确认安装成功 codex --version # 3. 如果找不到,先安装或把二进制加入 PATH npm install -g @openai/codex如果codex已经安装,但桌面端仍然报错,可以在桌面端设置里手动指定 codex 二进制的绝对路径。产生这个问题的常见场景是:使用 nvm 管理 Node.js,全局 npm 包的安装路径不在系统默认PATH中。
5.2 模型不支持或模型名称错误
热词中还有一条类似下面的报错:
The 'gpt-5.6-sol' model is not supported when using Codex with a...这类报错说明 Codex 配置中的 model 字段写了一个当前环境不支持或服务商不允许的模型名。解决方案是打开 Codex 配置文件,把 model 改成官方支持或你的 API 服务商允许的模型。
如果你接入的是第三方 OpenAI 兼容服务,也要特别注意模型名和接口能力是否一致。不同服务商开放的模型列表并不相同,Codex 本身只负责把请求发出去,模型是否可用取决于后端服务。
5.3 交叉编译时报错:找不到交叉编译器
在编译 C/C++ 或依赖 CGO 的 Go 项目时,交叉编译容易遇到类似报错:
gcc: error: unrecognized command-line option '-marm'或者:
exec: "aarch64-linux-gnu-gcc": executable file not found in $PATH原因通常是系统没有安装 arm64 的交叉编译工具链。Ubuntu/Debian 安装:
sudo apt install gcc-aarch64-linux-gnuGo 项目如果不需要 CGO,建议直接禁用:
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build ...禁用 CGO 后,Go 会使用纯静态编译,避免依赖目标机器上的 glibc 版本,也省去了交叉编译器的配置。
5.4 在 Windows 上下载了错误的架构版本
Omarchy 或其他开源工具在提供安装包时,通常会区分:
omarchy-windows-amd64.zip:给 x64 处理器的 Windows;omarchy-windows-arm64.zip:给 ARM64 处理器的 Windows。
如果你的设备是 Intel/AMD x64,却下载了 arm64 版本,运行时会直接报“程序无法运行”或“系统不兼容”。反之亦然。判断当前 Windows 架构:
echo $env:PROCESSOR_ARCHITECTURE下载前先确认安装包名称里的架构标识,是最简单也最有效的预防手段。
5.5 常见问题汇总
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| codex 命令不存在 | Codex CLI 未安装或未加入 PATH | 执行npm install -g @openai/codex,确认 PATH |
| 桌面端提示找不到 Codex CLI | 桌面端无法定位 codex 路径 | 在设置中手动指定 codex 二进制绝对路径 |
| 模型不支持报错 | 配置了错误或不存在的 model 名 | 修改配置文件中的 model 字段 |
| 交叉编译找不到交叉编译器 | 未安装 arm64 工具链 | 安装gcc-aarch64-linux-gnu |
| 生成的产物无法在 arm64 设备运行 | 实际构建成了 amd64 | 用file命令确认 ELF 架构 |
| 下载安装包后无法启动 | 架构版本选错 | 确认设备架构并重新下载 |
6. 最佳实践与工程建议
6.1 构建参数参数化,不要写死架构
架构适配的第一条规范就是:不要在构建脚本里写死arch、GOARCH、--platform等参数。把所有架构相关变量做成可传入的参数,默认值可以是当前构建机架构,但必须允许覆盖。这样无论是本地构建、CI 矩阵构建还是 Docker 多架构构建,都能复用同一套脚本。
6.2 CI 矩阵要多架构、多平台覆盖
如果项目发布 Linux 二进制,CI 至少覆盖amd64和arm64两个架构。如果项目还需要 macOS 和 Windows 版本,建议把GOOS也加入矩阵。矩阵模式能让每个组合独立运行,日志更清晰,排错也更方便。
但要注意,矩阵并不是越多越好。每增加一个组合,就多一份 CI 时间成本。合理的做法是:常见架构全量覆盖,小众架构按需增加。
6.3 发布产物命名与校验规范
多架构发布最容易出的问题就是产物同名覆盖。建议统一命名规则:
omarchy-${VERSION}-${GOOS}-${GOARCH}[.exe]示例:
omarchy-0.1.0-linux-amd64 omarchy-0.1.0-linux-arm64 omarchy-0.1.0-darwin-arm64 omarchy-0.1.0-windows-amd64.exe另外,在发布前用file、sha256sum校验产物,确保二进制架构正确、校验和已生成。发布说明里要明确列出每个文件的适用平台,减少用户选错架构的概率。
6.4 使用 Codex 辅助开发的注意事项
Codex 能显著提升架构适配效率,但要把它当成“结对编程搭档”,而不是“自动修改机器”。以下几点值得注意:
- 先让 Codex 产出问题清单,人工确认后再说“开始修改”;
- 涉及构建、CI、发布脚本的改动,必须逐行 review;
- AI 生成的命令,尤其是有
--push、rm、强制覆盖等操作的命令,执行前要确认影响范围; - 不要在 AI 会话中暴露 API Key、Token、私钥等敏感信息;
- 每次改动后都要跑一次完整构建,验证 AI 修改没有引入隐藏问题。
6.5 生产环境与安全边界
如果你是在公司项目里做 arm64 适配,还需要注意:
- 交叉编译产物要在目标架构的真实设备或云主机上做集成测试,不能只依赖 qemu 模拟;
- 涉及 CI 的 Token、镜像仓库的凭据,必须使用密钥管理系统,禁止明文写入 workflow;
- 发布前保留上一版 amd64 产物,方便快速回滚;
- 如果项目涉及数据库、系统级命令,要评估 arm64 平台上的兼容性差异。
7. 总结与下一步
给 omarchy 这样的项目添加 arm64 支持,本质是一次典型的跨架构工程改造。本文完整走了一遍流程:先理解 amd64 与 arm64 的差异,安装并配置 Codex CLI,分析现有构建脚本,参数化 Makefile,改造 CI 矩阵,最后用 Docker buildx 构建多架构镜像,并通过file和 qemu 验证产物。
这套方法不局限于 Go 项目。C/C++、Rust、Python 项目在架构适配时的核心思路是一致的:找到写死架构的位置,把架构参数化,让构建系统能同时产出多平台产物,最后在 CI 和镜像发布环节完成覆盖。
如果你正在做类似改造,建议按这个顺序推进:
- 先扫描仓库,列出所有架构硬编码点;
- 用 Codex 辅助生成初版修改方案;
- 在本地完成单架构交叉编译,确认产物可运行;
- 再改 CI 矩阵和镜像构建;
- 最后用真实 arm64 设备做回归验证。
架构适配的坑大多不在代码里,而在构建和发布链路中。把构建参数化、CI 矩阵化、镜像多平台化这三件事做好,你的项目距离“全架构发布”就不远了。