M1/M2 Mac Python多架构兼容实战:arm64与x86_64包管理三把硬刀子
2026/6/8 9:55:14 网站建设 项目流程

1. 项目概述:当Python撞上M1/M2芯片,为什么你的pip install总在深夜报错?

你有没有过这样的经历:凌晨两点,一个关键的AI模型训练脚本卡在pip install azure-eventhub这行不动了,终端里刷出一长串红色错误——不是缺编译器,不是权限问题,而是ImportError: dlopen(.../uamqp.cpython-311-darwin.so, 0x0002): tried: '.../uamqp.cpython-311-darwin.so' (mach-o file, but is an incompatible architecture (have 'arm64', need 'x86_64'))。你盯着这行字看了三分钟,心里默念:“我用的是M2 MacBook Pro,它明明是arm64,为什么系统非要找x86_64的二进制?”——这不是你的错,也不是库作者的疏忽,这是整个Python生态在CPU架构大迁徙中必然经历的阵痛。本文要讲的,就是这场“多CPU架构适配战”的底层逻辑、真实战场和可落地的三把硬刀子。核心关键词早已刻进每个M系列Mac用户的日常:M1/M2、arm64、x86_64、wheel包、pip、conda、Rosetta、Docker多平台构建。它不面向理论派,只服务实战派——如果你正在用MacBook Pro跑数据科学、机器学习或任何需要高性能Python扩展的项目,那么你不是在“学习”这个问题,而是在“每天面对”它。这篇文章就是为你写的作战手册,里面没有空泛的“未来可期”,只有今天就能复制粘贴、明天就能上线运行的解决方案。

2. 核心设计思路拆解:为什么“一次编写,到处运行”在M系列Mac上成了伪命题?

2.1 Python的“纯解释”幻觉与C扩展的物理现实

Python官方文档里那句“Write once, run anywhere”听起来很美,但它有个极其重要的隐藏前提:这个“anywhere”仅指Python解释器本身及其纯Python代码。一旦你引入pandas、NumPy、scikit-learn、PyTorch这些工业级库,你就已经一脚踏进了“混合执行”的世界。这些库的核心计算引擎(比如pandas的Cython加速层、NumPy的BLAS/LAPACK后端)都是用C/C++/Fortran写的,然后被编译成特定CPU架构的机器码。这个过程,就像给一辆车定制发动机——给宝马X5造的V8发动机,绝不可能直接拧到丰田卡罗拉的发动机舱里。M1/M2芯片用的是ARM64指令集,而过去十年间绝大多数macOS预编译wheel包,都是为Intel的x86_64架构打造的。它们之间不是“性能差异”,而是“语言不通”。当你pip install一个标着macosx_10_9_x86_64.whl的包时,pip只是把它原封不动地解压到你的site-packages里;等到Python运行时试图加载那个.so动态库,操作系统内核一看:这玩意儿的指令集是x86_64,而我的CPU是arm64,对不起,拒载。这就是所有报错的物理根源,它不玄学,它就是计算机体系结构的铁律。

2.2 pip的wheel机制:便利性与脆弱性的双刃剑

pip之所以能成为Python事实上的包管理器,核心功臣是wheel格式。它把源码、编译好的二进制、元数据打包成一个.whl文件,用户安装时无需本地编译,秒级完成。但这个设计在跨架构场景下暴露了致命弱点:wheel的命名规范(PEP 427)本身就是一套精密的“兼容性指纹”系统。我们来拆解一个真实的wheel名:pandas-1.5.0-cp311-cp311-macosx_11_0_arm64.whl。它不是一个随意的字符串,而是一个由五段组成的、有严格语义的标签:

  • pandas-1.5.0:包名与版本,这是业务层;
  • cp311:表示它需要CPython 3.11解释器,这是运行时层;
  • cp311:第二个cp311代表ABI(Application Binary Interface),即Python C API的二进制兼容性版本,这是链接层;
  • macosx_11_0_arm64:这是最关键的平台层,它明确声明了“此二进制仅适用于macOS 11.0及以上,且CPU必须是arm64”。

