Reputation: 20688
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
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
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