"linker input file unused because linking not done"是什么意思?(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

您的链接命令扩展为:

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不要进行链接。所以它实际上没有任何作用。(.o文件只能用于链接,而您已经禁用了链接,这就是为什么您会收到该消息)

您不希望在编译和链接时使用相同的标志。对于编译,您可能需要-c -std=c99 -Wall -Wextra -pedantic -O3 -Wfloat-equal -g,而对于链接,您需要-lm -lSDL2 -lSDL2_ttf -lSDL2_image -lSDL2_mixer -g

发布的makefile中有几个小疏忽。

其中:

  1. 库名称仅在链接步骤中使用,而不是在编译步骤中使用
  2. 建议使用通配符make运算符来获取源文件的列表。然后使用pattern替换操作符来获取对象文件的列表:

例如:

SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
  1. 当目标(all,clean)不会生成相同名称的文件时,请在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. 编译器和链接器的CCD_ 9参数允许使用调试器。如果调试器是gdb,那么更好的参数是-ggdb

  2. 几乎总是,不需要对宏定义进行多次评估,因此与其在宏定义中使用=,不如使用:=

  3. 如果您希望game是可执行的,那么在"链接"规则中插入一个chmod命令作为最后一行

建议阅读makefile中可以使用的特殊运算符,以帮助您理解以下建议的makefile

通常最好用宏替换对shell识别命令的调用。

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

不要将-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时)不应指定。

最新更新