pip在安装时,会根据你当前系统的platform.machine()(返回arm64)和sys.version_info(返回(3, 11, 0))等信息,去PyPI仓库里精准匹配这个五段式标签。如果找不到完全匹配的,它就会退回到“源码编译”模式。问题就出在这里:很多老库(比如uamqp)的wheel包,其平台标签是macosx_10_9_x86_64或更宽泛的macosx_10_9_universal2(universal2是苹果为过渡期设计的“胖二进制”,同时包含x86_64和arm64代码)。pip的匹配算法,在找不到arm64专属包时,会“降级”选择universal2,甚至在某些配置下,会错误地认为x86_64包也能“勉强运行”。结果就是安装成功,但运行时报错。这并非pip的bug,而是它的设计哲学——优先保证安装成功,把兼容性问题留给运行时。这种“乐观安装”策略,在单架构时代是福音,在多架构并存的今天,就成了埋雷现场。

2.3 conda的“全栈打包”哲学:为什么它更稳,却也更重?

如果说pip是“快递员”,只负责把包裹(wheel)送到你家门口,那么conda就是“基建队”,它不仅要送包裹,还要连同地基(C编译器)、钢筋(系统库)、甚至整栋楼(Python解释器本身)一起给你建好。conda的包(.tar.bz2)里,不仅有Python代码,还有它所依赖的所有动态链接库(.dylib)、头文件、甚至gccclang的特定版本。它通过一个叫conda-forge的社区,为每一个主流平台(osx-64,osx-arm64,linux-64,win-64)都维护着独立的、经过严格测试的二进制包仓库。当你执行conda install pandas时,conda会根据你的CONDA_DEFAULT_ENVplatform.machine(),从对应架构的仓库里下载一个“开箱即用”的完整环境。这从根本上规避了pip的“匹配失败”问题,因为conda的包本身就是为你的硬件量身定做的。但它的代价也很明显:包体积巨大(一个pytorchconda包动辄2GB),更新速度慢于PyPI(社区审核流程更长),并且最关键的是——不是所有Python包都在conda仓库里。像azure-eventhub这种云服务SDK,其主仓库在PyPI,conda-forge的镜像往往是滞后且不稳定的。所以,现实中绝大多数人走的是“conda建基础环境 + pip装缺失包”的混合路线,而这恰恰把pip的脆弱性又带了回来。理解这一点,你就明白了为什么“换conda”不是万能解药,而是一种权衡。

3. 核心细节解析与实操要点:三把硬刀子的原理、适用场景与致命陷阱

3.1 刀法一:pip install --no-binary —— 源码编译,以时间换空间

这是最“Python原教旨主义”的方案:既然没有现成的arm64二进制,那就自己动手丰衣足食。命令很简单:pip install --no-binary :all: package_name。但它的背后,是一场对本地开发环境的全面体检。

原理与触发条件--no-binary参数强制pip跳过所有预编译的wheel包,转而下载源码分发包(sdist,通常是.tar.gz),然后调用本地的setuptoolswheel工具链进行编译。这要求你的系统必须满足三个硬性条件:第一,安装了Xcode Command Line Tools(xcode-select --install);第二,安装了libffiopenssl等基础系统库(通常通过brew install libffi openssl);第三,目标包的setup.pypyproject.toml必须支持在arm64上编译。对于uamqp这种C扩展库,它依赖cmakeninja,所以你还得brew install cmake ninja

实操中的魔鬼细节

  • 不要全局禁用二进制--no-binary :all:会强制所有依赖(包括setuptoolswheel自己)都从源码编译,这会耗费数小时且极易失败。正确的做法是指定具体包:pip install --no-binary uamqp azure-eventhub。这样,azure-eventhub的纯Python部分仍用wheel,只有uamqp这个罪魁祸首被源码编译。
  • 编译缓存是你的朋友:第一次编译uamqp可能要5-10分钟,但pip会将编译产物缓存到~/Library/Caches/pip/。下次再装,只要版本没变,它会直接复用,秒级完成。
  • 环境变量是关键开关:有些库(如cryptography)需要额外的环境变量来指定系统库路径。例如,export LDFLAGS="-L$(brew --prefix openssl)/lib"export CPPFLAGS="-I$(brew --prefix openssl)/include"必须在pip install前设置,否则编译会找不到openssl头文件。

提示:此方案最适合“依赖树浅、C代码少、社区活跃”的包。像numpypandas这种庞然大物,源码编译在M2上可能耗时超过1小时,且失败率高,不推荐作为首选。

3.2 刀法二:Conda + Rosetta —— 架构虚拟化,以兼容性换性能

