Reputation: 1512
Can someone help me figure out the following make file?
BINS=file1 file2 file3
all: $(BINS)
clean:
rm -f $(BINS) *~
$*: [email protected]
gcc -g -o $@ $?
Here are my questions:
Thanks!
Upvotes: 4
Views: 1019
Reputation: 425291
1.) What is the -g option of gcc?
Generate debugging info
2.) What are $* and $@
$*
is the stem of the rule. When you make rule like
%.ext: %.otherext
ext2otherext --input $? --output $@ --logfile $*.log
, and the rule tries to make file.ext
from file.otherext
, then to log goes to file.log
$@
is the target filename (file.ext
in the case above).
3.) How does it know to execute the last target?
This is a mystery.
$*
is used for intermediary files: like, when you try to make an %.so
out of %.c
, you'll need an intermediary %.o
which is neither target nor a source. You put:
%.so: %.c
gcc -fPIC -g -c -o $*.o $?
ld -shared -o $@ $*.o
In other words, in a %.extension
rule, $*
is everything but the .extension
.
As a target, $*
makes no sense.
Are you sure this rule is actually executed somewhere? When I try to reproduce it using your Makefile, it applies default rules (cc -o
) instead of gcc -g -o
Rule you need seems to be:
%: %.c
gcc -g -o $@ $?
Upvotes: 3
Reputation: 21485
From the gcc
and make
documentation:
"-g Produce debugging information in the operating system's native format".
a. "$* The stem with which an implicit rule matches (see How Patterns Match). If the target is dir/a.foo.b and the target pattern is a.%.b then the stem is dir/foo. The stem is useful for constructing names of related files. In a static pattern rule, the stem is part of the file name that matched the '%' in the target pattern."
b. "$@ The file name of the target of the rule. If the target is an archive member, then '$@' is the name of the archive file. In a pattern rule that has multiple targets (see Introduction to Pattern Rules), '$@' is the name of whichever target caused the rule's commands to be run."
c. "$? The names of all the prerequisites that are newer than the target, with spaces between them." (Not asked, but worth adding.)
"'all' Compile the entire program. This should be the default target."
This example makefile is a bit limited, since it seems to only build C programs. The GNU make has several more extensive examples that are useful for learning how to write makefiles.
Upvotes: 5
Reputation: 56572
The first line does just what you'd expect by looking at it — it creates a list of names and assigns it to BIN
. Next, a make target called all
is defined, which is dependent on the targets listed in $BIN
(all
can't be built until each target in $BIN
is built). all
is a special build target; if you just run make
rather than, say, make clean
, the all
target is automatically built. There are no actual commands associated with all
— it simply ensures that all its dependencies are built. The last fairly straightforward command defines a build target called clean
, which deletes each file listed in $BIN
(note that $BIN
is being used both as a list of build targets and a list of files in this makefile) and all backups.
Next, we get to a line which is, basically, magic. $*
is a special build target which means "anything not specifically defined". When make
tries to build all
, it finds the target and starts work on its dependencies. But when it tries to build file1
, there is no explicit target defined. Instead, it uses $*
to build file1
. Similarly, $@
gets replaced with the build target's name, and $?
with its dependencies (sort of; that one you're better off checking the manual for). When make
goes to build file1
, then, the $*
rule causes it to behave as if the following rule were defined:
file1: file1.c
gcc -g -o file1 file1.c
Finally, the -g
option simply enables debugging information to be compiled in.
Upvotes: 1
Reputation: 8886
Q1 and Q2 have been answered extensively already, so a brief explanation for Q3 only:
Make always executes the first target unless you specified a different one. This is also called the default target. Usually the default target is called "all".
Upvotes: 0