Build and run your first application with make

In this example, we have the same code that we have in Build and run your first application with g++ but here we use make and Makefile to compile and link the source code.

You can find the source code of this sample here in Github.

The same as previous example, the application contains three files: hello.h, hello.cpp and main.cpp.

In order to use make for compilation, the first step is create a file in the root of your project called Makefile

In short, a Makefile has a general syntax called Rule Syntax:

targets : prerequisites
        recipe
...

target(s) is/are the generated or resulted files that the recipe section generates and the recipe can have prerequisites

Here is a simple example is you want to compile and link hello.h, hello.cpp and main.cpp

Makefile
CC=g++
DEPS = hello.h
OBJ = hello.o main.o

%.o: %.cpp $(DEPS)
	$(CC) -c -o $@ $<

greet: $(OBJ)
	$(CC) -o $@ $^

Save above content is a file called Makefile in the root folder of your project. I go to the Makefile line by line.

The first line is CC=g++. I defined CC variable to indicate the compiler which g++ in here to compile C++ files.

In the second line, I defined DEPS variable to list all header (.h) files which are needed to compile implementation (.cpp) files. Since we have only one header file DEPS = hello.h

In the third line, I listed the object compiled file which are result of the compilation of each .cpp file as a variable named OBJ. We have two .cpp files, one is hello.cpp that has the implementation of hello() function and main.cpp that is the consumer of hell() function in the main() method which is the starting point of the application.
So OBJ = hello.o main.o

Next is a two line paragraph, we call it Rule in Makefile. The target is %.o which means any file name with .o extension. In the prerequisites section I defined %.cpp $(DEPS) which means all .cpp files (hello.cpp and main.cpp) and DEPS variable has hello.h in it. In the recipe section $(CC) points to the value of CC variable which is g++ and -c means "Only run preprocess, compile, and assemble steps". -o is a switch to indicate the name of the output object file which refers to $@ and $@ means the target which is %.o. And finally $< means just the first prerequisite that equals to %.cpp that we defined in prerequisite section.

The last rule creates executable file that I named it greet. The target name is greet:. Prerequisite is $(OBJ) that has hello.o main.o values and in the recipe section we link all object files into one executable file called greet. $(CC) is the compiler, -o indicates output file, greet in this case that using $@ you refer to target name in the rule you define and $^ list all prerequisite items

The value of '$^' is a list of all the prerequisites of the rule, including the names of the directories in which they were found, and the value of '$@' is the target

Now in a terminal run make to execute Makefile that you created.

$ make
g++ -c -o hello.o hello.cpp
g++ -c -o main.o main.cpp
g++ -o greet hello.o main.o

And finally run your app:

$ ./greet
Hello World!

Leave a Reply