80

LinuxOSは初めてです。.cmakefileを使用してファイルをコンパイルしようとしています。数学ライブラリをリンクする必要があります。私のmakefileは次のようになります:

CC=gcc
CFLAGS=-Wall -lm

all:client

.PHONY: clean
clean:
    rm *~ *.o client

を実行するmakeと、次のエラーが発生します。

"undefined reference to rint"

そのため、数学ライブラリをリンクすることはできません。

しかし、私が明示的に使用してコンパイルするとき

gcc client.c -lm -o client

正常にコンパイルされます。

では、makefileをどのように変更して機能するようにする必要がありますか。すでに追加してみましLDFLAGS=-lmた。しかし、同じエラーが発生します。

また、実行するmakeと、次のように展開されます。

gcc -Wall -lm client.c -o client

gcc(最後に明示的に実行すると、機能することに注意して-lmください)。

4

3 に答える 3

71

リンカ(ld)は、makeがGCC引数を配置する順序を明らかに好まないため、Makefileを少し変更する必要があります。

CC=gcc
CFLAGS=-Wall
LDFLAGS=-lm

.PHONY: all
all: client

.PHONY: clean
clean:
    $(RM) *~ *.o client

OBJECTS=client.o
client: $(OBJECTS)
    $(CC) $(CFLAGS) $(OBJECTS) -o client $(LDFLAGS)

クライアントターゲットを定義する行で、必要に応じて順序を変更$(LDFLAGS)します。

于 2012-11-06T11:29:45.887 に答える
55

より複雑なビルドシナリオでは、コンパイルとアセンブリを最初に実行し(オブジェクトファイルに出力)、後でオブジェクトファイルを最終的な実行可能ファイルまたはライブラリにリンクすることで、コンパイルを段階に分割するのが一般的です。これにより、次の場合にすべてのオブジェクトファイルを再コンパイルする必要がなくなります。それらのソースファイルは変更されていません。そのため、リンクフラグを挿入しても、リンクフラグを含めること-lmができませんCFLAGSCFLAGSコンパイル段階で使用されます)。

リンクするライブラリの規則は、ライブラリをいずれかに配置することですLOADLIBESLDLIBSGNU makeには両方が含まれますが、マイレージは異なる場合があります)。

LDLIBS=-lm

これにより、独自のリンクルールを作成するのではなく、組み込みのルールを引き続き使用できるようになります。他のmakeの場合、組み込みルールを出力するフラグが必要です(GNU makeの場合、これはです-p)。お使いのバージョンのmakeにリンク用の組み込みルールがない場合(または-lディレクティブのプレースホルダーがない場合)、独自のルールを作成する必要があります。

client.o: client.c
    $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $@ $<

client: client.o
    $(CC) $(LDFLAGS) $(TARGET_ARCH) $^ $(LOADLIBES) $(LDLIBS) -o $@
于 2012-11-06T15:01:02.370 に答える
0

リンクフラグの順序は、古いバージョンのgccでは問題ではなかったようです。たとえばgcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-16)、入力ファイルの前にリンカーオプションを備えたCentos-6.7が付属しています。しかし、ubuntu16.04のgccgcc (Ubuntu 5.3.1-14ubuntu2.1) 5.3.1 20160413は許可していません。

それはgccバージョンだけではなく、ディストリビューションと何か関係があります

于 2016-08-10T04:07:09.703 に答える