12 MacPorts での boost (たくさんのバージョンがあるけど、どう選ぶ)

意外に長くなったので1行のまとめ: MacPorts には C++のクラスライブラリィ Boost の色々なバージョンが含まれているが、バージョンを選びたければ -I-L でディレクトリィを指定せよ。

C++で Boost を使っているのだが、最近 「sprintf() はよせ、snprintf() を…」 という警告がうるさく出るようになった。 まあ、理解できる主張だ。

警告だからコンパイル自体はできるし、ほっておいても良いかもしれないが、 ノイズがあると、作業効率(重要なエラーメッセージが探しにくい) とか作業品質(うっかり見落とす)が低下するので、 直したい、と考えた。


Boost の方でそういうの直していないのかな? と思って調べてみたら、実は MacPorts で普通に boost をインストールすると、 結構古いのが使われるようになっているんだ。
% port search boost|grep '^boost'|grep -v numpy
boost @1.76 (devel)
boost-build @2.0-m12_2 (devel)
boost-jam @3.1.18 (devel)
boost169 @1.69.0_11 (devel)
boost171 @1.71.0_10 (devel)
boost176 @1.76.0_13 (devel)
boost178 @1.78.0_10 (devel)
boost181 @1.81.0_13 (devel)
boost187 @1.87.0_1 (devel)
つまり、MacPorts に boost169, boost171, boost176, boost178, boost181, boost187 があると。 単に sudo port install boost としてインストールされるものは、 boost176 である。

Boost のWWWサイト を見に行ったら、 最新版は1.88 みたいで、その1つ前の 1.87 が ports に入っているということだ。

あまり深く考えずに
sudo port install boost187
とした。
% port installed|grep boost
  boost @1.76_0 (active)
  boost176 @1.76.0_10+no_single+no_static+python312
  boost176 @1.76.0_11+no_single+no_static+python312
  boost176 @1.76.0_12+no_single+no_static+python312
  boost176 @1.76.0_13+no_single+no_static+python312
  boost176 @1.76.0_14+no_single+no_static (active)
  boost181 @1.81.0_9+no_single+no_static+python311
  boost181 @1.81.0_10+no_single+no_static+python312
  boost181 @1.81.0_11+no_single+no_static+python312
  boost181 @1.81.0_12+no_single+no_static+python312
  boost181 @1.81.0_13+no_single+no_static+python313 (active)
  boost187 @1.87.0_1+no_single+no_static+python313 (active)
  poppler @24.03.0_0+boost
  poppler @24.04.0_1+boost (active)
うわっ。自分でインストールした覚えがあるのは boost (boost176), boost187 だけど、それ以外にもたくさんインストールされていて (ゾッとした…これらは Python がらみなのかな、そのうち整理しないと)、 active になっているのも自分でインストールしたもの以外に他に2つある。

これは知らなかった。 そうすると、 普段自分のプログラムで利用している /opt/local/include/boost の正体は何?
% ls -l /opt/local/include/boost
lrwxr-xr-x  1 root  admin  43  2 24 02:08 /opt/local/include/boost@ -> /opt/local/libexec/boost/1.76/include/boost
つまり /opt/local/libexec/boost/1.76/include/boost へのシンボリック・リンクであると。

ライブラリィの方はどうだろう?
% ls -l /opt/local/lib | grep boost
たくさんのシンボリック・リンクがはられている。どこにはってあるのか?
ls % ls -l /opt/local/lib|grep  boost|wc
      42     462    6252
% ls -l /opt/local/lib|grep  boost|grep /opt/local/libexec/boost/1.76/lib|wc
      42     462    6252
% ls -l /opt/local/libexec/boost/1.76/lib|wc
      41     362    3110
それらは全て /opt/local/libexec/boost/1.76/lib にあるファイルへの シンボリック・リンクであると。

数が合わないな (42 vs 41)。調べたところ、 存在しないファイルへのシンボリック・リンクが3つあって、 それらのファイル名には python3 という文字列が入っていた。

細かい事情は分からないけれど、Boost 自体は /opt/local/libexec/boost/バージョン/{include,lib,share} にインストールされていて、 /opt/local/include/boost/opt/local/lib/*boost* は、version 1.76 のファイル群へのシンボリック・リンクであると。

なるほど。では boost187 (version 1.87) が使いたければ
g++ -I/opt/local/libexec/boost/1.87/include -L/opt/local/libexec/boost/1.87/lib
とすればいいのかな。

警告がどっさり出たプログラムを再コンパイルしてみる。
g++ -I /opt/local/libexec/boost/1.87/include testcomp.cpp
見事に警告が消えた。

gcc とかだと、どの port を使うか、選べるのだけど。
% port select --list gcc
	mp-gcc13
	mp-gcc14 (active)
	none
こうして表示されたもののうち、どれを active にするかは
sudo port select --set gcc mp-gcc14
のようにして選択する。

boost については、port select はできないようだった。

まあ、プログラムのコンパイルはどうせ Makefile を使うし、 そこに
CXXFLAGS	=	-O -I /opt/local/libexec/boost/1.87/include
や、ライブラリィのありかを書くだけのことだから、そんなに面倒ではない。 むしろ、どのバージョンの boost を使うのか明記してある方が良いはずだ。



桂田 祐史