这是最“无痛”的方案,它不挑战硬件,而是绕开硬件。核心思想是:既然arm64原生包不够,那就让整个Python环境“假装”自己还在x86_64上运行。Rosetta 2是苹果内置的二进制翻译层,它能在M系列芯片上近乎实时地将x86_64指令翻译成arm64指令。conda的CONDA_SUBDIR环境变量,就是撬动这个杠杆的支点。

原理与操作链路CONDA_SUBDIR=osx-64这个环境变量,会欺骗conda的包解析器,让它认为当前系统是x86_64的macOS,从而从https://repo.anaconda.com/pkgs/main/osx-64/这个仓库下载所有包。创建的环境里,Python解释器、numpypandas,全部都是x86_64的二进制。当你的Python脚本运行时,macOS内核会自动调用Rosetta 2来翻译这些x86_64指令。实测下来,性能损失在10%-20%左右,对于绝大多数数据处理任务,这个代价完全可以接受。

实操中的避坑指南

  • 环境隔离是生命线:绝对不要在你的主conda环境(base)里设置CONDA_SUBDIR!必须新建一个专用环境:CONDA_SUBDIR=osx-64 conda create -n py310-x86 python=3.10。这样,你的日常开发(base环境)仍是arm64原生,只在需要跑特定老库时,才conda activate py310-x86
  • VS Code调试需手动指定解释器:激活x86环境后,在VS Code里按Cmd+Shift+P,输入Python: Select Interpreter,然后从列表里手动选择~/miniconda3/envs/py310-x86/bin/python。如果不这么做,VS Code的调试器可能仍在用arm64的Python,导致断点失效。
  • conda config --env的持久化陷阱conda config --env --set subdir osx-64这条命令,会把subdir: osx-64写入当前环境的conda-meta/history文件。这意味着,只要你conda activate这个环境,conda就会永远从x86_64仓库拉包。这是一个优点,也是一个风险——如果你某天想在这个环境里装一个arm64专属的新包(比如某个刚发布的M系列优化库),你就得先conda config --env --remove-key subdir来临时解除锁定。

注意:此方案的唯一短板是内存占用。Rosetta 2进程本身会常驻,加上x86_64的Python解释器比arm64版本多占约15%内存。如果你的MacBook只有16GB内存,且同时开着Docker和Chrome,可能会感到吃紧。

3.3 刀法三:Docker Multi-Arch —— 环境容器化,以可移植性换确定性

这是工程化程度最高的方案,它把“环境一致性”这个软件开发的终极难题,交给了Docker来解决。其核心信条是:“我的代码在哪跑,就应该在哪构建;我的构建环境,必须和生产环境100%一致。” Docker的--platform参数,就是实现这一信条的终极武器。

原理与构建哲学:Docker daemon在M1/M2 Mac上,原生支持--platform linux/amd64参数。当你执行docker build --platform linux/amd64 .时,Docker会启动一个QEMU模拟的x86_64 Linux内核,并在这个内核里运行整个构建过程。最终产出的镜像,其ARCHITECTURE字段被标记为amd64。当你docker run这个镜像时,Docker会再次调用Rosetta 2(这次是为Linux内核的x86_64指令做翻译),确保容器内的所有进程,都运行在x86_64的上下文中。这比conda方案更彻底,因为它连Linux内核都虚拟化了,彻底摆脱了macOS的任何限制。

实操中的黄金实践

  • Dockerfile里的FROM --platform是灵魂:在Dockerfile第一行写FROM --platform=linux/amd64 python:3.10-slim,这比在docker build命令里加--platform更可靠。因为build命令的--platform只影响本次构建,而Dockerfile里的--platform会成为镜像的元数据,后续所有docker run都会继承它,杜绝了“忘记加参数”的人为失误。
  • 多阶段构建是性能救星:对于需要编译的项目(如用poetry管理依赖),采用多阶段构建:第一阶段用linux/amd64python:3.10-build镜像,安装所有依赖并编译;第二阶段用轻量级的linux/amd64python:3.10-slim镜像,只COPY编译好的包。这样,最终镜像体积可以缩小50%以上。
  • .dockerignore是安全阀:务必在项目根目录创建.dockerignore文件,加入__pycache__/,.git/,venv/,node_modules/等。否则,docker build会把整个项目目录(包括你本地的arm64虚拟环境)都发送给Docker daemon,导致构建超时或失败。

