What does "linker input file unused because linking not done" mean? (C makefile)
Solution 1
there are several small oversights in the posted makefile.
Amongst them:
- library names are only used during the link step, not the compile step
- 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:
for instance:
SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
- when a target (all, clean) will not produce a file of the same name, then insert a
.PHONY:
statement early in the make file:
similarly to:
.PHONY : all clean
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.
this line:
rm *o game
will 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.
suggest:
rm -f *.o game
- this line:
all: ./game
can create problems
suggest:
all: game
- once the list of object files is created (as above) then the compile rules can be reduced:
by using the make operators:
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@ -I.
the
-g
parameter to the compiler and linker allows for a debugger to be used. If that debugger isgdb
then a better parameter is-ggdb
almost always, there is no need to evaluate a macro definition more than once, so rather than using
=
in a macro definition, use:=
If you want the
game
to be executable, then insert achmod
command as the last line in the 'link' rule
Suggest reading about the special operators that can be employed in a makefile
to help you understand the following, suggested 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
Solution 2
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 -c
flag in it. The -c
flag tells gcc not to do linking. So it has nothing to actually do. (.o
files can only be used for linking, and you've disabled linking, which is why you get that message)
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
.
liamw9
Updated on August 02, 2022Comments
-
liamw9 almost 2 years
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?
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
-
Jonathan Leffler over 8 yearsAnd better still to create a macro
OBJECTS = global.o display.o player.o entities.o controls.o sound.o menu.o
and then use the in both the dependency line and the link command line. -
liamw9 over 8 yearsThank you. I had tried following tutorials and there were several things that I didn't understand. You have cleared them up for me
-
user3629249 over 8 yearsthe error message the OP received means the link step was not performed. It was not performed due to the several 'oops' in the OPs posted makefile.
-
user318904 about 6 yearsDownvoting because your final Makefile has several bad practices: hard-coding RM and CC, not using make's built-in rules, passing some linking flags in hard-coded, others through SDL, including "." is un-needed, always append to CFLAGS so additional ones can be specified on command line, using "LFLAGS" as second set of cflags (w/ no warnings).
-
user3629249 about 6 years@user318904, your understanding of 'best practices' for the contents of a makefile and my understanding are significantly different. Please post a link to a web page that lists 'best practices' for makefiles