Reputation: 21
I have 4 source files and 5 header files and I use the following libraries:
But when I try out my makefile I get the following error:
/usr/bin/ld: cannot find -lSDL_gfx.
This is the make file I have so far:
The first rule links all the object files together and the other ones are responsible for creating the object files
CC=gcc
CFLAGS=-I -c -fmessage-length=0 -D_SDL_main_h -lSDL -lSDL_ttf -lSDL_gfx.
DEPS = game.h field.h cell.h allocate_field.h GUI.h
OBJ = game.o field.o allocate_field.o GUI.o
OUTPUT = game
all: $(OBJ)
@echo Programma aanmaken
gcc -o $@ $^ $(CFLAGS)
game.o : game.c field.h GUI.h
@echo Bezig met game.o te compileren
$(CC) -c -o game.o game.c
field.o : field.c allocate_field.h cell.h
@echo Bezig met field.o te compileren
$(CC) -c -o field.o field.c
allocate_field.o : cell.h
@echo Bezig met allocate_field.o te compileren
$(CC) -c -o allocate_field.o allocate_field.c
GUI.o : field.h cell.h
@echo Bezig met GUI.o te compileren
$(CC) -L/home/usr/lib/x86_64-linux-gnu -lSDL -lSDL_ttf -lSDL_gfx -c -o GUI.o GUI.c
.PHONY : clean
clean:
@echo Cleaning... Object files verwijderen
rm -f *.o
rm -f $(OUTPUT)
EDIT
The directory my libraries are in is /usr/lib/x86_64-linux-gnu.
I tried the echo command with the directory I mentioned here above, but I cant get it to work
EDIT EDIT
I think you meant the dot in the CFLAGS line. I removed it and then I got this error:
undefined reference to `IMG_Load' which is one the functions of the SDL_image library
Then I also added -lSDL_image and now it works.
Upvotes: 0
Views: 2253
Reputation: 16540
there are several little 'oops' in the posted makefile.
Note: the :=
for the macro definitions, so they are only evaluated once.
Note: could use: SRC := $(wildcard *.c)
then OBJ := $(SRC:.c=.o)
to get the list of object files. However, there must not be any stray *.c files in the current directory
Note: library files are only needed at link time.
Note: when compiling should always enable all warnings, then fix those warnings.
Note: The order of items on the command line, when linking is important. Always place the library path, followed by the 'short' library names last
Note: When ever a 'target' rule does not actually create a file with the same name, always proceed the rule with: .PHONY : target
Note: when calling system functions, it is (almost) always better to define a macro then invoke that macro. This results in better flexibility and less chance of an error. See the RM
and CC
macros for examples
Note: it is better to not define macros that will not be used: for instance the DEP
macro
You might want to use something similar to this for compiling and linking as it does not invoke the shell functionality echo
and it results in a better looking output
game.o : game.c field.h GUI.h
#
# ========= START $< TO $@ =========
$(CC) $(CFLAGS) -c $< -o $@ -I.
# ========= END $< TO $@ =========
#
By using something like: (note: gcc
has a parameter that can also do this)
%.d: %.c
#
# ========= START $< TO $@ =========
$(CC) -M $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
# ========= END $< TO $@ =========
plus this:
%.o: %.c %.d
#
# ========= START $< TO $@ =========
$(CC) $(CCFLAGS) -c $< -o $@ -I.
# ========= END $< TO $@ =========
#
and this: (with a DEP
macro)
ifneq "$(MAKECMDGOALS)" "clean"
-include $(DEP)
endif
then make
would generate all the dependency information so it would not have to be hardcoded into the makefile and all the compile statements would collapse into a single:
%.o: %.c %.d
#
# ========= START $< TO $@ =========
$(CC) $(CCFLAGS) -c $< -o $@ -I.
# ========= END $< TO $@ =========
#
The above will not make much difference for this project, but when the project contains hundreds of files, it is a MAJOR savings in time and debugging effort
The proposed makefile corrects all the obvious problems and allows running by:
make
or
make game
or
make all
or for individual file compilation
make <objectFileName>
Here is the proposed makefile
RM := /usr/bin/rm
CC := /usr/bin/gcc
CFLAGS := -c -fmessage-length=0 -D_SDL_main_h
#a better CFLAGS would be:
#CFLAGS := -fmessage-length=0 -D_SDL_main_h -std=c99 -Wall -Wextra -pedantic -Wconversion -c
LFLAGS :=
LIBS := -L/usr/lib/x86_64-linux-gnu -lSDL -lSDL_ttf -lSDL_gfx
# DEPS := game.h field.h cell.h allocate_field.h GUI.h
OBJ := game.o field.o allocate_field.o GUI.o
OUTPUT := game
.PHONY : all
all: $(OUTPUT)
$(OUTPUT): $(OBJ)
@echo Programma aanmaken
$(CC) $(LFLAGS) -o $@ $(OBJ) $(LIBS)
game.o : game.c field.h GUI.h
@echo Bezig met game.o te compileren
$(CC) $(CFLAGS) -c $< -o $@ -I.
field.o : field.c allocate_field.h cell.h
@echo Bezig met field.o te compileren
$(CC) $(CFLAGS) -c $< -o $@ -I.
allocate_field.o : allocate_field.c cell.h
@echo Bezig met allocate_field.o te compileren
$(CC) $(CFLAGS) -c $< -o $@ -I.
GUI.o : GUI.c field.h cell.h
@echo Bezig met GUI.o te compileren
$(CC) $(CFLAGS) -c $< -o $@ -I.
.PHONY : clean
clean:
@echo Cleaning... Object files verwijderen
$(RM) -f *.o
$(RM) -f $(OUTPUT)
Upvotes: 1