苹果硅上的Python、Django和React开发

169 阅读5分钟

去年,苹果公司宣布,他们将把整个Mac产品线从英特尔处理器过渡到他们的ARM64苹果硅芯片,称为M1。几周前,我开始在装有苹果M1芯片的MacBook Air上测试开发(如上图)。

**在M1上可以开发吗?是的。它是否容易和直接?并不总是这样,但如果你能接受一些变通办法,你就可以使它发挥作用。**虽然许多软件包现在都支持苹果硅(见 "它是ARM吗?"),但开发领域仍在推出支持,如Docker

这篇文章可能会很快过时在过去的几周里,许多软件包都收到了与苹果硅相关的更新。

我的开发环境

在高层次上,我目前在M1上运行以下东西。

  • Python和Django (Homebrew和Xcode)
  • JavaScript和React (Homebrew和nvm)
  • PostgreSQL (Homebrew)
  • Docker(苹果M1技术预览)
  • Visual Studio Code(Insiders)

其他软件包被用来帮助实现这个开发环境,从iTerm2direnv,所以M1的支持在这里看起来不错。我仍然有问题或者还没有时间去挖掘的领域是。

  • Rosetta 2下的Python 3.7
  • 在本地构建和运行某些Docker镜像
  • Java

下面的信息涵盖了配置这样一个开发环境的步骤(和问题)。

Rosetta 2和Xcode的命令行工具

首先,确保Rosetta 2已经安装。Rosetta 2使装有Apple silicon的Mac能够使用为装有Intel处理器的Mac开发的应用程序。安装它时要注意。

同时,安装Xcode的命令行工具,用于python3和其他有用的库。

xcode-select --install

活动监视器包括一个方便的架构栏,显示哪些进程是在苹果与英特尔(Rosetta 2)架构上运行。下面是一张截图,显示Python 3.7在Rosetta 2下运行。

Activity Monitor Screenshot

英特尔模拟的终端

安装了Rosetta 2后,你可以使用arch命令在Rosetta 2下运行命令。

我目前的.zshrc配置与使用Rosetta 2不兼容,所以你可能无法像这样启动zshshell。

arch -x86_64 zsh
arch: posix_spawnp: zsh: Bad CPU type in executable

所以我使用第一个例子中提到的bash,在Rosetta 2下安装软件包。

安装Homebrew

Homebrew确实支持苹果硅。然而,一个特定的软件包可能不会原生运行,所以你的里程可能会有所不同。为了支持运行原生的arm64和x86模拟的homebrew包,你要并排安装它们。

使用替代安装方法将arm64brew安装到/opt/homebrew。

安装Intel-emulated Homebrew

将Intel-emulated Homebrew安装到默认的/usr/local。

arch --x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

苹果硅的解决方法 - nvm

nvm在Homebrew中是可用的。

我能够使用nvm安装最新版本的node。

它从源码构建,花了一些时间,但最终产生了一个arm64可执行文件。

然而,正如nvm安装node在macOS Big Sur M1 Chip #2350上安装失败所指出的,旧版本的node需要Rosetta 2。

你可以像这样安装Node v12。

现在你可以无缝切换了。

Python

Python 3.8和Python 3.9可以使用自制软件轻松安装。

❯ brew install python@3.8 python@3.9
❯ file /opt/homebrew/bin/python3.9
/opt/homebrew/bin/python3.9: Mach-O 64-bit executable arm64

然而,问题41100表明Python 3.7及以下版本在苹果硅上将永远不被支持。

目前没有计划对3.7和3.6进行回传支持,这两个版本在发布周期中只处于安全修复的阶段。

这些版本需要Rosetta 2。此外,并不是所有的Python库和包都能在Apple Silicon上运行,所以安装Intel模拟的版本也很有用。

❯ arch -x86_64 bash
$ export PATH="/usr/local/Homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
$ brew install python@3.7 python@3.8
$ file /usr/local/opt/python@3.7/bin/python3.7
/usr/local/opt/python@3.7/bin/python3.7: Mach-O 64-bit executable x86_64

Xcode的命令行工具提供了几个可以在苹果硅上原生运行的Python版本。所以在Xcode的帮助下,我目前正在使用Homebrew和Xcode运行以下版本的Python。

arm64。

  • Python 2.7.16 (Xcode)
  • Python 3.8.7 (homebrew)
  • Python 3.9.1 (homebrew)

