Lone Learner
Lone Learner

Reputation: 20688

How to avoid duplication in Makefile targets with similar recipes?

I have a Makefile which has a lot of targets and the recipe for each target is quite similar.

foo:
    gcc foo.c -o foo
    mv foo ~/bin

bar:
    gcc bar.c -o bar
    mv bar ~/bin

baz:
    gcc baz.c -o baz
    mv baz ~/bin

I would like to avoid all this duplication. I would like to have something like below (this is not valid syntax; this only expresses my intention).

TARGET_NAME:
    gcc $(TARGET_NAME).c -o $(TARGET_NAME)
    mv $(TARGET_NAME) ~/bin

Is it possible to do something like this? If not, what is the best Makefile I can write that can minimize duplication in recipes?

Upvotes: 4

Views: 1551

Answers (2)

MadScientist
MadScientist

Reputation: 100956

Your makefile is wrong because your targets (foo, bar, etc.) don't depend on their source files (foo doesn't depend on foo.c, etc.) So, changing the source code won't cause the target to be rebuilt.

Also, your makefile says you're creating a file foo, but your recipe actually creates a file ~/bin/foo, which is not the same thing.

Anyway, this is exactly what pattern rules are for:

EXES = foo bar baz

all: $(addprefix $(HOME)/bin/,$(EXES))

$(HOME)/bin/%:: %.c
        gcc $< -o $@

(Thanks to Beta for pointing out my think-o in the original)

Upvotes: 5

sapanoia
sapanoia

Reputation: 789

A make rule can actually match multiple targets:

foo bar baz:
    gcc [email protected] -o $@
    mv $@ ~/bin

However, you should make the dependencies explicit in the rules:

foo: foo.c
bar: bar.c
baz: baz.c

foo bar baz:
    gcc $< -o $@
    mv $@ ~/bin

The first three lines only specifiy the dependencies without any actions to actually build them. You can generate these with the help of gcc: gcc -MM foo.c will print a rule for foo.c.

Upvotes: 3

Related Questions