Search code examples
python-cryptographyapple-siliconapple-m1

Installing Cryptography on an Apple Silicon M1 Mac


Help! I'm trying to install cryptography on my m1. I know I can run terminal in rosetta mode, but I'm wondering if there is a way not to do that.

Output:

    ERROR: Command errored out with exit status 1:
     command: /opt/homebrew/opt/[email protected]/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/[email protected]/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/[email protected]/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

I've tried to build and run like their instructions say in that code block to the same error. I've looked around and nobody has seemingly found the fix yet, but those things are two months old usually. What am I missing?


Solution

  • This issue is due to a mismatch between the libffi header version and the version of libffi the dynamic linker finds. In general it appears users encountering this problem have homebrew libffi installed and have a Python built against that in some fashion.

    When this happens cffi (a cryptography dependency) compiles, but fails at runtime raising this error. This should be fixable by passing the right path as a linker argument. To reinstall cffi you should pip uninstall cffi followed by

    LDFLAGS=-L$(brew --prefix libffi)/lib CFLAGS=-I$(brew --prefix libffi)/include pip install cffi --no-binary :all:

    This is an ugly workaround, but will get you past this hurdle for now.

    Update: I've uploaded arm64 wheels for macOS so the below compilation is no longer required if your pip is up-to-date. However, if, for some reason you wish to compile it yourself:

    LDFLAGS="-L$(brew --prefix [email protected])/lib" CFLAGS="-I$(brew --prefix [email protected])/include" pip install cryptography

    Update 2023: As of 2023 there are wheels for cffi and cryptography for Apple Silicon. If you are still seeing this type of error, there are a few likely culprits:

    1. Your pip is out of date. Update to latest! You can (and should) do all of this in a virtual environment.
    2. You are attempting to install an older version of cryptography. Any version >= 3.4.6 has an apple silicon wheel (either arm64 or universal2), but we only support the latest release so always update.
    3. You are attempting to install an older version of cffi. cffi cannot use abi3 so new wheels must be uploaded for each major Python release. If you're attempting to run an older cffi on a newer Python then a wheel may not be available and you'll need to compile.