C语言 “链接器输入文件未使用,因为链接未完成”是什么意思?(C 生成文件)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34426362/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 12:16:44  来源:igfitidea点击:

What does "linker input file unused because linking not done" mean? (C makefile)

ccompilationmakefilelinker

提问by liamw9

I have created a makefile to compile and link my program, however, I can't figure out why I am getting this error. Is it to do with SDL?

我创建了一个 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

采纳答案by user3629249

there are several small oversights in the posted makefile.

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

Amongst them:

其中:

  1. library names are only used during the link step, not the compile step
  2. suggest using the 'wildcard' make operator to get a list of the source files. Then use a patterm replacement operator to get a list of the object files:
  1. 库名称仅在链接步骤中使用,而不是在编译步骤中使用
  2. 建议使用“通配符”make 运算符来获取源文件列表。然后使用模式替换运算符获取目标文件列表:

for instance:

例如:

SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
  1. when a target (all, clean) will not produce a file of the same name, then insert a .PHONY:statement early in the make file:
  1. 当目标(all,clean)不会产生同名文件时,则.PHONY:在 make 文件的早期插入一条语句:

similarly to:

类似于:

.PHONY : all clean
  1. the posted make file has no facilities to handle the associated header files, There are several ways to handle that. This follows the OPs lead and does not handle the header files, so changing a header file will not recompile/relink the effected source files.

  2. this line: rm *o gamewill not remove the name.o files as it is missing the '.' between the root name and the 'o' extension. Also, the '-f' flag should be used with the 'rm' command.

  1. 发布的 make 文件没有处理相关头文件的功能,有几种方法可以处理。这遵循 OP 的指导,不处理头文件,因此更改头文件不会重新编译/重新链接受影响的源文件。

  2. 这一行:rm *o game不会删除 name.o 文件,因为它缺少“。” 根名称和“o”扩展名之间。此外,'-f' 标志应该与 'rm' 命令一起使用。

suggest:

建议:

rm -f *.o game 
  1. this line: all: ./gamecan create problems
  1. 这一行:all: ./game可能会产生问题

suggest:

建议:

all: game
  1. once the list of object files is created (as above) then the compile rules can be reduced:
  1. 一旦创建了目标文件列表(如上),则可以减少编译规则:

by using the make operators:

通过使用 make 运算符:

%.o: %.c
    $(CC) $(CFLAGS) -c $< -o $@ -I.
  1. the -gparameter to the compiler and linker allows for a debugger to be used. If that debugger is gdbthen a better parameter is -ggdb

  2. almost always, there is no need to evaluate a macro definition more than once, so rather than using =in a macro definition, use :=

  3. If you want the gameto be executable, then insert a chmodcommand as the last line in the 'link' rule

  1. -g编译器和链接器的参数允许使用调试器。如果那个调试器是gdb那么更好的参数是-ggdb

  2. 几乎总是,不需要多次评估宏定义,因此不要=在宏定义中使用,而是使用:=

  3. 如果您希望它game是可执行的,则chmod在“链接”规则的最后一行插入一个命令

Suggest reading about the special operators that can be employed in a makefileto help you understand the following, suggested makefile

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

It is usually best to replace calls to the shell recognized commands with macros.

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

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

回答by user253751

Your linking command expands to:

您的链接命令扩展为:

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

which, as you can see, has the -cflag in it. The -cflag tells gcc notto do linking. So it has nothing to actually do. (.ofiles can only be used for linking, and you've disabled linking, which is why you get that message)

如您所见,其中包含-c标志。该-c标志告诉 gcc不要进行链接。所以它实际上没有什么可做的。(.o文件只能用于链接,并且您已禁用链接,这就是您收到该消息的原因)

You don't want to use the same flags for compiling and linking. For compiling you probably want -c -std=c99 -Wall -Wextra -pedantic -O3 -Wfloat-equal -g, and for linking you want -lm -lSDL2 -lSDL2_ttf -lSDL2_image -lSDL2_mixer -g.

您不想使用相同的标志进行编译和链接。用于您可能想要的编译-c -std=c99 -Wall -Wextra -pedantic -O3 -Wfloat-equal -g,以及您想要的链接-lm -lSDL2 -lSDL2_ttf -lSDL2_image -lSDL2_mixer -g

回答by fuz

Do not put -lmor the SDL libraries into CFLAGS, library operands go to the end of the command line. Instead, use an extra variable LDLIBSand modify your gamerule like this:

不要将-lm或 SDL 库放入CFLAGS,库操作数到命令行的末尾。相反,使用一个额外的变量LDLIBSgame像这样修改你的规则:

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)

The -lmoperand (it's not an option) and the operands for SDL only apply when linking, thus it should not be part of CFLAGSand should not be specified when compiling without linking (i.e. when -cis supplied).

-lm仅连接时,适用的操作数(这不是一个选项)和SDL操作数,因此它不应该成为其中的一部分CFLAGS,并没有连接编译时不应该被指定(即当-c供给)。