わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

cc -lmではコンパイルできない?

いきなりですが問題です.以下のプログラムを,どんなコマンドでコンパイルすればいいですか.

/* sincos.c */
#include <stdio.h>
#include <math.h>

int main(void)
{
  int i;

  for (i = 0; i <= 24; i++) {
    double x = M_PI / 180 * i * 15;
    printf("%f,%f\n", sin(x), cos(x));
  }

  return 0;
}

前の木曜の授業です*1.問題用紙に,「cc -lm -o sincos sincos.cを実行して,実行ファイルsincosを作りなさい」と書いておきました.数学関数を用いたソースファイルをコンパイルする際には,-lmオプションをつける必要があります.
なのですが,リンクエラーが続出でした.ああ,-lmオプションを忘れたんだな,問題文をよく読んでね,と指示しようとしたら,きちんとオプションを与えてあって,それでも,リンクエラーが発生していたのでした.
自分でも確認してみるかと,教卓PCに向かう途中で立ち止まり,全体にアナウンスしてみました.
「みなさんの中で,sincos.cのコンパイルに成功した人は,いますか?」
すると一人から手が挙がりました.その学生のところに行き,端末を見せてもらうと,プロンプトに続いて,「cc -o sincos sincos.c -lm」というコマンドが,画面の真ん中にありました.
「-lm」は後ろに……
「コマンド名,(マイナスから始まる)オプション群,処理対象のファイル群」というUNIXの慣例に反した指定に,びっくりしましたが,動くのであればそれを優先すべきですので,再びアナウンスをしました.部屋の前後のホワイトボードに訂正を書き,ふたたび巡回すると,コンパイルそして実行のできた画面ばかりとなりました.


授業の部屋の計算機環境は,この春からLinux Mintになりました*2Ubuntu 14.04のGCC*3でもまた,「cc -lm ...」で失敗し,「cc ... -lm」で成功しました.
といったところで調査…見つかりました.

(2012-06-06 23:24:08,vbk)
Ubuntu 11.04以降、リンク時に--as-neededオプションがデフォルトで有効化されているため、リンクオプションを適切な位置に入れないとエラーが発生します。
https://lists.ubuntu.com/archives/ubuntu-devel/2010-November/031991.html
gcc に -Wl,--no-as-needed を付加することで、エラーを回避できます。
一応 Ubuntugcc-4.4 及び、Debiangcc-4.6,4.7 で確認しましたが、同様の現象は発生しませんでした。

3年前から,そうなっていたとは!
いろいろ試したところ,「cc -Wl,--no-as-needed -lm -o sincos sincos.c」とする必要がありました.でもそこまでして,-lmオプションを前に置きたいとは思いません…….

*1:ただし,ファイル名・ソースファイルとも,授業で使用したものとは異なります.

*2:昨年度まではVine Linuxでした.

*3:cc --versionを実行すると,最初に「cc (Ubuntu 4.8.2-19ubuntu1) 4.8.2」と出力されました.gcc --versionだと,「gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2」です.ccとgcc,実体は同じです.