SNSへはこちら

Macのpkg-configでライブラリが認識されない/古いgccのビルドが失敗する

PC の Tips です。

pkg-configでライブラリが認識されない

Mac でインストールされているはずのライブラリが認識され無いことがありました。例えば gcc 等のビルドに必須になってくる任意精度数値計算ライブラリ mpfr。

$ pkg-config --libs mpfr
Package mpfr was not found in the pkg-config search path.
Perhaps you should add the directory containing `mpfr.pc'
to the PKG_CONFIG_PATH environment variable
No package 'mpfr' found

おかしいなぁ...と思い、Homebrew でも確認。

$ brew install mpfr
Warning: mpfr 4.0.2 is already installed and up-to-date
To reinstall 4.0.2, run `brew reinstall mpfr`

ですよねぇ。「あるぜ」とおっしゃっています。
この問題は結構前からハマっていて、とりあえず PKG_CONFIG_PATH に無理やりパスを追加したりしていました。

$ export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
$ pkg-config --libs mpfr
-L/usr/local/Cellar/mpfr/4.0.2/lib -lmpfr -lgmp

まあそりゃ出るよね、と。

しかし、いちいち認識されないライブラリが見つかったらエラーごとに対処するのは流石に面倒だし、そもそも環境ぶっ壊れているのか?と考えるとおかしすぎます。何かが絶対に間違っている。

最近、それに対する答えが出ましたのでご報告。

$ which pkg-config
/Library/Frameworks/Mono.framework/Commands/pkg-config

ん??

そう、これまで使ってきたのは Mono のパッケージに付いてきた pkg-config だったのです。多分 Visual Studio for Mac とかそこら編をインストールした時に入ってきたものですね。現在も Mac で C# をいじる時に使うことがあるパッケージです。パスの設定は、既存の /usr/local/bin よりもこちらを優先するように設定していました。
謎が解けました。ということで先程の環境変数を削除して、/usr/local/bin の方を実行してみましょう。

$ unset PKG_CONFIG_PATH
$ /usr/local/bin/pkg-config --libs mpfr
-L/usr/local/Cellar/mpfr/4.0.2/lib -lmpfr -lgmp

ちゃんと出ますね。よかったよかった。
ということで、パスの変更やシンボリックリンクの作成を行ってこのおかしな環境を直しました。

ついでにgmpについて解決

mpfr は上で解決しました。が、現状 gmp については、(少なくとも Homnebrew でインストールしたものに関しては) pkg-config で必要な .pc ファイルが無いようです。これでは困ってしまいますので、以下の Gist を参考にします。
多少無理やりな方法になってしまいますが、仕方ありません。

まずは現状のバージョンについて確認です。

$ ls /usr/local/Cellar/gmp/
6.1.2_2/

6.1.2_2 らしいので、上の Gist をコピペして、バージョンを 6.1.2_2 に置き換えます。具体的には、まず pc ファイルを個別に置く gmp 用の Cellar ディレクトリに lib/pkgconfig が存在しないので、それを作ってからになります。

$ cd /usr/local/Cellar/gmp/6.1.2_2/lib
$ mkdir pkgconfig
$ cd pkfconfig
$ vim gmp.pc # お好きなエディタで編集...バージョン番号を書き換えるのをお忘れなく
$ ln -s /usr/local/Cellar/gmp/6.1.2_2/lib/pkgconfig/gmp.pc /usr/local/lib/pkgconfig

これで多分 OK です。確認してみましょう。

$ pkg-config --libs --cflags gmp
-I/usr/local/Cellar/gmp/6.1.2_2/include -L/usr/local/Cellar/gmp/6.1.2_2/lib -lgmp

出ますね。よし。

古いgccのビルドが失敗する

上にも関連した問題です。

configureでgmp.hが見つからないと言われる

なんか見つかりません。実際に手動で gcc を実行しても知らんと言われます。

#include <gmp.h>

int main(void) {

}
$ gcc a.c
a.c:1:10: fatal error: gmp.h: No such file or directory
    1 | #include "gmp.h"
      |          ^~~~~~~
compilation terminated.

ですが、gcc の引数に pkg-config の出力を加えてやればコンパイルは成功します。

$ gcc $(pkg-config --cflags --libs gmp) a.c
$

ですので、../configure する際に、CFLAGS= としてデフォルトのフラグを追加してしまえばいいわけです。

gcc-9はバグっているらしい

ソース元 URL は紛失してしまいましたが、どうやら gcc-9 で他の gcc をビルドするとバグでエラーが出るらしいです。
実際、僕も gcc4 系をビルドする時に、gcc 内部で定義されている構造体関連でエラーが出てしまいました。そこで、gcc-8 系を用いたところそのエラーは消え去りました。皆さん、gcc-8 を使いましょう。

以上をまとめて

古い gcc をビルドする時は、こんな感じで configure すればいいわけです。

$ CC=gcc-8 CXX=g++-8 CFLAGS="$(pkg-config --libs --cflags gmp mpfr)" ../configure --prefix=/usr/local/cross/avr32 --target=avr32 --disable-werror --disable-nls --disable-bootstrap --enable-newlib --disable-libssp --enable-languages=c