FreeBSD QandA 1609

FreeBSD QandA

Q. C のソースをコンパイルすると、
      ... undefined reference to `sin'
      ... undefined reference to `XOpenDisplay'
   などというエラーになります。

A. コンパイルは成功し、オブジェクトファイル (*.o) が生成されましたが、
   リンク時に sin・XOpenDisplay という関数が見付からなかったという
   エラーです。

   /usr/lib/ や /usr/X11R6/lib、/usr/local/lib/ には lib*.so.* や
   lib*.a というファイルがあります。これらはライブラリと言い、
   コンパイル済の関数群が入っています。

   sin は /usr/lib/libm.so.* に、XOpenDisplay は /usr/X11R6/lib/libX11.so.*
   に含まれていますので、この場所を教えてやればいいのです。


   例えば、sin が見付からないなら
     % cc foo.c -lm
   とします。XOpenDisplay が見付からないなら
     % cc foo.c -lX11 -L /usr/X11R6/lib
   とします。

   -lm というのは、リンカ (/usr/bin/ld) に
     「libm.so.* というライブラリを探しなさい」
   というオプションです。

   同様に -lX11 というのも
     「libX11.so.* というライブラリを探しなさい」
   という意味なのですが、ld はデフォルトでは、/usr/lib からしか
   ライブラリを探しません。そのため、/usr/X11R6/lib や /usr/local/lib
   のライブラリを使う場合は、-L /usr/X11R6/lib などとライブラリの
   置いてある場所を指定しなければなりません。


   ただし、X のプログラムの場合は、インクルードファイルの場所を指定
   しなければいけないので、最終的には、
     % cc foo.c -I /usr/X11R6/include -lX11 -L /usr/X11R6/lib
   などと -I オプションも指定しなければいけないでしょう。ですから、
   Makefile や autoconf などを利用する方が楽です。→[管理番号 509]

   なお、どのライブラリにどの関数が含まれているかを調べるには、
   まずマニュアルを見ましょう。man sin の SEE ALSO に math(3) と
   ありますので、man math を見ると、
     These  functions constitute the C math library, libm.
   とありますので、libm に含まれていることがわかります。

   マニュアルから読み取れなかったら、
     % nm -o /usr/lib/*.so.* /usr/X11R6/lib/*.so.* | grep ' T sin$'
     /usr/lib/libm.so.2:0000b3d8 T sin
     % nm -o /usr/lib/*.so.* /usr/X11R6/lib/*.so.* | grep ' T XOpenDisplay$'
     /usr/X11R6/lib/libX11.so.6:00020adc T XOpenDisplay
   とすればわかります。libm.so.2 なら -lm だし、libX11.so.6 なら
   -lX11 ですね。

間違い・追加情報を見付けた場合は、 修正案の投稿のしかた を読んだ上で、
QandA@jp.FreeBSD.org まで お知らせください。