いきなりですが問題です.以下のプログラムを,どんなコマンドでコンパイルすればいいですか.
/* 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になりました*2.Ubuntu 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 を付加することで、エラーを回避できます。
一応 Ubuntu の gcc-4.4 及び、Debian の gcc-4.6,4.7 で確認しましたが、同様の現象は発生しませんでした。
3年前から,そうなっていたとは!
いろいろ試したところ,「cc -Wl,--no-as-needed -lm -o sincos sincos.c」とする必要がありました.でもそこまでして,-lmオプションを前に置きたいとは思いません…….