Table of contents
1. What is make/Makefile
Makefile
Under Windows, after we use ides such as VS and VS Code to write C/C++ programs to implement a project, these ides will help us process and generate executable files for these programs.
But under Linux, if we need to implement this project by ourselves through instructions, the source files in a project are not counted, and they are placed in several directories according to type, function, and module. It is very inconvenient to connect them one by one. convenient.
And Linux provides a project automatic compilation tool - Makefile
, which defines a series of rules to specify, which files need to be compiled first, which files need to be compiled later, which files need to be recompiled, and even perform more complex functional operations. Once the Makefile is written, only one make command is needed, and the entire project is completely automatically compiled, which greatly improves the efficiency of software development.
Therefore, whether you can write a Makefile or not shows from the side whether a person has the ability to complete large-scale projects.
make
make is a command tool that explains the instructions in the makefile. Generally speaking, most IDEs have this command, such as: make in Delphi, nmake in Visual C++, make in GNU under Linux. It can be seen that Makefile has become a compilation method in engineering.
As follows: We use Makefile to generate the executable file of the C language file hello.c.
When the development environment of a c programmer is only one Linux connected through the terminal, Makefile is almost the only choice for building complex projects, and it is also whether the project has a project. A watershed of globalization, all in all, to learn Linux, Makefile is important enough.
Summarize:
Under Linux, make is a command, and Makefile is a file. The two complement each other and jointly realize the "automated build" of the project.
2. Makefile logic
1. Simple dependency
Makefile mainly consists of and 依赖关系
, 依赖方法
while dependencies consist 目标
of依赖
The most classic format is as follows:
target:dependence #依赖关系
command #依赖方法
Among them, target
is the target to be generated, and dependence
is to generate the dependencies required by the target. The two form a dependency relationship, and command
it is to generate the commands to be executed by the target.
Notice:
- There can be multiple or none of the dependencies in the dependencies
- Makefile can also be written as makefile, which cannot be recognized by other make. (This article is Makefile)
- Each dependency must start with the [Tab] key
Take our test code above as an example:
In order to generate the hello file, you need to depend on the hello.c file, and finally generate the target file hello through the following dependencies.
2. Complex dependencies
In the above test case, it is a file in this directory. If the file in it 依赖关系
is not in this directory , the system will automatically search for the same file in the Makefile when it is generated. If the found file is still not in this directory Next, repeat the above operation. (The system uses the result of the stack to operate)依赖
依赖关系
依赖
目标文件
其它目标文件
Let's first modify the above test case as follows:
- Generate hello file and depend on hello.o file
- Generate hello.o file and depend on hello.s file
- Generate hello.s file and depend on hello.i file
- Generate hello.i file and depend on hello.c file
- The hello.c file is found in this directory, use it directly
When we generate a hello file, the other three are generated 目标文件
and stored in this directory
The dependencies are as follows:
- Changes in other
目标文件
locations will not affecttarget1
the generation, it依赖
is the same search under the Makefile file目标文件
, and has nothing to do with the target file位置
. Still use the above method to generate files.
Three. make command
1. Use of make
Under Linux, after we enter the make command, the system will search the Makefile in the current directory, execute the first dependency and dependent method in the file after finding it, print out the dependent method on the screen and generate the target file.
We modify the above Makefile test case as follows:
Generate two sets of dependencies. (clean will be discussed below)
As follows for us to pass the make test
When we want to delete other target files in the generated Makefile, we need to specify the target file
make target1 target2 #make后可以有多个target目标文件
- make target
- make target1 target2
2. clean up
In a project, some unnecessary files are always cleaned up, and we often use clean
them as target files for project cleaning.
Because cleaning files do not need to depend on other files, clean does not have dependencies.
When clean is not the first target file in the Makefile, we need to add clean after make to compile it, just like the previous test.
3. False target
Use .PHONY
modified targets, called pseudo-targets, in the following format
.PHONY:target
Function : Make the file always executable
When we use make multiple times to generate the same target file, the compilation can pass for the first time, but after that, it cannot pass, and the following results will be given:
At this time, we can use .PHONY
to modify the target file hello to make it a pseudo target, which can always be compiled
Note: Not only .PHONY
can it be compiled always after modification is used, the clean object file can also be compiled always, as follows:
4. How does make determine whether to compile
We have tested above, if not used .PHONY
, make can only be used once, and then it cannot be compiled, so how does make determine whether to compile?
When we finish writing a project and want to implement it (generally the project is very large, not the point we tested), it will waste a lot of time and performance. We can't let it execute unscrupulously, only when After the source file is modified, the project can be re-implemented to generate an executable file.
make judges whether to recompile, based on the comparison of the modification time of the source file and the target file.
- When the modification time of the source file is less than that of the target file, do not compile
- Compile when the modification time of the source file is greater than that of the target file
In Linux, each file has three times, as follows:
- Access time (Access): the time of the most recent access to the file content, such as cat, vim, less;
- Modification time (Modify): the time when the content of the file was last modified, such as nano, vim;
- Change time (Change): The time when the file attributes were changed recently, including file name, size, content, permissions, owner, group, etc., such as nano/vim (file size changes),
We can stat
view these three times of the file through commands
Impact of Access Time
Why is it necessary to compare the modification time of two numbers to judge whether make compiles repeatedly?
Under Linux, accessing a file can be performed through cat、less
instructions, and the file accessed through these two instructions will not modify its own access time, for the following two reasons:
- In LInux, accessing files is a very frequent operation, and modifying the file access time requires IO operations every time. If the access time is modified every time, it will increase the burden on the system.
- Whether a file can be read is determined by the permission of the file. Since the file is readable, it means that the owner and group of the file do not recommend you to read it, and there is no need to modify the access time every time.
Therefore, the Linux access time changes in the following two situations:
- It will be updated when the visits accumulate to a certain number of times or accumulate for a period of time
- When the modification time of the file changes, it changes accordingly
- The above picture only uses the vim check-in file and has not modified it, but the modification time will also change from time to time
To sum up: If you want to judge whether a file has been modified, you can judge whether its modification time has changed.
Note: The modification time changes, and the file does not necessarily change
Effect of modification time
When the modification time of the source file changes, it means that the source file has been modified. At this time, use make to compile again. We first use vim to update the modification time to judge
that we are using the touch command to update all the time of the source file (touch file: file There is no creation of file, file exists to update the file all the time), to judge whether make is executed has nothing to do with whether to modify the content of the source file.
From the above knowledge, we can conclude that whether make is compiled is related to the modification time of the source file , then we can know ,PHONY
that whether the target file is compiled is not judged according to the modification time, so as to achieve the effect of always being compiled.