web-dev-qa-db-ja.com

「リンカが行われていないために未使用のリンカ入力ファイル」とはどういう意味ですか? (C makefile)

プログラムをコンパイルしてリンクするメイクファイルを作成しましたが、このエラーが発生する理由がわかりません。それはSDLと関係がありますか?

GCC = gcc
CFLAGS = -c -std=c99 -lm -Wall -Wextra -pedantic -O3 -Wfloat-equal -g
SDL = -lSDL2 -lSDL2_ttf -lSDL2_image -lSDL2_mixer

all: ./game

game: global.o display.o player.o entities.o controls.o sound.o menu.o
    $(GCC) $(CFLAGS) global.o display.o player.o entities.o controls.o sound.o menu.o -o game

global.o: global.c
    $(GCC) $(CFLAGS) $(SDL) global.c

display.o: display.c
    $(GCC) $(CFLAGS) $(SDL) display.c

player.o: player.c
    $(GCC) $(CFLAGS) $(SDL) player.c

entities.o: entities.c
    $(GCC) $(CFLAGS) $(SDL) entities.c

controls.o: controls.c
    $(GCC) $(CFLAGS) $(SDL) controls.c

sound.o: sound.c
    $(GCC) $(CFLAGS) $(SDL) sound.c

menu.o: menu.c
    $(GCC) $(CFLAGS) $(SDL) menu.c

clean:
    rm *o game
6
liamw9

投稿されたmakefileにはいくつかの小さな見落としがあります。

それらの中で:

  1. ライブラリ名は、リンク手順でのみ使用され、コンパイル手順では使用されません。
  2. ソースファイルのリストを取得するには、 'wildcard' make演算子を使用することをお勧めします。次に、patterm置換演算子を使用して、オブジェクトファイルのリストを取得します。

例えば:

SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
  1. ターゲット(すべて、クリーン)が同じ名前のファイルを生成しない場合は、makeファイルの初期に.PHONY:ステートメントを挿入します。

同様に:

.PHONY : all clean
  1. 投稿されたmakeファイルには、関連するヘッダーファイルを処理する機能がありません。これを処理する方法はいくつかあります。これはOPリードに従い、ヘッダーファイルを処理しないため、ヘッダーファイルを変更しても、影響を受けるソースファイルは再コンパイルまたは再リンクされません。

  2. この行:rm *o gameは '。'がないため、name.oファイルを削除しません。ルート名と「o」拡張子の間。また、「-f」フラグは「rm」コマンドで使用する必要があります。

提案:

rm -f *.o game 
  1. この行:all: ./gameは問題を引き起こす可能性があります

提案:

all: game
  1. (上記のように)オブジェクトファイルのリストが作成されたら、コンパイルルールを減らすことができます。

make演算子を使用する:

%.o: %.c
    $(CC) $(CFLAGS) -c $< -o $@ -I.
  1. コンパイラとリンカへの-gパラメータにより、デバッガを使用できます。そのデバッガーがgdbの場合、より適切なパラメーターは-ggdbです。

  2. ほとんどの場合、マクロ定義を複数回評価する必要はありません。そのため、マクロ定義で=を使用する代わりに、:=を使用してください。

  3. gameを実行可能にする場合は、「リンク」ルールの最後の行としてchmodコマンドを挿入します

makefileで使用できる特殊な演算子について読んで、以下の推奨されるメイクファイルの理解に役立ててください。

通常、シェルが認識したコマンドの呼び出しをマクロに置き換えるのが最善です。

CC := /user/bin/gcc
RM := /usr/bin/rm

CFLAGS := -c -std=c99 -Wall -Wextra -pedantic -O3 -Wfloat-equal -ggdb
LFLAGS := -std=c99 -O3 -ggdb

SDL := -lSDL2 -lSDL2_ttf -lSDL2_image -lSDL2_mixer

SRC := $(wildcard *.c)
OBJS := $(SRC:.c=.o)


.PHONY : all clean
all: game


game: $(OBJS)
    $(CC) $(LFLAGS)  $(OBJS) -o $@ $(SDL) -lm

%.o: %.c
    $(CC) $(CFLAGS) -c $< -o $@ -I.


clean:
    $(RM) -f *.o game
4
user3629249

リンクコマンドは次のように展開されます。

gcc -c -std=c99 -lm -Wall -Wextra -pedantic -O3 -Wfloat-equal -g global.o display.o player.o entities.o controls.o sound.o menu.o -o game

ご覧のとおり、-cフラグ。 -cフラグは、gcc notにリンクを行うように指示します。したがって、実際には何もする必要はありません。 (.oファイルはリンクにのみ使用でき、リンクを無効にしているため、そのメッセージが表示されます)

コンパイルとリンクに同じフラグを使用したくない場合。コンパイルするには、おそらく-c -std=c99 -Wall -Wextra -pedantic -O3 -Wfloat-equal -g、リンクには-lm -lSDL2 -lSDL2_ttf -lSDL2_image -lSDL2_mixer -g

7
user253751

おかないで -lmまたはSDLライブラリからCFLAGSへ、ライブラリオペランドはコマンドラインの最後に移動します。代わりに、追加の変数LDLIBSを使用して、gameルールを次のように変更します。

game: global.o display.o player.o entities.o controls.o sound.o menu.o
    $(GCC) $(CFLAGS) -o $@ global.o display.o player.o entities.o controls.o sound.o menu.o $(LDLIBS)

-lmオペランド(これはオプションではありません)およびSDLのオペランドはリンク時にのみ適用されるため、CFLAGSの一部であってはならず、リンクなしでコンパイルする場合(つまり、-cが提供されます)。

0
fuz