Python: fuss-free use of Homebrew libraries for package dependencies

Mini library.

Some Python packages require native libraries to be installed on your system when you install them. For example, mysqlclient requires libssl and libcrypto. If those libraries are missing at install time, clang, the C compiler, fails with a message like:

$ pip install mysqlclient
Collecting mysqlclient
  Downloading mysqlclient-2.2.7.tar.gz (91 kB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: mysqlclient
  Building wheel for mysqlclient (pyproject.toml) ... error
  error: subprocess-exited-with-error

  × Building wheel for mysqlclient (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [47 lines of output]
      ...
      ld: library 'ssl' not found
      clang: error: linker command failed with exit code 1 (use -v to see invocation)
      error: command '/usr/bin/cc' failed with exit code 1
      [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for mysqlclient
Failed to build mysqlclient
ERROR: ERROR: Failed to build installable wheels for some pyproject.toml based projects (mysqlclient)

Here’s the full message if you care to see it:

Full message
$ pip install mysqlclient
Collecting mysqlclient
  Downloading mysqlclient-2.2.7.tar.gz (91 kB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: mysqlclient
  Building wheel for mysqlclient (pyproject.toml) ... error
  error: subprocess-exited-with-error

  × Building wheel for mysqlclient (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [47 lines of output]
      Trying pkg-config --exists mysqlclient
      Command 'pkg-config --exists mysqlclient' returned non-zero exit status 1.
      Trying pkg-config --exists mariadb
      # Options for building extension module:
        extra_compile_args: ['-I/opt/homebrew/Cellar/mariadb/11.6.2/include/mysql', '-std=c99']
        extra_link_args: ['-L/opt/homebrew/Cellar/mariadb/11.6.2/lib', '-lmariadb', '-lssl', '-lcrypto']
        define_macros: [('version_info', (2, 2, 7, 'final', 0)), ('__version__', '2.2.7')]
      running bdist_wheel
      running build
      running build_py
      creating build/lib.macosx-11.0-arm64-cpython-313/MySQLdb
      copying src/MySQLdb/release.py -> build/lib.macosx-11.0-arm64-cpython-313/MySQLdb
      copying src/MySQLdb/cursors.py -> build/lib.macosx-11.0-arm64-cpython-313/MySQLdb
      copying src/MySQLdb/connections.py -> build/lib.macosx-11.0-arm64-cpython-313/MySQLdb
      copying src/MySQLdb/__init__.py -> build/lib.macosx-11.0-arm64-cpython-313/MySQLdb
      copying src/MySQLdb/times.py -> build/lib.macosx-11.0-arm64-cpython-313/MySQLdb
      copying src/MySQLdb/converters.py -> build/lib.macosx-11.0-arm64-cpython-313/MySQLdb
      copying src/MySQLdb/_exceptions.py -> build/lib.macosx-11.0-arm64-cpython-313/MySQLdb
      creating build/lib.macosx-11.0-arm64-cpython-313/MySQLdb/constants
      copying src/MySQLdb/constants/FLAG.py -> build/lib.macosx-11.0-arm64-cpython-313/MySQLdb/constants
      copying src/MySQLdb/constants/CLIENT.py -> build/lib.macosx-11.0-arm64-cpython-313/MySQLdb/constants
      copying src/MySQLdb/constants/__init__.py -> build/lib.macosx-11.0-arm64-cpython-313/MySQLdb/constants
      copying src/MySQLdb/constants/ER.py -> build/lib.macosx-11.0-arm64-cpython-313/MySQLdb/constants
      copying src/MySQLdb/constants/CR.py -> build/lib.macosx-11.0-arm64-cpython-313/MySQLdb/constants
      copying src/MySQLdb/constants/FIELD_TYPE.py -> build/lib.macosx-11.0-arm64-cpython-313/MySQLdb/constants
      running egg_info
      writing src/mysqlclient.egg-info/PKG-INFO
      writing dependency_links to src/mysqlclient.egg-info/dependency_links.txt
      writing top-level names to src/mysqlclient.egg-info/top_level.txt
      reading manifest file 'src/mysqlclient.egg-info/SOURCES.txt'
      reading manifest template 'MANIFEST.in'
      adding license file 'LICENSE'
      writing manifest file 'src/mysqlclient.egg-info/SOURCES.txt'
      copying src/MySQLdb/_mysql.c -> build/lib.macosx-11.0-arm64-cpython-313/MySQLdb
      running build_ext
      building 'MySQLdb._mysql' extension
      creating build/temp.macosx-11.0-arm64-cpython-313/src/MySQLdb
      cc -fno-strict-overflow -Wsign-compare -Wunreachable-code -DNDEBUG -g -O3 -Wall -arch arm64 -mmacosx-version-min=11.0 -Wno-nullability-completeness -Wno-expansion-to-defined -Wno-undef-prefix -fPIC "-Dversion_info=(2, 2, 7, 'final', 0)" -D__version__=2.2.7 -I/Users/chainz/tmp/pip-missing-libraries/.venv/include -I/Users/chainz/.local/share/uv/python/cpython-3.13.1-macos-aarch64-none/include/python3.13 -c src/MySQLdb/_mysql.c -o build/temp.macosx-11.0-arm64-cpython-313/src/MySQLdb/_mysql.o -I/opt/homebrew/Cellar/mariadb/11.6.2/include/mysql -std=c99
      src/MySQLdb/_mysql.c:488:10: warning: variable 'ssl_mode_set' set but not used [-Wunused-but-set-variable]
        488 |     char ssl_mode_set = 0;
            |          ^
      1 warning generated.
      cc -bundle -undefined dynamic_lookup -arch arm64 -mmacosx-version-min=11.0 -LModules/_hacl build/temp.macosx-11.0-arm64-cpython-313/src/MySQLdb/_mysql.o -L/Users/chainz/.local/share/uv/python/cpython-3.13.1-macos-aarch64-none/lib -o build/lib.macosx-11.0-arm64-cpython-313/MySQLdb/_mysql.cpython-313-darwin.so -L/opt/homebrew/Cellar/mariadb/11.6.2/lib -lmariadb -lssl -lcrypto
      ld: warning: search path 'Modules/_hacl' not found
      ld: library 'ssl' not found
      clang: error: linker command failed with exit code 1 (use -v to see invocation)
      error: command '/usr/bin/cc' failed with exit code 1
      [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for mysqlclient
Failed to build mysqlclient
ERROR: ERROR: Failed to build installable wheels for some pyproject.toml based projects (mysqlclient)

The key line is:

ld: library 'ssl' not found

ld is the linker, the tool that combines the extension with the libraries it needs. It’s failing to find the ssl library.

You can install libssl from the openssl Homebrew package:

$ brew install openssl

But just installing it is not sufficient. Homebrew places the library files in its own directory, separate from the system defaults. To make them available to the linker, you need to declare this directory in the LDFLAGS environment variable. Additionally, you’ll likely want to declare the installed C header files directory in the CFLAGS environment variable. To do both use:

# C compiler use Homebrew-installed headers and libraries
export CPPFLAGS="-I/opt/homebrew/include"
export LDFLAGS="-L/opt/homebrew/lib"

Put this in your shell RC file so it’s always available: ~/.zshrc for Zsh, or ~/.bashrc for Bash. Then source that file to apply the changes:

$ source ~/.zshrc

Then, you should find the installation succeeds:

$ pip install mysqlclient
Collecting mysqlclient
  Using cached mysqlclient-2.2.7.tar.gz (91 kB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: mysqlclient
  Building wheel for mysqlclient (pyproject.toml) ... done
  Created wheel for mysqlclient: filename=mysqlclient-2.2.7-cp313-cp313-macosx_11_0_arm64.whl size=76691 sha256=93650987dd6b9d99f30e6cdf73a61f6b0323761b313d61bab4f8ef822a98fe7e
  Stored in directory: /Users/chainz/Library/Caches/pip/wheels/8a/c8/52/16875174760e2325aa4ba72f82c921b4d80636783d0ef584a2
Successfully built mysqlclient
Installing collected packages: mysqlclient
Successfully installed mysqlclient-2.2.7

(mysqlclient in particular depends on libcrypto as well as openssl, so you may need to install that too.)

Great, now you can get to coding.

Fin

May your installations be smoother hereafter,

—Adam


😸😸😸 Check out my new book on using GitHub effectively, Boost Your GitHub DX! 😸😸😸


Subscribe via RSS, Twitter, Mastodon, or email:

One summary email a week, no spam, I pinky promise.

Related posts:

Tags: