GNU Make is a tool for controlling the compilation process. It controls how the source files of the program generate executable files or non-source files, in fact, it specifies a way to automate our build process.
Let's first understand how a program is compiled.
Before getting an executable file, the object file must be compiled first, and then the object file must be linked.
(Note: During the compilation process, preprocessing will be done first, and some macro expansions, include, etc. will be included, etc., to obtain *.i
or *.ii
, then compile to obtain the assembler *.s
, then compile to obtain the target file *.o
, and finally link the target file to obtain the executable file) .
The first step is to compile the target file
How to get the target file? You can tell the compiler to only compile to object files:
g++ main.cpp –c –o main.o
g++ library.cpp –c –o library.o
-c
Indicates only compile (compile only)
The second step is to link the target file
g++ library.o main.o -o main
If the above steps are expressed in makefile, how should makefile be written?
According to the above information, we can get the following information
- main.o should be generated with main.cpp file
- library.o should be generated with library.cpp file
- The main executable file needs to be linked with the previously generated object file,
so the makefile can be written like this.
main.o: main.cpp
g++ main.cpp -c -o main.o
library.o: library.cpp
g++ library.cpp -c -o library.o
main: main.o library.o
g++ main.o library.o -o main
Save the above content into a file named makefile.
Use the make command to execute the compilation process of the makefile. Through the following results, we will find that only the first line of the makefile will be executed to get main.o.
What if we use make. main
it?
We specify that the target of make execution is main, then it will also execute the commands that the resources that the result depends on need to be executed.
We continue to enrich our makefile.
main.o: main.cpp
g++ -Wall -g main.cpp -c -o main.o
library.o: library.cpp
g++ -Wall -g library.cpp -c -o library.o
main: main.o library.o
g++ -Wall -g main.o library.o -o main
We have added -Wall -g
, which -Wall
means that all warnings are printed out during the compilation process, -g
which means that files that can be used for gdb debugging are compiled. And we found that there are three commands g++ -Wall -g
, we can use a variable to store them, and then add them to each command by quoting variables:
cxx = g++ -Wall –g
main.o: main.cpp
$(cxx) main.cpp -c -o main.o
library.o: library.cpp
$(cxx) library.cpp -c -o library.o
main: main.o library.o
$(cxx) main.o library.o -o main