Intel-emulated (with Rosetta 2):

  • Python 3.7.9 (自制)
  • Python 3.8.7 (自制)

使用direnv的Python

我曾经使用pyenvpyenv-virtualenv,但我无法成功地安装不同的版本(即使在Rosetta中)。我现在改用direnv的layout_python来代替pyenv-virtualenv对项目虚拟环境的管理,到目前为止,效果很好。

它很容易自动创建和激活一个基于 arm64 的 Python 3.9 的虚拟环境。

# project-a/.envrc
layout python /opt/homebrew/bin/python3.9

而用英特尔仿真的Python 3.7也同样容易。

# project-b/.envrc
layout python /usr/local/opt/python@3.7/bin/python3

需要编译的 Python 包

我发现导出这些标志对确保Python包的正确编译很有用。

Python Intel-emulated 的解决方法

有些软件包在苹果硅上安装失败。

❯ file `which python`
/Users/copelco/projects/.../.direnv/python-3.9.1/bin/python: Mach-O 64-bit executable arm64
❯ pip install numpy
*** snip ****
  ----------------------------------------
  ERROR: Failed building wheel for numpy

但可以使用 Intel-emulated 版本进行安装。

❯ file `which python`
/Users/copelco/projects/.../.direnv/python-3.8.7/bin/python: Mach-O 64-bit executable x86_64
❯ pip install numpy

与 Intel-emulated Python 3.7 的问题

我在Python 3.7上遇到的问题最多。Python 3.7在Apple Silicon上不被支持。它可以通过使用Rosetta 2的Homebrew安装,但我在Django项目中使用它时遇到了麻烦。

例如,我遇到了有外部依赖性的软件包(如libffi)的问题。

❯ file `which python`
/Users/copelco/projects/.../.direnv/python-3.7.9/bin/python: Mach-O 64-bit executable x86_64
❯ pip install bcrypt
❯ python3 -m bcrypt
Traceback (most recent call last):
  File "/usr/local/Cellar/python@3.7/3.7.9_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 183, in _run_module_as_main
    mod_name, mod_spec, code = _get_module_details(mod_name, _Error)
  File "/usr/local/Cellar/python@3.7/3.7.9_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 142, in _get_module_details
    return _get_module_details(pkg_main_name, error)
  File "/usr/local/Cellar/python@3.7/3.7.9_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 109, in _get_module_details
    __import__(pkg_name)
  File "/Users/copelco/projects/test/.direnv/python-3.7.9/lib/python3.7/site-packages/bcrypt/__init__.py", line 25, in <module>
    from . import _bcrypt  # type: ignore
ImportError: dlopen(/Users/copelco/projects/test/.direnv/python-3.7.9/lib/python3.7/site-packages/_cffi_backend.cpython-37m-darwin.so, 2): Symbol not found: _ffi_type_double
  Referenced from: /Users/copelco/projects/test/.direnv/python-3.7.9/lib/python3.7/site-packages/_cffi_backend.cpython-37m-darwin.so
  Expected in: flat namespace
 in /Users/copelco/projects/test/.direnv/python-3.7.9/lib/python3.7/site-packages/_cffi_backend.cpython-37m-darwin.so

Docker

Docker可以使用苹果M1技术预览版来安装。我使用这个版本遇到了几个问题。

第一个问题是一些镜像依赖的二进制文件还没有arm64的变种。例如,npm install在这里找不到sentry-cli-Linux-arm64。

我已经研究过使用buildx来支持多架构构建,比如在这篇《如何实际部署用苹果硅在M1 Mac上构建的Docker镜像》博文中。问题是,在某些情况下,我只想构建x86变体。

目前,我正在使用如何用docker-compose在远程Docker主机上进行部署,用Docker Contexts构建x86镜像。这种方法允许我将我的dockerCLI指向运行在我本地网络上的Linux盒子来构建镜像。

Kubernetes - kubectl CLI

苹果硅上的kubectl定位于Go 1.16。在macOS上用curl安装kubectl二进制文件后,我没能用Rosetta 2运行二进制文件。然而,Docker的[苹果M1技术预览]带有kubectl 1.19。

不过,你也可以用自制的方式来安装英特尔仿真版的kubectl。

摘要

就这样吧!如果你有其他想法和/或解决方法,我很高兴在评论中听到它们。