Can someone help me figure out the following make file?
BINS=file1 file2 file3
all: $(BINS)
clean:
rm -f $(BINS) *~
$*: $@.c
gcc -g -o $@ $?
Here are my questions:
- What is the -g option of gcc?
- What are $* and $@
- How does it know to execute the last target?
Thanks!
-
Jay Conrod : RTFM is not really a helpful answer.nicerobot : Teach a person to fish ...Jay Conrod : Technical documentation like this can be pretty opaque. Learning the basics of make through the documentation is about the hardest way I can think of.nicerobot : The benefit Chris would gain from reading the manuals to learn the answer to his few basic questions far outweighs any reason for duplicating the content from those manuals here in SOChrisDiRulli : This is why I hate coming to this site...It's hard to Google for special characters like $* or $@. And I don't have a lot of time to spend reading a manual.nicerobot : @chrisdirulli but i gave you the resources and once on those pages, it's easy to search for those characters.
-
From the
gccandmakedocumentation:"-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.
-
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.extfromfile.otherext, then to log goes tofile.log$@is the target filename (file.extin 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%.soout of%.c, you'll need an intermediary%.owhich is neither target nor a source. You put:%.so: %.c gcc -fPIC -g -c -o $*.o $? ld -shared -o $@ $*.oIn other words, in a
%.extensionrule,$*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 ofgcc -g -oRule you need seems to be:
%: %.c gcc -g -o $@ $?Jon Ericson : I'm curious to know if the makefile works, but I'm too lazy to actually try it. Did you?Quassnoi : Yes, I did, it doesn't work :) It makes actually, but uses default rules instead of gcc -g. -
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".
-
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 calledallis defined, which is dependent on the targets listed in$BIN(allcan't be built until each target in$BINis built).allis a special build target; if you just runmakerather than, say,make clean, thealltarget is automatically built. There are no actual commands associated withall— it simply ensures that all its dependencies are built. The last fairly straightforward command defines a build target calledclean, which deletes each file listed in$BIN(note that$BINis 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". Whenmaketries to buildall, it finds the target and starts work on its dependencies. But when it tries to buildfile1, there is no explicit target defined. Instead, it uses$*to buildfile1. 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). Whenmakegoes to buildfile1, then, the$*rule causes it to behave as if the following rule were defined:file1: file1.c gcc -g -o file1 file1.cFinally, the
-goption simply enables debugging information to be compiled in.Quassnoi : $* is not a special build target, it's not a target at all.
0 comments:
Post a Comment