他人が作ったプログラムを、標準ライブラリ関数を使わないようにしてコンパイルしたいと思っています。

そこで、MakefileのLDFLAGSやCFLAGSに-nostdlibオプションや-fno-builtinオプションを設定してコンパイルしようとしたのですが、
なぜか起きるはずの(ソースを見ると確実に標準ライブラリ関数があるので)リンクエラーが発生しません。
どうやら、通常通りライブラリへのリンクが行われているようです。
おそらく、なんらかの設定でオプションが上書きされ無効化されているのだとは思うのですが、原因がわかりません。
どなたか原因と考えられるものがありましたら教えてください。
コンパイラはgcc、OSはUbuntuを使っています。
Makefileはautoconfを利用して作成しました。
よろしくお願いします。

回答の条件
  • URL必須
  • 1人3回まで
  • 登録:2009/06/30 13:47:15
  • 終了:2009/07/03 17:09:05

ベストアンサー

id:kenichiice No.3

kenichiice回答回数48ベストアンサー獲得回数72009/07/02 01:10:35

ポイント40pt

gcc -g -O2 -nostdlib -fno-builtin -I. -I.. -c (ファイル名)

となっているので、オプションが渡されていないという事はないはずです。

とのことですが、2番目の回答にある通り、-c オプションが指定されているのでこの処理ではリンク処理は行われません。

-nostdlib はリンカオプションなので、リンク時に指定しないと意味がありません。コンパイル時にリンカオプションが使われている所を見ると、やはりMakefileが少しおかしいように思います。

いずれにせよ、そのMakefileでリンク処理も行っているだろうと思うので、その部分(-c を指定せずgccを呼び出している所)で gcc にどのようなオプションが渡されているかを確認するといいと思います。

また、もしかするとリンク処理にはgccではなくリンカを直接起動しているのかもしれません。その場合は -nostdlib オプションは意味がなくなってしまうと思います。

(URLは思いつかなかったので、GCCのマニュアルのURLを書いておきます。)

http://gcc.gnu.org/onlinedocs/gcc-4.4.0/gcc/Option-Index.html#Op...

id:takiaki-ouka

Makefileを精査したところ、どうやらCFLAGSやLDFLAGS等のオプションをどれでも利用しているようでした。

お教えいただいた通り、-cを呼び出さずにgccを呼び出している所のオプションを確認し、

そこで指定されていた-ldl等のオプションを省いてmakeしたところ、エラーを出すことができました。

ありがとうございました。

2009/07/03 17:02:25

その他の回答(2件)

id:hijk05 No.1

hijk05回答回数1307ベストアンサー獲得回数232009/06/30 20:22:52

標準ライブラリ関数を使わないでコンパイルすることはできません。

id:takiaki-ouka

gccのオプションで、-nostdlibをつけると標準システムスタートアップファイルや標準システムライブラリを使用しないでコンパイルできるはずなので、それを指定すればできると思うのですが。

また、makeした時の出力は、

gcc -g -O2 -nostdlib -fno-builtin -I. -I.. -c (ファイル名)

となっているので、オプションが渡されていないという事はないはずです。それでもエラーは出ていません。

2009/07/01 18:41:45
id:longicorn No.2

longicorn回答回数56ベストアンサー獲得回数62009/07/01 19:51:08

ポイント40pt

-cをつけているからじゃないかな?


a.c

#include <stdio.h>

int main(){
        printf("aaaa\n");
        return 0;
}

$ ls
a.c a.o

-cをつけないと…

$ gcc -nostdlib -fno-builtin a.c
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000008048074
/tmp/cca0UEWq.o: In function `main':
a.c:(.text+0x19): undefined reference to `printf'
collect2: ld はステータス 1 で終了しました

この辺の話を理解するには、「そもそもコンパイラは何をしているか?」の理解が必要です。

キーワードとしてはプリプロセッサ、字句解析、構文解析、コンパイル、リンクとかです。

例えばこんな内容です。

http://www.mi.s.osakafu-u.ac.jp/~kada/course-kitami/j3_02/guide0...


今回の問題は、コンパイルだけしてリンクを行わなかったのでエラーがでなかってのではないかと。

それに対して自分の例では、コンパイルを行い、リンク時に始めて標準システムライブラリを見に行き、そこで始めて関数(自分の例だとprintf)が無いと始めて気づいたのでエラーが出たと言う話です。

id:takiaki-ouka

確かに-cオプションを消すとエラーが出ました。

ただ、今回は大量の.cのソースファイルを.oファイルにコンパイルし、それを一括で書庫ファイルにした後、

最後にmain.cをコンパイルした.oファイルと一緒にその書庫ファイルをコンパイルしているようでした。

なので、1つ1つのファイルのコンパイル時に-cオプションをとってしまうと、1つ目のファイルでエラーが出て止まってしまうため、他に方法はないか? と探していました。

結局、最後のmain.cのコンパイル時の-ldl等のオプションを省くことでエラーを出す事ができました。

ですが、今回の事でMakefileやgcc、コンパイラについての知識不足を痛感する事ができ、勉強になりました。

ありがとうございました。

2009/07/03 16:57:30
id:kenichiice No.3

kenichiice回答回数48ベストアンサー獲得回数72009/07/02 01:10:35ここでベストアンサー

ポイント40pt

gcc -g -O2 -nostdlib -fno-builtin -I. -I.. -c (ファイル名)

となっているので、オプションが渡されていないという事はないはずです。

とのことですが、2番目の回答にある通り、-c オプションが指定されているのでこの処理ではリンク処理は行われません。

-nostdlib はリンカオプションなので、リンク時に指定しないと意味がありません。コンパイル時にリンカオプションが使われている所を見ると、やはりMakefileが少しおかしいように思います。

いずれにせよ、そのMakefileでリンク処理も行っているだろうと思うので、その部分(-c を指定せずgccを呼び出している所)で gcc にどのようなオプションが渡されているかを確認するといいと思います。

また、もしかするとリンク処理にはgccではなくリンカを直接起動しているのかもしれません。その場合は -nostdlib オプションは意味がなくなってしまうと思います。

(URLは思いつかなかったので、GCCのマニュアルのURLを書いておきます。)

http://gcc.gnu.org/onlinedocs/gcc-4.4.0/gcc/Option-Index.html#Op...

id:takiaki-ouka

Makefileを精査したところ、どうやらCFLAGSやLDFLAGS等のオプションをどれでも利用しているようでした。

お教えいただいた通り、-cを呼び出さずにgccを呼び出している所のオプションを確認し、

そこで指定されていた-ldl等のオプションを省いてmakeしたところ、エラーを出すことができました。

ありがとうございました。

2009/07/03 17:02:25
  • id:kenichiice
    原因は分かりませんが、例えば、Makefileに間違いがあってLDFLAGSに指定した値が使われていないといった可能性があるのではないでしょうか。

    make コマンドの出力を見て、gcc にどのようなオプションが渡されているのかを確認すると何か分かるのではないでしょうか。

  • id:longicorn
    ちょっと補足です。

    lsの前に、 「gcc -nostdlib -fno-builtin -c a.c」コマンドを実行するを書くのを忘れていました。
    分かり辛かったかったかもしれません。申し訳有りません。


    ついでに、 gccの内部動作を解説している本を紹介しておきます。
    西田亙氏の「GNU 開発ツール」です。
    http://www.oversea-pub.com/books/gnudevjp/about.htm

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません