5 Makefile project management
Script file: put a series of commands in a file for batch execution
Name: makefile Makefile
One rule:
Objectives: dependencies
Command (1 table indent before the command)
Two functions:
#The wildcard function, together with wildcards, finds all the files in the folder . c Documents src=$(wildcard ./*.c) #Put all the c. replace the suffix of the document with o obj=$(patsubst %.c,%.o,$(src))
Three automatic variables:
The three automatic variables can only be used in the command line, not in targets and dependencies!!!
$@: represents the target file;
$<: the first clause representing dependency conditions;
$^: represents all dependency conditions;
5.1 a rule
basic principle:
1. If you want to generate a target, check whether the dependency condition in the rule exists. If it does not exist, look for whether there is a rule to generate the dependency file;
2. Check whether the target in the rule needs to be updated. First check all its dependencies. If there are updates in the dependencies, the target must be updated
1) Analyze the relationship between objectives and dependencies
2) Execute commands from bottom to top according to dependencies;
3) Determine the update according to the modification time is newer than the target;
4) If the target does not depend on any conditions, execute the corresponding command to show the update
The file directory is as follows:
daniel@daniel-Vostro-5471:~/file/OS/test/make_test/make1$ tree . ├── add.c ├── cal.h ├── Makefile ├── sub.c └── test.c 0 directories, 5 files
The corresponding Makefile files are as follows:
test: test.o add.o sub.o gcc test.o add.o sub.o -o test -I. test.o:test.c gcc -c test.c -o test.o add.o:add.c gcc -c add.c -o add.o sub.o:sub.c gcc -c sub.c -o sub.o #The advantage of separating each file is that when a single file is changed, other files do not need to be recompiled #Just compile the changed file and re link it
The make command checks the makefile file and takes the first statement as the ultimate goal; Therefore, it is best to put the overall generation steps at the front;
To solve the above disadvantages, you can use the ALL command to specify the final purpose of the makefile;
ALL:a.out
5.2 two functions
Two functions commonly used in makefile:
#Find all suffixes in the current directory c file, assigned to src src=$(wildcard ./*.c) #All suffixes in src variables are Replace the file of c with o #Replace the part of parameter 3 containing parameter 1 with parameter 2 obj=$(patsubst %.c,%.o,$(src))
$(src) represents the value of the function; After the above function is called, the variable
src= add.c sub.c test.c
obj=add.o sub.o test.o
With two functions, the makefile can be rewritten as follows:
#Specify the final goal ALL:main #Two functions are used, src variable represents the source file and obj represents the compiled file o documentation src=$(wildcard ./*.c) #add.c sub.c test.c obj=$(patsubst %.c,%.o,$(src)) #add.o sub.o test.o main:$(obj) gcc $(obj) -o main -I. test.o:test.c gcc -c test.c -o test.o -I. add.o:add.c gcc -c add.c -o add.o sub.o:sub.c gcc -c sub.c -o sub.o #If you execute the make clean command alone, the *. In the file will be deleted o file and main file deletion #add to The make clean -n option is to simulate the execution of the command, and the file to be deleted will be displayed on the command line clean: rm -rf $(obj) main
clean: -rm -rf $(obj) a.out #If you execute the make clean command alone, the *. In the file will be deleted o file and main file deletion #Add the make clean -n option to simulate the execution of commands
The clean command has no dependency. The "-" before rm is used to delete nonexistent files without reporting an error;
5.3 three automatic variables
3 automatic variables:
$@: in the command of the rule, it represents the target in the rule (it can not be used in the target or dependency);
$^: in the command of the rule, it represents all the dependency conditions of the rule;
$<: in the command of the rule, it represents the first dependency condition in the rule; If the automatic variable is applied to the pattern rule, it can successively take out the dependencies in the dependency condition list and apply the pattern rule;
With three automatic variables, the above makefile can be further rewritten as,
ALL:main src=$(wildcard ./*.c) #add.c sub.c test.c obj=$(patsubst %.c,%.o,$(src)) #add.o sub.o test.o main:$(obj) gcc $^ -o $@ -I. test.o:test.c gcc -c $< -o $@ -I. add.o:add.c gcc -c $< -o $@ sub.o:sub.c gcc -c $< -o $@ clean: -rm -rf $(obj) main
5.4 mode rules
The makefile in the previous section will each c compiled into o in the process of, the commands are the same, that is:
gcc -c $< -o $@
In this way, multiple instructions can be rewritten into the following form using pattern rules:
%.o:%.c gcc -c $< -o $@
The above makefile can be further rewritten as:
ALL:main src=$(wildcard ./*.c) #add.c sub.c test.c obj=$(patsubst %.c,%.o,$(src)) #add.o sub.o test.o main:$(obj) gcc $^ -o $@ -I. %.o:%.c gcc -c $< -o $@ clean: -rm -rf $(obj) #If you execute the make clean command alone, the *. In the file will be deleted o file and main file deletion #add to The make clean -n option is to simulate the execution of the command
Through multiple updates, the extensible function of makefile is realized. On the basis of the original file, a multiplication module, mul c. Makefiles do not need to be rewritten,
daniel@daniel-Vostro-5471:~/file/OS/test/make_test/make3$ tree ├── add.c ├── cal.h ├── makefile ├── mul.c ├── sub.c └── test.c 0 directories, 6 files
5.5 extension
Static mode rules:
The following statement is to the obj variable o files, generating c) documents;
$(obj):%.o:%c gcc -c $< -o $@
Generate pseudo target:
Example: add a clean file in the above folder, that is, use the command touch clean. The file directory is as follows:
daniel@daniel-Vostro-5471:~/file/OS/test/make_test/make3$ tree . ├── add.c ├── cal.h ├── clean ├── makefile ├── mul.c ├── sub.c └── test.c 0 directories, 7 files
If you execute the make clean command later, an error will appear:
daniel@daniel-Vostro-5471:~/file/OS/test/make_test/make3$ make clean make: "clean"Is up to date.
This is because the clean file in the folder interferes with the execution of the make clean file, especially in the clean command without dependencies. In this case, you can solve it by adding a pseudo target, as follows:
Pseudo target: do not generate files, but execute the target;
ALL:main src=$(wildcard ./*.c) #add.c sub.c test.c obj=$(patsubst %.c,%.o,$(src)) #add.o sub.o test.o main:$(obj) gcc $^ -o $@ -I. %.o:%.c gcc -c $< -o $@ clean: -rm -rf $(obj) #Pseudo target .PHONY:clean ALL
Add compilation parameters:
You can add compilation parameters to myArgs, and then make $(myArgs) take out the parameters;
ALL:main src=$(wildcard ./*.c) #add.c sub.c test.c obj=$(patsubst %.c,%.o,$(src)) #add.o sub.o test.o myArgs=-Wall -g main:$(obj) gcc $^ -o $@ -I. $(myArgs) %.o:%.c gcc -c $< -o $@ $(myArgs) clean: -rm -rf $(obj) #Pseudo target .PHONY:clean ALL
Library variable
It is a variable defined by yourself in the makefile library. Some variables have default values, while the variables defined by have no default values
CC: the default is CC =cc c language compiler
CPPFLAGS: C + + default parameter
CFLAGS: C default parameter
LDFLAGS: dynamic link parameters
Compile multiple file instances in the same directory at the same time:
daniel@daniel-Vostro-5471:~/file/OS/test/make_test/make5$ tree . ├── add.c ├── makefile ├── mul.c └── sub.c 0 directories, 4 files
Every%. Is required c files are compiled into a separate% out executable
The makefile is written as follows:
src=$(wildcard *.c) # obj=$(patsubst %.c,%.o,$(src)) out=$(patsubst %.c,%.out,$(src)) ALL: $(out) $(out):%.out:%.c gcc $< -o $@ clean: -rm -rf $(out) .PHONY:ALL clean
5.6 standard examples
The directory of the file is as follows:
daniel@daniel-Vostro-5471:~/file/OS/test/make_test/make4$ tree . ├── inc │ └── cal.h ├── main ├── makefile ├── obj └── src ├── add.c ├── mul.c ├── sub.c └── test.c
Requirement: put the compiled file into the obj directory
The makefile file is written as follows:
#Compile total target file ALL:main #set variable src=$(wildcard ./src/*.c) #./src/ add.c sub.c mul.c test.c # # %Equivalent substitution means to put the value of% taken from the first variable on the second% obj=$(patsubst ./src/%.c,./obj/%.o,$(src))#./obj/ add.o sub.o mul.o test.o # echo: # echo $(src) $(obj) #Header file location inc_path=./inc #Set compilation parameters myArgs=-Wall -g #compile main:$(obj) gcc $^ -o $@ $(myArgs) # Replace obj directory with src directory # Header file expansion runs in the preprocessing phase, so there is no need to add header files in line 17 $(obj):./obj/%.o:./src/%.c gcc -c $< -o $@ $(myArgs) -I $(inc_path) clean: -rm -rf $(obj) .PHONY: ALL clean
You can also run the command without using makefile. For example, give the file the name m6(mv makefile m6)
The operation method is: make -f m6
Many files are named: * * * * mk, which may be the makefile file
Make can perform multi-threaded compilation, make -j4 or make -j8