Understanding this Makefile

I have this program which has lots of source files in the directories

src
src/dir1 
src/dir2
src/dir3... and so on

I am trying to understand the following Makefile:

CC = gcc
CFLAGS= -g -c -D_REENTRANT
SOURCES = src/main.c src/dir1/a.c src/dir1/b.c src/dir2/x.c src/dir2/y.c ...and so on
OBJS = src/main.o src/dir1/a.o src/dir1/b.o src/dir2/x.o src/dir2/y.o ...and so on
TARGETS = prog.exe

%.o : %.c
        $(CC) $(CFLAGS) -o $@ $?

${TARGETS}:  ${OBJS}
        $(CC) ${OBJS} -o ${TARGETS}

First of all, I am trying to understand what does $@ $? do?? And also what does the wild character % in %.o : %.c stand for ?

And, since I have a lot of source files spread out in multiple directories and lots of corresponding directories.. the macros SOURCES and OBJS are getting quite ugly.. is there any way around this ?

(I couldve also used macros for the directory names, but it is still getting very ugly)

It would be much better if i could say:

SOURCES = src/*.c    src/dir1/*.c    src/dir2/*.c
OBJS       = src/*.o    src/dir1/*.o    src/dir2/*.o 

But that does not work :frowning:

$@ is the target of the dependancy

$? are the prequisites for each dependancy rule

The %.o: %.c means in order to build a file with this extension from a file of this extension follow this rule.

Personally I think wild cards are bad news in Makefiles. You want to know exactly what you are building.

While we are at it, I also I don't recommend requiring gmake.

Also, personally, I think that objects should be built in a totally different tree to the source.

And I think that persistent objects be kept in source control along with the primary source. Source control is a must.

I was referring to .o files. As in I recommend keeping the compiled objects built in a separate tree to the source especially when you compile for multiple architectures.

This article will help you to understand "make".
An Introduction to the UNIX Make Utility

Best regards,
Iliyan Varshilov