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

41,573

Solution 1

there are several small oversights in the posted 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:

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:

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 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 
  1. this line: all: ./game can create problems

suggest:

all: game
  1. 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.
  1. the -g parameter to the compiler and linker allows for a debugger to be used. If that debugger is gdb then 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 game to be executable, then insert a chmod 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.

Share:
41,573
liamw9
Author by

liamw9

Updated on August 02, 2022

Comments

  • liamw9
    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
    Jonathan Leffler over 8 years
    And 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
    liamw9 over 8 years
    Thank you. I had tried following tutorials and there were several things that I didn't understand. You have cleared them up for me
  • user3629249
    user3629249 over 8 years
    the 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
    user318904 about 6 years
    Downvoting 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
    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