在Apple Silicon M1 Mac上安装密码学

32

帮帮我!我正在尝试在我的M1芯片电脑上安装密码学软件。我知道可以在Rosetta模式下运行终端,但我想知道是否有其他方法。

输出:

    ERROR: Command errored out with exit status 1:
     command: /opt/homebrew/opt/python@3.9/bin/python3.9 /opt/homebrew/lib/python3.9/site-packages/pip/_vendor/pep517/_in_process.py prepare_metadata_for_build_wheel /var/folders/hj/5zfkv68d7lqgrfqt046bn23c0000gn/T/tmpl4sga84k
         cwd: /private/var/folders/hj/5zfkv68d7lqgrfqt046bn23c0000gn/T/pip-install-jko4b562/cryptography_7b1bbc9ece2f481a8e8e9ea03b1a0030
    Complete output (55 lines):
    
        =============================DEBUG ASSISTANCE=============================
        If you are seeing a compilation error please try the following steps to
        successfully install cryptography:
        1) Upgrade to the latest pip and try again. This will fix errors for most
           users. See: https://pip.pypa.io/en/stable/installing/#upgrading-pip
        2) Read https://cryptography.io/en/latest/installation.html for specific
           instructions for your platform.
        3) Check our frequently asked questions for more information:
           https://cryptography.io/en/latest/faq.html
        =============================DEBUG ASSISTANCE=============================
    
    Traceback (most recent call last):
      File "/opt/homebrew/lib/python3.9/site-packages/pip/_vendor/pep517/_in_process.py", line 280, in <module>
        main()
      File "/opt/homebrew/lib/python3.9/site-packages/pip/_vendor/pep517/_in_process.py", line 263, in main
        json_out['return_val'] = hook(**hook_input['kwargs'])
      File "/opt/homebrew/lib/python3.9/site-packages/pip/_vendor/pep517/_in_process.py", line 133, in prepare_metadata_for_build_wheel
        return hook(metadata_directory, config_settings)
      File "/private/var/folders/hj/5zfkv68d7lqgrfqt046bn23c0000gn/T/pip-build-env-9bqzge_f/overlay/lib/python3.9/site-packages/setuptools/build_meta.py", line 161, in prepare_metadata_for_build_wheel
        self.run_setup()
      File "/private/var/folders/hj/5zfkv68d7lqgrfqt046bn23c0000gn/T/pip-build-env-9bqzge_f/overlay/lib/python3.9/site-packages/setuptools/build_meta.py", line 145, in run_setup
        exec(compile(code, __file__, 'exec'), locals())
      File "setup.py", line 44, in <module>
        setup(
      File "/private/var/folders/hj/5zfkv68d7lqgrfqt046bn23c0000gn/T/pip-build-env-9bqzge_f/overlay/lib/python3.9/site-packages/setuptools/__init__.py", line 153, in setup
        return distutils.core.setup(**attrs)
      File "/opt/homebrew/Cellar/python@3.9/3.9.1_7/Frameworks/Python.framework/Versions/3.9/lib/python3.9/distutils/core.py", line 108, in setup
        _setup_distribution = dist = klass(attrs)
      File "/private/var/folders/hj/5zfkv68d7lqgrfqt046bn23c0000gn/T/pip-build-env-9bqzge_f/overlay/lib/python3.9/site-packages/setuptools/dist.py", line 432, in __init__
        _Distribution.__init__(self, {
      File "/opt/homebrew/Cellar/python@3.9/3.9.1_7/Frameworks/Python.framework/Versions/3.9/lib/python3.9/distutils/dist.py", line 292, in __init__
        self.finalize_options()
      File "/private/var/folders/hj/5zfkv68d7lqgrfqt046bn23c0000gn/T/pip-build-env-9bqzge_f/overlay/lib/python3.9/site-packages/setuptools/dist.py", line 708, in finalize_options
        ep(self)
      File "/private/var/folders/hj/5zfkv68d7lqgrfqt046bn23c0000gn/T/pip-build-env-9bqzge_f/overlay/lib/python3.9/site-packages/setuptools/dist.py", line 715, in _finalize_setup_keywords
        ep.load()(self, ep.name, value)
      File "/private/var/folders/hj/5zfkv68d7lqgrfqt046bn23c0000gn/T/pip-build-env-9bqzge_f/overlay/lib/python3.9/site-packages/cffi/setuptools_ext.py", line 219, in cffi_modules
        add_cffi_module(dist, cffi_module)
      File "/private/var/folders/hj/5zfkv68d7lqgrfqt046bn23c0000gn/T/pip-build-env-9bqzge_f/overlay/lib/python3.9/site-packages/cffi/setuptools_ext.py", line 49, in add_cffi_module
        execfile(build_file_name, mod_vars)
      File "/private/var/folders/hj/5zfkv68d7lqgrfqt046bn23c0000gn/T/pip-build-env-9bqzge_f/overlay/lib/python3.9/site-packages/cffi/setuptools_ext.py", line 25, in execfile
        exec(code, glob, glob)
      File "src/_cffi_src/build_openssl.py", line 77, in <module>
        ffi = build_ffi_for_binding(
      File "src/_cffi_src/utils.py", line 54, in build_ffi_for_binding
        ffi = build_ffi(
      File "src/_cffi_src/utils.py", line 74, in build_ffi
        ffi = FFI()
      File "/private/var/folders/hj/5zfkv68d7lqgrfqt046bn23c0000gn/T/pip-build-env-9bqzge_f/overlay/lib/python3.9/site-packages/cffi/api.py", line 48, in __init__
        import _cffi_backend as backend
    ImportError: dlopen(/private/var/folders/hj/5zfkv68d7lqgrfqt046bn23c0000gn/T/pip-build-env-9bqzge_f/overlay/lib/python3.9/site-packages/_cffi_backend.cpython-39-darwin.so, 2): Symbol not found: _ffi_prep_closure
      Referenced from: /private/var/folders/hj/5zfkv68d7lqgrfqt046bn23c0000gn/T/pip-build-env-9bqzge_f/overlay/lib/python3.9/site-packages/_cffi_backend.cpython-39-darwin.so
      Expected in: flat namespace
     in /private/var/folders/hj/5zfkv68d7lqgrfqt046bn23c0000gn/T/pip-build-env-9bqzge_f/overlay/lib/python3.9/site-packages/_cffi_backend.cpython-39-darwin.so

我按照代码块中的指示尝试构建和运行,但出现了相同的错误。我查看了周围的情况,似乎还没有找到解决方法,但这些信息通常都是两个月前的。我错过了什么?

8个回答

58
这个问题是由于libffi头文件版本与动态链接器找到的libffi版本不匹配导致的。一般来说,遇到这个问题的用户安装了homebrew libffi,并且使用某种方式构建了一个针对该版本的Python。
当出现这种情况时,cffi(cryptography的依赖项)会编译,但在运行时失败并引发此错误。通过将正确的路径作为链接器参数传递,可以解决此问题。要重新安装cffi,您应该先执行pip uninstall cffi,然后执行以下操作:
LDFLAGS=-L$(brew --prefix libffi)/lib CFLAGS=-I$(brew --prefix libffi)/include pip install cffi --no-binary :all:
这是一个丑陋的解决方法,但目前可以帮助您克服这个障碍。
更新:我已经上传了macOS的arm64 wheels,因此如果您的pip是最新的,则不再需要下面的编译过程。但是,如果出于某种原因您希望自己进行编译,请执行以下操作:
LDFLAGS="-L$(brew --prefix openssl@1.1)/lib" CFLAGS="-I$(brew --prefix openssl@1.1)/include" pip install cryptography
2023年更新:截至2023年,Apple Silicon已经有了cffi和cryptography的轮子。如果您仍然看到这种类型的错误,可能有几个可能的原因:
1. 您的pip版本过旧。请更新到最新版本!您可以(也应该)在虚拟环境中完成所有操作。
2. 您正在尝试安装较旧版本的cryptography。任何版本>= 3.4.6都有适用于Apple Silicon的轮子(arm64或universal2),但我们只支持最新版本,所以请始终更新。
3. 您正在尝试安装较旧版本的cffi。cffi无法使用abi3,因此必须为每个主要的Python发布上传新的轮子。如果您尝试在较新的Python上运行较旧的cffi,则可能没有可用的轮子,您需要进行编译。

2
谢谢,我在其他地方找到了这个答案,但它绝对是正确的。 - Joe Fedorowicz
1
当我运行 pip uninstall cffi 时,它只告诉我该软件包未安装。但是,我仍然遇到了如上述的确切错误。 - James Parker
尽管我已经安装了最新版本的pip,但更新仍然无法正常工作。不过第一个解决方法仍然有效。谢谢。 - Yehya
1
更新的信息是针对 cryptography 包,该包具有更多的构建要求。主要的说明是为了解决 cffi 问题,截至2021年6月,它不提供 macOS arm64 wheel。一旦您拥有了它,那么 cryptography wheel 将能够正常工作并简化您的安装过程。 - Paul Kehrer
我在我的M1 Mac上内置的Python中使用的加密功能无法正常工作。例如,fabric与其不兼容。我能够从Nix软件包管理器获取适用于arm的python2(这是我在M1 Mac上找到python2软件包的唯一地方),然后从那里安装了一个可用的加密功能。请参阅https://stackoverflow.com/questions/68293059/mac-os-11-4-big-sur-fixing-python-cryptography-package-in-system-library-fram/68309199 - nobled
显示剩余3条评论

10

我正在使用Macbook Pro M1 2020模型,遇到了同样的问题。这个问题只可能与我的cffi和pip版本有关。因为下面这4个步骤帮助我解决了问题:

  1. 卸载旧版cffi pip uninstall cffi
  2. 升级pip python -m pip install --upgrade pip
  3. 重新安装cffi pip install cffi
  4. 安装cryptography pip install cryptography

9
有点晚了,但是上面的解决方案对我没用。Paul引导我正确解决问题,但我的问题是pyenv使用mac libffi来进行构建,而cffi使用homebrew版本。我在某个地方读到了这个信息,不能声称这是独特的见解。 我的解决方法是确保我的Python(3.8.13)通过正确的头文件库和包配置使用homebrew libffi构建。
export LDFLAGS="-L$(brew --prefix zlib)/lib -L$(brew --prefix bzip2)/lib -L$(brew --prefix openssl@1.1)/lib -L$(brew --prefix libffi)/lib"
export CPPFLAGS="-I$(brew --prefix zlib)/include -I$(brew --prefix bzip2)/include -I$(brew --prefix openssl@1.1)/include -I$(brew --prefix libffi)/include"
export PKG_CONFIG_PATH="$(brew --prefix openssl@1.1)/lib/pkgconfig:$(brew --prefix libffi)/lib/pkgconfig"

重新构建 Python...
pyenv uninstall 3.8.13
pyenv install 3.8.13

清除pip缓存
pip cache purge

最后,使用pipenv重新安装我的依赖项

pipenv --rm
pipenv sync --dev

经过这些步骤,我成功摆脱了令人恐惧的

ImportError: dlopen(/private/var/folders/k7/z3mq67_532bdr_rcm2grml240000gn/T/pip-build-env-apk5b25z/overlay/lib/python3.8/site-packages/_cffi_backend.cpython-38-darwin.so, 0x0002): symbol not found in flat namespace '_ffi_prep_closure'

感谢您提供的类型,此答案中的CFLAGS和PKGCONFIG解决了问题。 - Jean-Bernard Jansen
希望我能给你一杯啤酒作为答谢,@Matt。其他关于这个问题的回答大多对我无效,我本来就怀疑这可能是原因,但没想到pyenv会以这种方式重新构建我所需的 Python 版本,并正确链接库。非常感谢! - ewall

6

可能你会遇到更多的软件包,每个都有自己的Apple Silicon解决方案,这很烦人。

我找到了最终的解决方案:使用x86_x64 Homebrew安装x86软件包,包括Python。因此,所有的要求都像在x86_x64的Mac上一样安装,并且不再出现编译错误等问题。

操作步骤:

  1. 在 Rosetta 2 下运行 iTerm2(或默认的 Terminal 应用程序)(右键单击应用程序图标 -> 获取信息 -> 使用 Rosetta 打开)。
  2. 像平常一样安装 homebrew /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 或者您可以从 https://brew.sh/ 获取此链接以提高安全性(不要在没有仔细检查的情况下从 stackoverflow 复制 curl 命令)。
  3. 在你的 ~/.zshrc(如果你使用 ZSH)或 ~/.bash_profile(如果你是 bash 用户)中添加别名:alias brew='arch -x86_64 /usr/local/bin/brew'
  4. 关闭 iTerm2 的 使用 Rosetta 打开 选项 获取信息

现在,每次你在终端应用程序中输入 brew,你将运行 x86_x64 Homebrew。并且当你从 brew 安装任何软件包时,它将自动在 Rosetta 2 下工作。


还没有开始处理这个,但是非常感谢!这太疯狂了。我购买了一台MacMini M1,完全打算将其用作构建服务器。哎呀妈呀!真是一团糟。 - James Parker

3

我已经卸载了旧版本的cfficryptography

pip uninstall cffi
pip uninstall cryptography

并将requirements.txt文件中的确切版本更新为最新版本

# requirements.txt

cffi>=1.15.1 
cryptography>=38.0.1

(版本号可能不同)。 这解决了我的问题。


3

这个答案完美解决了我的问题!@paveldroo

作为上述答案的延伸,我继续执行了第3步并将别名设置为 alias ibrew='arch -x86_64 /usr/local/bin/brew' ,保存到 ~/.zshrc 文件中。

这意味着当我使用 brew 命令安装任何东西时,它会安装在 M1 架构上,而当我使用 ibrew 命令安装时,则会安装在 -x86_64 架构上。

因此,在我的系统上安装了两个 python3 实例,一个在 /opt/homebrew/bin/python3 使用 brew 安装,另一个在 /usr/local/bin/python3 使用 ibrew 安装。

这两个版本为创建项目虚拟环境提供了一定的灵活性。例如,您可以使用以下命令创建虚拟环境:

  1. /usr/local/bin/python3 -m venv venv 用于 -x86_64 架构
  2. /opt/homebrew/bin/python3 -m venv venv 用于 M1 架构

2

之前我无法安装cffi,直到我发现了一个不相关的问题。我折腾了两天,直到我找到了这个命令:

python3 -m ensurepip --upgrade

神奇地,一切都开始为我工作了。问题源于Python和Pip来自不同的源。

答案来源于这个问题:using pip3: module "importlib._bootstrap" has no attribute "SourceFileLoader"

编辑:这可能是上面帖子作者的举止,因此可能与此无关。如果是这样,谢谢匿名人士!


0

我通过使用 intel64 版本的 Python 解决了我的问题。因此,我使用 Python 网站 上的 macOS 64 位通用2安装程序 安装了 Python。

然后,我只需要使用例如 /usr/local/bin/ 中的 python3.11-intel64 文件创建虚拟环境,并使用该版本安装所有软件包:

$ venv/bin/python-intel64 -m pip install -r requirements.txt

一切都开始正常工作了,没有任何问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接