pip で C拡張パッケージをビルドするときに include と lib のパス指定が必要になる理由
Apple Silicon 環境(特に conda + pip 併用)向けの解説
概要
conda 環境では多くの Python パッケージがプリビルド(バイナリ)で提供される。
しかし一部のパッケージ(例 pyaudio、portaudio を必要とするもの、特殊な C/NASM/Fortran を含むもの)は conda にビルド済みパッケージがなく、pip にビルドを任せることになる。
このとき pip は、パッケージ内部の Cコードをコンパイルするために ヘッダファイル(include) と ライブラリ(lib) を必要とするが、デフォルトでは
- Xcode の標準パス
- /usr/local(Intel Homebrew 想定)
しか探さないことが多い。
Apple Silicon 環境では、conda の依存ライブラリは
$CONDA_PREFIX/include
$CONDA_PREFIX/lib
に置かれているため、そのままでは pip が見つけられずビルドに失敗する。
よくある状況
- Apple Silicon Mac
- conda の仮想環境を使用
- portaudio、libsndfile、OpenBLAS、その他 C ライブラリを利用するパッケージ
- pip install するとビルドエラーが出る
- エラー内容は
- “header file not found”
- “library not found”
- “fatal error: file.h: No such file or directory”
ベストプラクティス(Apple Silicon 向け)
export CFLAGS="-I$CONDA_PREFIX/include"
export LDFLAGS="-L$CONDA_PREFIX/lib"
pip install pyaudio
成功時は:
install succeeded
などのメッセージが出る。
なぜ Apple Silicon では特に起こりやすいのか
- Apple が /usr/local を使わず /opt/homebrew を採用している
- conda-forge が M1/M2 用に独立パス(env ごとに完全隔離)
- pip のビルドスクリプトは
- /usr/include
- /usr/local/include
しか探索しない
こういうケースはよくあるか
結論:かなりよくある。特に C拡張パッケージで頻発する。
よく起きる例
- pyaudio
- pysam
- soundfile
- scipy
- lightgbm
- Pillow
- pygraphviz
回避策
conda-forge を最優先
conda config --add channels conda-forge
conda config --set channel_priority strict
必要ライブラリを OS側に入れておく
brew install portaudio
依存を conda で導入してから pip
conda install portaudio
pip install pyaudio
まとめ
- conda で入らない C拡張パッケージを pip で入れると include と lib のパス不足でビルドエラーが頻発
- Apple Silicon + conda で特に多い
- ベストプラクティス
export CFLAGS="-I$CONDA_PREFIX/include"
export LDFLAGS="-L$CONDA_PREFIX/lib"
pip install パッケージ名