8

私は数学関数を使用するコードを作成しようとしています(例pow)。

math.hが含まれ、フラグ-lmはビルド中に使用されます。

このようにコンパイルが呼び出されると(-lmコマンドの先頭にあるフラグ)、:への未定義の参照があると言って失敗しましたpow

gcc -lm -O3 main.o clustering.o grassberger.o hash.o list.o mat.o metropolis.o motif_ids.o output.o permutation.o prob.o random.o results.o role.o stubs.o switches.o -o mfinder
main.o: In function `get_sn_motif_id':
main.c:(.text+0x28d): undefined reference to `pow'

そして、-lm旗がコマンドの終わりに置かれるとき、それは働きます!

gcc -O3 main.o clustering.o grassberger.o hash.o list.o mat.o metropolis.o motif_ids.o output.o permutation.o prob.o random.o results.o role.o stubs.o switches.o -o mfinder -lm

これは正常ですか?

4

2 に答える 2

18

はい、正常です。多くのリンカでは、オブジェクトファイルとライブラリを指定する順序が重要です。

「GCCの紹介-GNUコンパイラgccおよびg++用」を引用するには:

リンカの従来の動作は、コマンドラインで指定されたライブラリで左から右に外部関数を検索することです。つまり、関数の定義を含むライブラリは、それを使用するソースファイルまたはオブジェクトファイルの後に表示される必要があります。-lこれには、次のコマンドに示すように、ショートカットオプションで指定されたライブラリが含まれます。

$ gcc -Wall calc.c -lm -o calc (correct order)

この動作は一般的ですが、決して普遍的ではありません。疑わしい場合は、リンカーのマニュアルを参照することをお勧めします。たとえば、私のUbuntuシステムでは次のman ldように述べています。

   -l namespec
   --library=namespec

       ...

       The linker will search an archive only once, at the location where
       it is specified on the command line.  If the archive defines a
       symbol which was undefined in some object which appeared before the
       archive on the command line, the linker will include the
       appropriate file(s) from the archive.  However, an undefined symbol
       in an object appearing later on the command line will not cause the
       linker to search the archive again.

言い換えると、このリンカーはgcc本に記載されている方法で動作します。

于 2012-01-25T08:59:53.903 に答える
4

GCCの概要で述べたように-GNUコンパイラgccおよびg++の場合

リンカの従来の動作は、コマンドラインで指定されたライブラリで左から右に外部関数を検索することです。つまり、関数の定義を含むライブラリは、それを使用するソースファイルまたはオブジェクトファイルの後に表示される必要があります。

私はあなたが同じ振る舞いを見ていると思います。

さらに、次のように述べていることに注意してください。

最新のリンカのほとんどは、順序に関係なくすべてのライブラリを検索しますが、ライブラリを左から右に並べる規則に従うのが最善です。

于 2012-01-25T09:01:21.563 に答える