My directory contains 2
source files: a.c
and b.c
. I want to generate executable file a
from a.c
and b
from b.c
. Now I can only figure out one method to write Makefile:
all:
gcc -o a a.c
gcc -o b b.c
It seems a little awkward, is it better method?
The answers are fine, still I think you need some insight in how make
works:
The basic functionality of make
is to create output files from input files if necessary. make
decides what is necessary by comparing timestamps: If any input file is newer than an output file created from it, the recipe for this output file is executed.
This means with just a rule named all
, this rule is always executed (except when you happen to have a recent file actually called all
-- to prevent this behavior, you have to list all
as a .PHONY
target, that is one that doesn't actually create a file). Your original Makefile is equivalent to a simple shell script, so it doesn't use make
properly.
The minimal "correct" version of your Makefile should look like this:
all: a b
a: a.c
gcc -o a a.c
b: b.c
gcc -o b b.c
.PHONY: all
So, all
is "phony" and depends on a
and b
. a
is only rebuilt when a.c
changed, b
is only rebuilt when b.c
changed.
In a real project, your programs are probably made from more than just one source file and in this case, you can really take advantage of make
: Have it build object files of your translation units, so only the parts that changed are actually rebuilt. It's overkill for your tiny example, but could e.g. look like this:
a_OBJS:= a.o
b_OBJS:= b.o
all: a b
a: $(a_OBJS)
gcc -o$@ $^
b: $(b_OBJS)
gcc -o$@ $^
%.o: %.c
gcc -c -o$@ $<
clean:
rm -f *.o
.PHONY: all clean
You would just have to add more object files to a_OBJS
and b_OBJS
to include new translation units in your build. The pattern rule %.o: %.c
will match them. There's a lot more to discover, I suggest starting with the GNU make manual.
I think the follow method is better:
all: a b
a: a.c
gcc -o a a.c
b: b.c
gcc -o b b.c
In your version, make all
will always run gcc
twice, whether or not a.c
and b.c
are modified. In this version gcc
will be run only when necessary.
Of course you can use some magic (for
-loop or similar) to create the rules but I think the difference between my and your method is clear.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With