提示:此方案的隐性成本是学习曲线。你需要掌握Docker的基本概念(镜像、容器、层、volume),以及如何在CI/CD流水线中集成--platform参数。但对于团队协作和持续交付,它是ROI(投资回报率)最高的选择——一个docker-compose.yml文件,就能让新同事在5分钟内拥有和你一模一样的、零兼容性问题的开发环境。

4. 实操过程与核心环节实现:从零开始,手把手复现一个稳定可用的M2开发环境

4.1 场景设定与目标验证

我们设定一个典型的、会让M2用户抓狂的真实场景:你需要在一个新的M2 MacBook Pro上,快速搭建一个能运行azure-eventhubSDK的Python环境,用于连接Azure云服务并消费事件流。我们的目标非常明确:执行以下Python脚本,必须成功输出Platform: arm64(证明是原生环境)和EventHub client created successfully(证明SDK工作正常),且整个过程可重复、可文档化。

# test_azure.py import platform print("Platform:", platform.machine()) from azure.eventhub import EventHubProducerClient print("EventHub client created successfully")

4.2 方案一:源码编译全流程实录(耗时约12分钟)

步骤1:环境初始化

# 确保系统工具链最新 xcode-select --install brew update && brew upgrade # 安装必要系统库 brew install libffi openssl cmake ninja pkg-config # 创建并激活一个干净的venv python3.11 -m venv ~/venvs/eh-native source ~/venvs/eh-native/bin/activate

步骤2:针对性源码编译

# 关键一步:只对uamqp禁用二进制,其他包保持wheel pip install --upgrade pip setuptools wheel pip install --no-binary uamqp azure-eventhub # 验证安装 pip list | grep -E "(uamqp|azure-eventhub)" # 输出应为:uamqp 1.7.2, azure-eventhub 5.11.0

步骤3:运行验证脚本

python test_azure.py # 预期输出: # Platform: arm64 # EventHub client created successfully

实测记录与参数说明

  • 编译uamqp时,pip会自动下载uamqp-1.7.2.tar.gz源码包(约1.2MB),解压后调用cmake生成Makefile,再用ninja编译。整个过程在M2 Max(32GB内存)上耗时约8分30秒。
  • --no-binary uamqp参数中的uamqp是包名,必须与PyPI上注册的名称完全一致(区分大小写)。如果写成UAMQP,pip会报错ERROR: Could not find a version that satisfies the requirement UAMQP
  • 如果编译失败,最常见的原因是cmake找不到openssl。此时,必须在pip install前执行:
    export OPENSSL_INCLUDE_DIR="$(brew --prefix openssl)/include" export OPENSSL_LIBRARY="$(brew --prefix openssl)/lib/libssl.dylib"

4.3 方案二:Conda+Rosetta全流程实录(耗时约3分钟)

步骤1:创建专用x86环境

# 使用conda-forge频道,它对x86_64的支持最完善 CONDA_SUBDIR=osx-64 conda create -n eh-x86 -c conda-forge python=3.10 # 激活环境并设置永久subdir conda activate eh-x86 conda config --env --set subdir osx-64 # 验证环境架构 python -c "import platform; print(platform.machine())" # 输出必须是:x86_64

步骤2:安装SDK与依赖

# 由于环境是x86_64,pip会自动选择x86_64的wheel pip install azure-eventhub # 验证 pip list | grep azure-eventhub # 输出:azure-eventhub 5.11.0

步骤3:运行验证脚本

# 注意:此时脚本中的platform.machine()会返回x86_64 python test_azure.py # 预期输出: # Platform: x86_64 # EventHub client created successfully

实操心得

  • conda-forge频道比默认的defaults频道对M系列Mac的支持更好,尤其是在x86_64包的更新速度上。强烈建议在~/.condarc中全局配置:
    channels: - conda-forge - defaults channel_priority: strict
  • 如果你在eh-x86环境中执行conda install numpy,conda会从osx-64仓库下载一个约120MB的numpy-1.24.3-py310h59b6b7e_0.tar.bz2包。这个包内部包含了针对x86_64优化的OpenBLAS库,性能远超源码编译的版本。

4.4 方案三:Docker Multi-Arch全流程实录(耗时约5分钟,含首次镜像拉取)

步骤1:编写Dockerfile

