Linux OSは初めてです。メイクファイルを使用して.c
ファイルをコンパイルしようとしています。数学ライブラリをリンクする必要があります。私のメイクファイルは次のようになります。
CC=gcc
CFLAGS=-Wall -lm
all:client
.PHONY: clean
clean:
rm *~ *.o client
make
を実行すると、次のエラーが表示されます。
"undefined reference to rint"
そのため、数学ライブラリをリンクできません。
しかし、私が明示的にコンパイルすると
gcc client.c -lm -o client
正常にコンパイルされます。
だから、どのようにそれが動作するように私のメイクファイルを変更する必要があります。私はすでにLDFLAGS=-lm
を追加しようとしました。しかし、私は同じエラーを受け取ります。
make
を実行すると、次のように展開されることも追加する必要があります。
gcc -Wall -lm client.c -o client
(最後に-lm
を指定してgcc
を明示的に実行すると動作することに注意してください)。
リンカ(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)
clientターゲットを定義する行で、必要に応じて$(LDFLAGS)の順序を変更します。
より複雑なビルドシナリオでは、コンパイルを段階的に分割し、コンパイルとアセンブリを最初に(オブジェクトファイルへの出力)、オブジェクトファイルを最終的な実行可能ファイルまたはライブラリにリンクします。これにより、すべてのオブジェクトファイルを再コンパイルする必要がなくなります。ソースファイルは変更されていません。 CFLAGS
(コンパイル段階でCFLAGS
が使用されます)に配置するときに、リンクフラグ-lm
を含めることは機能しません。
ライブラリをリンクするための規則は、それらをLOADLIBES
またはLDLIBS
のいずれかに配置することです(GNU 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 $@
リンクフラグの順序は、gccの古いバージョンでは問題ではなかったようです。たとえば、gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-16)
にはCentos-6.7が付属しており、入力ファイルの前にリンカーオプションを追加できます。ただし、ubuntu 16.04のgcc gcc (Ubuntu 5.3.1-14ubuntu2.1) 5.3.1 20160413
は許可されません。
Gccバージョンだけではなく、ディストリビューションと何か関係がある