We have already introduced how to use gcc to compile code to generate files. However, when there are many projects, an automated compilation tool is often needed to help us complete this operation. In Windows, you can use Ctrl + F5 to complete project compilation with one click.
Makefile syntax Basics
In Linux, automated compilation tools are completed using the make command (some tool vendors also provide their own make commands, such as gmake). The basic format of the make command is as follows:
Make [-f makefile] [label]
It can use the-f parameter to specify the input file. When the-f parameter is omitted, the default input file name is Makefile. Because we usually do not use this-f parameter, the default Makefile file name is often used.
Makefile is a text file based on certain syntax rules. Its basic execution rules are defined as follows:
Target: [prerequisites]
Command
- Target tag, used to mark the currently built rule. It can also be a file.
- Prerequisites dependency, the rule that is first executed when the tag is created
- Command make command to be executed. (Any Shell command)
Note:The target of Makefile is written in the top lattice, while the Command requires a Tab key. I add a Tab key to each line to make the layout look more comfortable. If you want to use the Makefile example in this article, remove the first Tab key of each line; otherwise, an error is reported during make.
For example, we compile a simple Makefile:
Clean:
@ Echo "clean"
All:
@ Echo "all"
When we directly execute the make command, the output is as follows:
Tianfang> make
Clean
Tianfang> make all
All
Tianfang> make clean
Clean
We can see that the first tag is constructed by default. You can use the command line parameters to construct a specified tag.
Then let's take a look at how dependency works. This time, let's modify the Makefile so that the all tag depends on the clean Tag:
Clean:
@ Echo "clean"
All: clean
@ Echo "all"
When you execute make all again, you will first execute the clean label:
Tianfang> make all
Clean
All
Use Makefile to build a project
After a simple understanding of the Makefile syntax, we can use Makefile to simplify our building operations. Let's take a look at the previous stack example. First, let's implement the simplest example:
All:
Gcc-o run main. c stack. c
In this way, you can run the gcc-o run main. c stack. c command directly using the make command.
To implement incremental compilation, we need to implement the following rules:
- If this project has not been compiled, all our C files must be compiled and linked.
- If several C files of this project are modified, We will compile only the modified C files and link them to the target program.
In this case, the preceding dependency is required:
Run: stack. o main. o
Gcc-o run main. o stack. o
Stack. o: stack. c
Gcc-c stack. c
Main. o: main. c
Gcc-c main. c
All targets here are files, and run depends on stack by default. o and main. o. Therefore, when building run, the stack will be built first. o and main. o. The output method is as follows:
Tianfang> make
Gcc-c stack. c
Gcc-c main. c
Gcc-o run main. o stack. o
When we only change one of the files, such as stack. c. This is because main. c has not changed, so it will not recompile main. o. Only the stack will be re-built. o and run to achieve our incremental compilation goal. (This is actually more powerful than the batch processing method written in shell or script language)
Tianfang> make
Gcc-c stack. c
Gcc-o run main. o stack. o
Improved Makefile through automatic Derivation
The above example shows that although we can implement incremental compilation, the entire Makefile process is very complex and requires compiling scripts for each. o file. If many project files are added or deleted, it is very troublesome to write Makefile files.
To improve this problem, makefile provides an automatic derivation function, which can simplify the compilation process. For example, the preceding example can be simplified as follows:
CC = gcc
Objs = stack. o main. o
Run: $ (objs)
$ (CC)-o run $ (objs)
Here we introduce two variables. The first line of CC sets the compiler to gcc (if not specified, it is the default cc), and the second line sets our obj file.
In this way, you only need to execute the make command to produce our program:
Tianfang> make
Gcc-c-o stack. o stack. c
Gcc-c-o main. o main. c
Gcc-o run stack. o main. o
As you can see, the make command automatically exports how to root the. o file. If the project file changes, you only need to change the objs variable, which is very convenient.
However, sometimes we may feel that the automatic deduction method is not enough, and we need to manually control the compilation options. In this case, we can specify the deduction rules ourselves:
CC = gcc
Objs = stack. o main. o
Run: $ (objs)
$ (CC)-o run $ (objs)
$ (Objs): %. o: %. c
$ (CC)-c-g $ <-o $ @
Makefile features are very powerful, and the corresponding syntax is also very complex. Because someone has already written a lot of details on the internet, I am not planning to introduce various Makefile rules here, for more information, refer to the Makefile article with me.