# Dockerfile.eh FROM --platform=linux/amd64 python:3.10-slim # 设置工作目录和时区 WORKDIR /app ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone # 复制依赖文件并安装 COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制应用代码 COPY . . # 运行验证脚本 CMD ["python", "test_azure.py"]

requirements.txt内容

azure-eventhub==5.11.0

步骤2:构建与运行

# 构建镜像,显式指定平台 docker build --platform linux/amd64 -f Dockerfile.eh -t eh-x86 . # 运行容器 docker run --rm eh-x86 # 输出: # Platform: x86_64 # EventHub client created successfully

关键参数解析

  • --platform linux/amd64:这是告诉Docker BuildKit,无论宿主机是什么架构,都要构建一个linux/amd64镜像。
  • -f Dockerfile.eh:指定Dockerfile路径,避免与项目中其他Dockerfile混淆。
  • --rm:容器运行结束后自动删除,保持环境整洁。
  • 首次构建时,Docker会拉取python:3.10-slimlinux/amd64镜像(约120MB),后续构建会复用缓存,速度极快。

5. 常见问题与排查技巧实录:那些让你拍桌怒吼的报错,其实都有迹可循

5.1 “ImportError: No module named 'xxx'” —— 虚假的模块缺失

现象:在conda x86_64环境中,pip install显示成功,但import xxx时却报ModuleNotFoundError

根本原因:这不是模块没装,而是Python解释器的“路径污染”。当你在base环境(arm64)里执行过pip install,它可能把包装到了~/miniconda3/lib/python3.11/site-packages/。而eh-x86环境的Python,其sys.path默认不包含这个路径。它只认自己环境下的~/miniconda3/envs/eh-x86/lib/python3.10/site-packages/

排查与解决

  1. eh-x86环境中,运行python -c "import sys; print('\n'.join(sys.path))",确认site-packages路径是否正确。
  2. 运行pip show xxx,看输出的Location:字段是否指向eh-x86的路径。
  3. 如果pip show找不到,说明确实没装对。执行which pip,确认它指向~/miniconda3/envs/eh-x86/bin/pip,然后重新pip install

经验:永远用conda activate env_name后再操作,而不是直接source activate env_name。后者在较新版本的conda中已被弃用,可能导致环境变量未正确加载。

5.2 “ERROR: Failed building wheel for xxx” —— 源码编译的死亡循环

现象pip install --no-binary xxx后,报错Failed building wheel for xxx,并附带一长串C编译错误。

典型场景cryptographypyarrowtensorflow等重度依赖系统库的包。

深层原因与破解之道

  • 原因1:缺少系统头文件cryptography需要rustc编译器。解决方案:brew install rust
  • 原因2:链接器找不到库pyarrow需要arrowC++库。解决方案:brew install apache-arrow,然后设置环境变量:
    export ARROW_HOME="$(brew --prefix apache-arrow)" export PKG_CONFIG_PATH="$ARROW_HOME/lib/pkgconfig"
  • 原因3:Python ABI不匹配tensorflow的源码包要求cp311ABI,但你的Python是cp311,却用了--no-binary,导致它试图用旧版setuptools编译。解决方案:先pip install --upgrade setuptools wheel,再重试。

终极保险方案:使用pip install --no-build-isolation --no-binary :all: xxx--no-build-isolation参数会禁用pip的沙盒构建,让编译过程能访问你系统里所有已安装的库和工具链,成功率大幅提升。

5.3 “docker build --platform ... fails with 'exec format error'” —— Docker的架构迷雾

现象:在Dockerfile中写了FROM --platform=linux/amd64 ubuntu,但docker build时却报standard_init_linux.go:228: exec user process caused: exec format error

真相揭秘:这个错误99%是因为你COPY了一个在arm64上编译的二进制文件(比如你本地的venv/bin/python)到镜像里。Docker镜像是linux/amd64的,但你塞进去的却是darwin/arm64的文件,自然无法执行。

排查清单

  • 检查Dockerfile中所有COPY指令,确保只复制源码(.py)、配置(.json)、文本(.txt)等与架构无关的文件。
  • 绝对不要COPY venv/ ./venv/COPY .git/ ./git/
  • docker build前,运行file $(which python),确认你的本地pythonx86_64还是arm64。如果是arm64,说明你没激活x86环境,which python返回的路径是错的。

快速验证法:在Dockerfile末尾加一行RUN uname -m,构建后docker run它。如果输出x86_64,说明平台设置成功;如果输出aarch64,说明--platform参数没生效,检查Docker Desktop是否开启了“Use the new Virtualization framework”(M系列Mac必需)。

