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

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.
😸😸😸 Check out my new book on using GitHub effectively, Boost Your GitHub DX! 😸😸😸
One summary email a week, no spam, I pinky promise.
Related posts:
Tags: python