I found this makefile on this site. They don't explain this example, so I was wondering if anybody new what was going on.
CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=hello
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(开发者_运维问答LDFLAGS) $(OBJECTS) -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp
sets four variables to be constant strings. For the rest of the makefile, wherever $(CC)
appears (for example), it will be replaced by g++
OBJECTS=$(SOURCES:.cpp=.o)
sets the variable OBJECTS to be the same as SOURCES, except wherever the pattern .cpp
appears in a words of SOURCES, its replaced by .o
EXECUTABLE=hello
sets another constant string var
all: $(SOURCES) $(EXECUTABLE)
The first actual rule in the makefile, This tells make that to build all
it must first build everything in $(SOURCES)
and $(EXECUTABLE)
, and then do nothing. Since this is first, it becomes the default target, so running make
is equivalent to make all
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $@
Another rule: to create $(EXECUTABLE)
(which expands to hello
) it must first build everything in $(OBJECTS)
(equivalent to main.o hello.o factorial.o
) and then run the command $(CC) $(LDFLAGS) $(OBJECTS) -o $@
.cpp.o:
$(CC) $(CFLAGS) -o $@ $<
A pattern rule: in order to build a file ending in .o
, first rebuild/create/find the corresponding file ending in .cpp, and then run the command $(CC) $(CFLAGS) -o $@ $<
.
These last two rules contain the special variables $@
and $<
which are only valid in rule actions and expand to the target and first dependency respectively
So when you run make
, it reads all this and then tries to build the default target (all).
Since it doesn't exist, it tries to build the files main.cpp, hello.cpp, factorial.cpp, and hello. Since the first 3 (presumably) exist, it looks for rules/dependencies for them, but doesn't find any, so decides there's nothing to do for them. If they didn't exist, make would give an error saying "no rule to make target 'main.cpp'"
In the case of "hello" it depends on main.o, hello.o and factorial.o, so it looks into them. For main.o, the pattern rule says it depends on main.cpp, so if main.o doesn't exist or if main.cpp is newer, it will run the command g++ -c -Wall -o main.o main.cpp
. The same happens for hello.o and factorial.o.
Once those are done, if hello
doesn't exist or is older than any of those .o files (which may have just changed, so are possibly pretty new), it will run that command to relink it. Finally, it will run the empty command (doing nothing) to 'rebuild' all.
精彩评论