5.4 “VS Code调试器无法连接到conda x86环境” —— IDE的架构盲区

现象:在VS Code里按F5调试test_azure.py,控制台输出Platform: arm64,而不是预期的x86_64

原因定位:VS Code的Python扩展,有一个“Python Interpreter”的全局设置。它默认会读取你终端当前的which python,但如果你是在base环境里打开VS Code,即使你后来conda activate eh-x86,VS Code的调试器进程可能仍绑定在base的Python上。

一劳永逸的解决方法

  1. 在VS Code中打开你的项目文件夹。
  2. Cmd+Shift+P,输入Python: Select Interpreter
  3. 在弹出的列表中,不要选“Enter interpreter path...”,而是向下滚动,找到Conda Environment分类下的eh-x86
  4. 选中后,VS Code会在项目根目录下生成一个.vscode/settings.json文件,内容为:
    { "python.defaultInterpreterPath": "~/miniconda3/envs/eh-x86/bin/python" }
    这个文件会被Git跟踪,确保所有团队成员都使用同一解释器。

实操心得:我踩过的最大坑,是在.vscode/settings.json里手写了"python.defaultInterpreterPath": "/Users/xxx/miniconda3/envs/eh-x86/bin/python",但路径里用了~符号。VS Code不识别~,导致调试器静默失败。必须用绝对路径,或者直接用VS Code的图形界面选择,它会自动帮你展开~

6. 方案对比与决策树:什么情况下该用哪一把刀?

面对一个全新的、未知兼容性的Python包,你该如何决策?下面这张表,是我过去三年在十几个M系列Mac项目中总结出的经验结晶,它不是教科书理论,而是血泪教训的浓缩。

评估维度pip install --no-binaryConda + RosettaDocker Multi-Arch
首次环境搭建耗时⏳ 5-30分钟(取决于包复杂度)⏱️ 2-5分钟⏱️ 3-8分钟(含首次镜像拉取)
长期维护成本📉 低(环境干净)📉 低(conda环境隔离好)📈 中(需维护Dockerfile和CI/CD)
性能损耗🚀 0%(arm64原生)🐢 ~10-20%(Rosetta翻译)🐢 ~15-25%(QEMU+Rosetta双重翻译)
内存占用🟢 低(纯Python进程)🟡 中(x86_64 Python + Rosetta)🔴 高(Docker daemon + QEMU进程)
团队协作友好度🔴 差(每个人的编译环境不同)🟡 中(需共享environment.yml🟢 极佳(Dockerfile即文档)
CI/CD流水线集成难度🔴 高(需在CI服务器上重现编译环境)🟡 中(需在CI上安装conda)🟢 低(标准Docker构建)
适用包类型✅ 小型C扩展(uamqp,cryptography
❌ 大型科学计算(numpy,tensorflow
✅ 所有conda-forge有包的库
✅ 混合生态(conda基础 + pip补充)
✅ 任何包(只要能pip install
✅ 需要Linux生产环境的项目

我的个人决策树(供你参考)

  • 第一步:查包源。打开PyPI页面,看Download files里有没有*arm64*.whl。如果有,直接pip install,万事大吉。
  • 第二步:查conda-forge。访问https://anaconda.org/conda-forge/<package-name>,看osx-arm64osx-64两个标签下,哪个有最新版。如果有osx-arm64,用conda install;如果没有,进入第三步。
  • 第三步:看包的“体重”。如果这个包的PyPI页面上,sdist源码包小于5MB,且GitHub README里没有“Requires CUDA”、“Requires Intel MKL”等重型依赖,就用pip install --no-binary。否则,果断切到Conda + Rosetta
  • 第四步:看项目性质。如果你的项目最终要部署到Linux服务器,或者需要和前端、数据库等其他服务一起用docker-compose编排,那就别犹豫,直接上Docker Multi-Arch。一次投入,终身受益。

最后再分享一个小技巧:在你的~/.zshrc里,添加一个别名:

alias pip-arm="pip install --no-binary :all:" alias pip-x86="CONDA_SUBDIR=osx-64 conda install"

这样,当你需要快速编译时,敲pip-arm uamqp;当你需要快速切x86环境时,敲pip-x86 azure-eventhub。键盘敲击次数,就是工程师的尊严。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询