1. Experimental purpose and requirements
- Use Makefile to manage and compile source code, and master the basic syntax of Makefile.
- Learn the definition and use of variables in Makefile, as well as the common use of special variables.
- Learn the automatic derivation function of makefile.
- Learn to use makefile pseudo-targets.
2. Experimental platform
The experimental environment installed in the laboratory (Linux operating system) and Touge (www.educoder.net) experimental platform (course experiment)
3. Experimental content
- Basic syntax of Makefile.
- Definition and use of variables in Makefile
- Automatic derivation function of makefile
- pseudo-targets for makefiles
4. Experiment details and steps
mission details
The task of this level: use Makefile
to manage the compiled source code and master Makefile
the basic grammar.
related information
what is makefile
it Maybe many Winodws
programmers don't know this thing, because those Windows
people IDE
have done this work for you, but to be a professional programmer, you makefile
still need to understand it. makefile
In fact, it describes the compilation order and compilation rules of all files in the entire project, and make
reads makefile
the files by commands, and then makefile
parses them according to the rules defined in the files to complete the compilation operation of the entire project.
makefile
linux
It is relatively common in operating systems. For example, when we use source code to install a software, we usually only need to execute commands make
to complete the compilation of the software. It is precisely because the software developer has written makefile
the file, so we only need to execute make
the command The automatic compilation of the entire project will be completed.
makefile
The grammar introduced in this pass is used makefile
to complete the compilation of the software.
Makefile rules
makefile
The file contains a set of rules for compiling the application. A rule can be divided into three parts:
- work target
- Dependency (prerequisite)
- The command to be executed (command)
The format is:
- target : prereq1 prereq2
- commands
The above format is the dependency relationship of a file, that is to say, target
this object file depends on multiple prerequisites
files, and its generation rules are defined in commands
. To put it bluntly, prerequisites
if there is more than one file in the file target
that is newer than the file, commands
the defined command will be executed. That's Makefile
the rule. That is Makefile
the most core content.
Notice
- The TAB key is used in front of the commands instead of a space, and an error will occur if a space is used;
- commands can be any shell command;
- When executing the make command, make will parse the first rule;
Case demo 1:
There is a source code main.c
file, compile a makefile
rule to compile the file, and generate an HelloWorld
executable file named as follows:
- vim makefile
- make
vim
Write the following code using
- #include <stdio.h>
- int main()
- {
- printf("Hello world\n");
- return 0;
- }
- use
vim
writemakefile
- HelloWorld : main.c
- gcc -o HelloWorld main.c
[Please experience directly in the "command line" on the right]
As can be seen from the above cases, after writing makefile
, you only need to enter make
the command and automatically only need to define the rules.
Note: gcc -o HelloWorld main.c
the command is preceded by TAB
a key and not a space.
Case demo 2:
Assuming that a project contains 5
source code files, namely Add.c
, Sub.c
, Mul.c
, Div.c
and main.c
and a header file def.h
, compile a makefile
rule to compile the project and generate an exe
executable file named , the specific operations are as follows:
- vim makefile
- make
- vim Add.c
- #include <stdio.h>
- int Add(int a, int b)
- {
- return a + b;
- }
- vim Sub.c
- #include <stdio.h>
- int Sub(int a, int b)
- {
- return a - b;
- }
- vim Mul.c
- #include <stdio.h>
- int Mul(int a, int b)
- {
- return a * b;
- }
- vim Div.c
- #include <stdio.h>
- int Div(int a, int b)
- {
- return a / b;
- }
- vim main.c
- #include <stdio.h>
- #include "def.h"
- int main()
- {
- int add = Add(10, 5);
- int sub = Sub(10, 5);
- int mul = Mul(10, 5);
- int div = Div(10, 5);
- printf("10 + 5 = %d\n", add);
- printf("10 - 5 = %d\n", sub);
- printf("10 * 5 = %d\n", mul);
- printf("10 / 5 = %d\n", div);
- return 0;
- }
- vim def.h
- #ifndef __DEF_H__
- #define __DEF_H__
- #include <stdio.h>
- int Add(int a, int b);
- int Sub(int a, int b);
- int Mul(int a, int b);
- int Div(int a, int b);
- #endif
- vim makefile
- exe : main.o Add.o Sub.o Mul.o Div.o
- gcc -o exe main.o Add.o Sub.o Mul.o Div.o
- main.o : main.c def.h
- gcc -c main.c -o main.o
- Add.o : Add.c
- gcc -c Add.c -o Add.o
- Sub.o : Sub.c
- gcc -c Sub.c -o Sub.o
- Mul.o : Mul.c
- gcc -c Mul.c -o Mul.o
- Div.o : Div.c
- gcc -c Div.c -o Div.o
[Please experience directly in the "command line" on the right]
In the above case, when only make
the command is needed, the rule with the target is first parsed exe
, and then exe
the dependencies are found, and then the rules are parsed main.o
、Add.o和Sub.o
separately , that is, the commands with the target are executed respectively. When generated, finally execute the corresponding command.main.o
、Add.o和Sub.o
main.o
、Add.o和Sub.o
main.o
、Add.o和Sub.o
exe
programming requirements
The task of this level is to learn to use makefile
to compile the project.
The specific programming requirements are as follows:
- Write
5
a source file Add.c, Sub.c, Mul.c, Div.c and main.c and a header file def.h, the file content is the same as the case2
; - Use
makefile
to manage the above projects, and compile and generate anCalc
executable file named;
- vim Add.c
1. #include <stdio.h>
2. int Add(int a, int b)
3. {
4. return a + b;
5. }
- vim Sub.c
1. #include <stdio.h>
2. int Sub(int a, int b)
3. {
4. return a - b;
5. }
- vim Mul.c
1. #include <stdio.h>
2. int Mul(int a, int b)
3. {
4. return a * b;
5. }
- vim Div.c
1. #include <stdio.h>
2. int Div(int a, int b)
3. {
4. return a / b;
5. }
- vim main.c
1. #include <stdio.h>
2. #include "def.h"
3. int main()
4. {
5. int add = Add(10, 5);
6. int sub = Sub(10, 5);
7. int mul = Mul(10, 5);
8. int div = Div(10, 5);
9.
10. printf("10 + 5 = %d\n", add);
11. printf("10 - 5 = %d\n", sub);
12. printf("10 * 5 = %d\n", mul);
13. printf("10 / 5 = %d\n", div);
14.
15. return 0;
16. }
- vim def.h
1. #ifndef __DEF_H__
2. #define __DEF_H__
3.
4. #include <stdio.h>
5.
6. int Add(int a, int b);
7. int Sub(int a, int b);
8. int Mul(int a, int b);
9. int Div(int a, int b);
10. #endif
- vim makefile
1. Calc : main.o Add.o Sub.o Mul.o Div.o
2. gcc -o Calc main.o Add.o Sub.o Mul.o Div.o
3.
4. main.o : main.c def.h
5. gcc -c main.c -o main.o
6.
7. Add.o : Add.c
8. gcc -c Add.c -o Add.o
9.
10. Sub.o : Sub.c
11. gcc -c Sub.c -o Sub.o
12.
13. Mul.o : Mul.c
14. gcc -c Mul.c -o Mul.o
15.
16. Div.o : Div.c
17. gcc -c Div.c -o Div.o
mission details
The task of this level: Makefile
the definition and use of variables in learning, and the use of commonly used special variables.
related information
The use of variables can facilitate us to write makefile
files. We can use a short variable to replace a longer string, so that we can easily use variables to replace when using this string. In addition, when we modify a certain string, if we do not use a variable, we need to modify every place where the string is used. If a variable is used, we only need to modify the variable definition.
makefile
Variable commands can contain characters, numbers, underscores (may start with numbers), and are case-sensitive.
makefile
$
Variables need to be assigned a value when they are declared, and ** symbols need to be added before the variable name when using the variable. For example $(VARNAME)
, if the user needs to makefile
use real $
characters in the file, use $$
** to indicate.
makefile
There are three ways to assign values to variables in , namely:
- Recursive assignment (=): recursive assignment, that is, the assignment does not take effect immediately, and the actual assignment is made when it is used. At this time, the current value is found through recursion;
- Direct assignment (:=): It is to directly expand the variable contained in the right side of ":=" to the variable assignment on the left side;
- Conditional assignment (?=): Only when this variable has not been assigned a value before, this variable will be assigned a value, so it is generally used for the first assignment;
makefile
In addition to custom variables, there are also some system default special variables, which can help us quickly write makefile
files, such as: $@
、$<和$^
etc.
This level will introduce makefile
the definition and use of variables, as well as the use of special variables to write makefile
files.
Makefile custom variables
Custom variable format:
- recursive assignment
变量名 = 变量内容
- direct assignment
变量名 := 变量内容
- conditional assignment
变量名 ?= 变量内容
Variables are used in the format: $
变量名
either ${
变量名}
or$(变量名)
Case demo 1:
The item in the case in the previous level 2
contains 5
a source code file and a header file. If you use variables to write, makefile
it will show a relatively concise format. The specific operation is as follows:
- vim makefile
- make
- vim makefile
- object=main.o Add.o Sub.o Mul.o Div.o
- exe : $(object)
- gcc -o exe $(object)
- main.o : main.c def.h
- gcc -c main.c -o main.o
- Add.o : Add.c
- gcc -c Add.c -o Add.o
- Sub.o : Sub.c
- gcc -c Sub.c -o Sub.o
- Mul.o : Mul.c
- gcc -c Mul.c -o Mul.o
- Div.o : Div.c
- gcc -c Div.c -o Div.o
[ makefile
content]
[Please experience directly in the "command line" on the right]
It can be seen that we use object
to represent main.o Add.o Sub.o Mul.o Div.o
, so that we can use $(object)
to represent the above target file instead of entering 5
this .
Makefile special variables
makefile
Commonly used special variables are:
- $@: indicates all targets;
- $^: Indicates the collection of all dependent targets, separated by spaces;
- $<: Indicates the name of the first target in the dependent target;
Case demo 1:
Following the project in the previous case, if it is written using special variables, makefile
it will display a more concise format. The specific operations are as follows:
- vim makefile
- make
- vim makefile
- object=main.o Add.o Sub.o Mul.o Div.o
- exe : $(object)
- gcc -o $@ $(object)
- main.o : main.c def.h
- gcc -c $< -o $@
- Add.o : Add.c
- gcc -c $< -o $@
- Sub.o : Sub.c
- gcc -c $< -o $@
- Mul.o : Mul.c
- gcc -c $< -o $@
- Div.o : Div.c
- gcc -c $< -o $@
[Please experience directly in the "command line" on the right]
programming requirements
The task of this level is to learn to use makefile
to compile the project.
The specific programming requirements are as follows:
- Write
5
a source file Add.c, Sub.c, Mul.c, Div.c and main.c and a header file def.h, the file content is the same as the first case2
; - The variable used
makefile
to compile produces anVarCalc
executable named;
• vim makefile
1. object=main.o Add.o Sub.o Mul.o Div.o
2. VarCalc : $(object)
3. gcc -o VarCalc $(object)
4.
5. main.o : main.c def.h
6. gcc -c $< -o $@
7.
8. Add.o : Add.c
9. gcc -c $< -o $@
10.
11. Sub.o : Sub.c
12. gcc -c $< -o $@
13.
14. Mul.o : Mul.c
15. gcc -c $< -o $@
16.
17. Div.o : Div.c
18. gcc -c $< -o $@
mission details
The task of this level: makefile
the automatic derivation function of learning.
related information
make
.o
Very powerful, it can automatically deduce the commands behind files and file dependencies, so we don't need to write similar commands after each file. Because, ours make
will automatically recognize and derive commands by ourselves.
As long as make
it sees a .o
file, it will automatically add .c
the file to the dependencies, and if make
it finds one main.o
, then main.c
it will be main.o
the dependent file. And gcc -c main.c
will also be derived, so we makefile
don't have to write so complicated anymore.
This level will introduce makefile
the automatic derivation function.
Makefile automatic derivation
Automatic derivation format:目标 : 其它依赖
Case demo 1:
If you use the automatic derivation mode to write the case in the previous level makefile
, there will be a more concise format, the specific operation is as follows:
- vim makefile
- make
- vim makefile
- object=main.o Add.o Sub.o Mul.o Div.o
- exe : $(object)
- gcc -o $@ $(object)
- main.o : def.h
[Please experience directly in the "command line" on the right]
It can be seen that we only need to main.o
create a compilation rule for 4
the target file, and there is no need to create a compilation rule for it, because make
the compilation rule will be automatically constructed for it.
programming requirements
The task of this level is makefile
an automatic derivation in learning. The specific programming requirements are as follows:
- Modify the previous level
makefile
, use automatic derivation to compile the project, and generate anAutoCalc
executable file named;
• vim makefile
1. object=main.o Add.o Sub.o Mul.o Div.o
2. AutoCalc : $(object)
3. gcc -o AutoCalc $(object)
4.
5. main.o : def.h
mission details
The task of this level: learn to use makefile
the false target.
related information
A rule for clearing object files (.o and execution files) should be written in each Makefile
, which is not only convenient for recompilation, but also very helpful for keeping files clean.
make install
Usually, when we use source code to install software, we will execute this command to install the software after compiling the software , or execute make clean
this command to clear the temporarily generated target files. The above operation is the use of makefile
the false target.
The false target that will be introduced in this level makefile
.
Makefile pseudo-target
makefile
Use .PHONY
keywords to define a pseudo-target, the specific format is:.PHONY : 伪目标名称
Case demo 1:
makefile
Clear the temporary object file label for the addition in the previous level case clean
, the specific operation is as follows:
- vim makefile
- make
- vim makefile
- object=main.o Add.o Sub.o Mul.o Div.o
- exe : $(object)
- gcc -o $@ $(object)
- main.o : def.h
- .PHONY : clean
- clean :
- rm $(object)
[Please experience directly in the "command line" on the right]
It can be seen that when we execute make
the command, multiple temporary files will be generated, and then make clean
after we execute the command, the generated temporary file will be deleted. In fact, executing make clean
the command is executing rm main.o Add.o Sub.o Mul.o Div.o
.
Case demo 2:
Use another format to clear the temporarily generated directory files and not display the delete command, the specific operation is as follows:
- vim makefile
- make
- vim makefile
- object=main.o Add.o Sub.o Mul.o Div.o
- exe : $(object)
- gcc -o $@ $(object)
- main.o : def.h
- clean :
- @echo "clean object files"
- @rm $(object)
[Please experience directly in the "command line" on the right]
As you can see, when we execute make clean
the command, the command will not be displayed in the terminal rm main.o Add.o Sub.o Mul.o Div.o
.
Note: If the ** ** symbol is added before the command @
, the command will not be output to the terminal as it is.
programming requirements
The task of this level is makefile
a false goal in the society. The specific programming requirements are as follows:
makefile
Add a pseudo-target that automatically cleans up temporary files for the previous levelclean
, and generate anAutoCleanCalc
executable file named ;
• vim makefile
1. object=main.o Add.o Sub.o Mul.o Div.o
2. AutoCleanCalc : $(object)
3. gcc -o AutoCleanCalc $(object)
4.
5. main.o : def.h
6.
7. .PHONY : clean
8.
9. clean :
10. rm $(object)