A Makefile with Multiple Executables

ghz 1years ago ⋅ 3623 views

Question

I am trying to write a makefile which uses macros to create multiple executables from multiple files at once. I tried searching through previously answered questions but, because I am fairly new to programming in C as well as working with gcc, I was not able to find an answer to my question.

Here is what I have so far:

CC=gcc
CFLAGS=-I.
OBJ = ex1.c ex3.c
EXECUTABLE = ex1 ex3

$(EXECUTABLE): $(OBJ)
    gcc -o $@ $^ $(CFLAGS)

clean:
    rm -f $(EXECUTABLE)

I would like the line

$(EXECUTABLE): $(OBJ)

to create executables ex1 and ex3 from files ex1.c ex3.c respectively.


Answer

For this particular case, where each executable has a single source file with .c extension, all you need is a one line Makefile:

all: ex1 ex3

The built-in default rules for make then work already:

$ make
cc -O2 -pipe   ex1.c  -o ex1
cc -O2 -pipe   ex3.c  -o ex3

Behind the scene, make is using the POSIXly mandated built-in single suffix rule

.c:
    $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<

Vary the command to your liking with make CC=gcc CFLAGS=-O2 LDFLAGS=-s and similar.

Trivia of the day: in fact, if you are willing to name the targets when invoking make, you can use an empty or even run without any Makefile:

$ make -f /dev/null CC=gcc CFLAGS=-O2 LDFLAGS=-s ex1 ex3
gcc -O2 -s ex1.c  -o ex1
gcc -O2 -s ex3.c  -o ex3
$ rm -f Makefile ex1 ex3
$ make CC=gcc CFLAGS=-O2 LDFLAGS=-s ex1 ex3
gcc -O2 -s ex1.c  -o ex1
gcc -O2 -s ex3.c  -o ex3

Make magic!

As a rule of thumb, don't reinvent the wheel (or rules), use the rules that are already there. It simplifies your and make's life a lot. This makes for small and sexy makefiles to impress the ladies with :-)