Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Could someone explain this make file?

Tags:

makefile

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 $@
like image 393
jumpnett Avatar asked Feb 23 '11 23:02

jumpnett


People also ask

What does make a file mean?

A makefile is a file that results from using the "make" processing tool, a tool used in software development to build a program in its final ".exe" file extension form together with its libraries. The make tool performs an interpretation process of make files to determine the final code of the destination .exe file.

What is the point of a make file?

The purpose of a makefile is to be easily build an executable that might take many commands to create (which would be a pain to compile over and over again manually).

How do you read a make file?

A makefile is simply a way of associating short names, called targets, with a series of commands to execute when the action is requested. For instance, a common makefile target is "clean," which generally performs actions that clean up after the compiler--removing object files and the resulting executable.

What is makefile and how do you use it?

The make utility requires a file, Makefile (or makefile ), which defines set of tasks to be executed. You may have used make to compile a program from source code. Most open source projects use make to compile a final executable binary, which can then be installed using make install .


1 Answers

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.

like image 53
Chris Dodd Avatar answered Sep 21 '22 07:09

Chris Dodd