当前位置:网站首页>6. how to automatically generate header file dependency -m
6. how to automatically generate header file dependency -m
2022-06-11 10:38:00 【Qimu king · Prince】
How to automatically generate header file dependencies
When we compile , I hope it has been changed c file , Just compile that one c file , meanwhile , When changing a header file , You also want to include this header file c Files are also compiled . For the former ,make The default is to do this , And for the latter , But it needs our cooperation gcc Some options to achieve this .
To implement header file changes , That contains this header file c Files are also compiled , Need to be in Makefile It shows that c Dependency between file and header file , such as func.c It contains func.h, that Makefile If there are the following dependencies in , You can realize the change func.h after ,func.c Also compiled :
func.o:func.c func.h
such , Changed func.h It will automatically compile func.c Generate func.o.
gcc Provides a -M Options , To automatically generate such dependencies .-M Option will find the included system header files and other system header files , If we do not need to output the dependencies of the system header file , It can be used -MM Options . When we compile , add -MD Options , You can generate .o The position of the is automatically generated c Of documents .d Dependency file . Of course , Generated .d Dependency file , We also need to .d Dependent files are included in makefile Only in the middle , such make This dependency is only used when .
1. Why use a suffix of .d The dependent files of ?
stay Makefile in , Our dependencies may need to include a series of header files .
such as
main.c The content of the source file is as follows :
#include "stdio.h"
#include "defs.h"
int main(int argc, char *argv[])
{
printf("Hello, %s!\n", NAME);
return 0;
}
defs.h The header file is as follows :
#ifndef _DEFS_H_
#define _DEFS_H_
#define NAME "makefile"
#endif _DEFS_H_
# Then the dependencies should be as follows :
main.o : main.c stdio.h defs.h ...
But if it is a relatively large project , You must know every C What header files does the source file contain , And when adding or deleting header files , It also needs to be carefully modified Makefile, It's a very maintenance free job . In order to avoid such heavy and error prone things , We can use gcc A function of compilation . Most of the gcc Compilers support one “-M” The option to , That is to automatically find the header file contained in the source file , And generate a dependency . for example , Execute the following command :
gcc -M main.c
Its output is as follows :
main.o : main.c defs.h
Automatically generate dependencies by the compiler , The benefits of doing so are as follows :
- You don't have to write dependencies on several files manually , Generated automatically by compiler
- Whether it's .c The file or .h The document is updated , The target files will be recompiled
2. Parameter description
2.1 -M
Dependencies of generated files , At the same time, some standard library header files are also included . The essence is to tell the preprocessor to output a suitable make The rules of , Used to describe the dependency of each object file . For each source file , Preprocessor output One make The rules , The target item of the rule (target) Is the target file name corresponding to the source file , Dependencies (dependency) It's in the source file ‘#include’ All referenced files , The generated rule can be a single line , But if it's too long , Just use ’\’ The newline continues into multiple lines . The rules Display in standard output , No pretreated C Program .
Be careful : This option is turned on by default -E Options , -E Arguments are used to make the compiler stop compiling at the end of preprocessing
> for example : gcc -M main.c
> Then output the following on the terminal :
> main.o: main.c defs.h \
> /usr/include/stdio.h \
> /usr/include/features.h \
> /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \
> /usr/lib/gcc-lib/i486-suse-linux/2.95.3/include/stddef.h \
> /usr/include/bits/types.h \
> /usr/include/bits/pthreadtypes.h \
> /usr/include/_G_config.h /usr/include/wchar.h \
> /usr/include/bits/wchar.h /usr/include/gconv.h \
> /usr/lib/gcc-lib/i486-suse-linux/2.95.3/include/stdarg.h \
> /usr/include/bits/stdio_lim.h
>
2.2 -MM
Dependencies of generated files , and -M similar , But does not contain the header file of the standard library
for example :gcc -MM main.c Then output the following on the terminal : main.o: main.c defs.h
2.3 -MF File
When using the ‘-M’ perhaps ‘-MM’ Option , Then write the dependency to the file named ‘File’ In the file of . If you also use ‘-MD’ or ‘-MMD’,’-MF’ The name of the dependent file that will overwrite the output
for example :gcc -M -MF main.d main.c
be '—M' The output exists in main.d It's in the document
2.4 -MD
Equate to ‘-M -MF File’, But it's off by default ‘-E’ Options . The output file name is based on ‘-o’ Options , If given ‘-o’ Options , Then the output file name is ‘-o’ Specified file name , And add .d suffix , If not given , Then the input file name is used as the output file name , And add .d suffix , At the same time continue the specified compilation
Be careful :’-MD’ Don't like ‘-M’ That prevents normal compilation tasks . Because it is off by default ‘-E’ Options , For example, the command uses -c Options , The result is to generate .o file , If used ‘-M’ Options , Will not be generated .o file , If you use ‘-MD’ Options , It will generate .o file
for example 1:gcc -E -MD main.c
The following files are generated in this directory :
main.d
At the same time, it outputs main.c Preprocessing results of files
It is found that , Don't use '-o' Specify output file name , There are slight differences in the following situations :
gcc -E main.c // Don't use '-o', Output the result on the terminal
gcc -S main.c // Don't use '-o', By default, the result will be output to... With the name of the input file .s In file , namely main.s
gcc -c main.c // ditto
gcc main.o // Don't use '-o', Output the result to by default a.out In the executable
for example 2:gcc -E -o tmp.i -MD main.c
The following files are generated in this directory :
tmp.d tmp.i
for example 3:gcc -c -MD main.c
The following files are generated in this directory :
main.d main.o
for example 4:gcc -c -o tmp.o -MD main.c
The following files are generated in this directory :
tmp.d tmp.o
for example 5: gcc -MD main.c
The following files are generated in this directory :
a.out main.d
for example 6: gcc -M -MD main.c
The following files are generated in this directory :
main.d // It doesn't generate a.out Executable file , because '-M' It's on by default '-E' Options , Make the compiler stop compiling after preprocessing
2.5 -MMD
Be similar to ‘-MD’, But in the output dependency file , Does not contain standard header files
2.6 -MP
In the generated dependency file , All of the dependencies in the rule .h Dependencies will generate a pseudo target in this file , It does not depend on any other dependencies . This pseudo rule will avoid deleting the corresponding header file without updating “Makefile” To match a new dependency that results in make An error occurs .
( English description :This option instructs CPP to add a phony target for each dependency
other than the main file, causing each to depend on nothing. These
dummy rules work around errors ‘make’ gives if you remove header
files without updating the ‘Makefile’ to match.)
for example 1: gcc -c -MM -MD main.c
Generated main.d The contents of the document are as follows :
main.o: main.c defs.h
for example 2: gcc -c -MM -MD main.c -MP
Generated main.d The contents of the document are as follows :
main.o: main.c defs.h
defs.h: // This option will generate the pseudo target , It has no dependencies , If not used '-MP' Options , The pseudo target rule will not be generated
2.7 -MT Target
In the generated dependency file , Specify the target in the dependency rule
for example : gcc -MF main.d -MG -MM -MP -MT main.d -MT main.o main.c
$ cat main.d # View the contents of the generated dependency file
main.d main.o: main.c
notes : Dependency rules main.d and main.o The goal is through '-MT' Option specified
3. Examples of use
# Find files c.c The header file of depends on , Print out
gcc -M c.c
# hold c.c The header file of depends on writing to c.d In file
gcc -M -MF c.d c.c
# Both c.c The header file of depends on writing to c.d In file , And compile at the same time c.c File for c.o
gcc -c -o c.o c.c -MD -MF c.d
#makefile
%.o : %.c
gcc -c -o [email protected] $< -MD -MF [email protected]
The above is a brief introduction to gcc -M Related options , Designed to make Automatically derive and generate File Dependencies .
Here is a good example gcc -M Reference examples of options , It will automatically generate dependent files , And saved in the specified directory ‘.d’ In file .
3.1 makefile Example 1
SRCS=$(wildcard *.c)
OBJS=$(SRCS:.c=.o)
DEPS=$(SRCS:.c=.d)
.PHONY: all clean
all: main
-include $(DEPS)
# notes :'-' The role of No : Error loading , Will continue to execute make, Mainly considering the first make when , If it does not exist in the directory '*.d' When you file , Loading will cause an error and stop make Implementation
%.o:%.c
gcc -c -g -Wall $< -o [email protected] -MD -MF $*.d -MP
main: $(OBJS)
gcc $^ -o [email protected] # notes :$^: Represents all dependent files [email protected]: Represents the target file
clean:
rm -f *.d *.o main
The dependent files .d Whether there is , You can also use shell The judgment in the book . As the following example :
3.1 makefile Example 2
#makefile
objs = a.o b.o c.o
dep_files = $(patsubst % ,.%.d ,$(objs))
dep_files_exist = $(wildcard $(dep_files))
test : $(objs)
gcc -o test $^
ifneq ($(dep_files_exist),)
include $(dep_files_exist)
endif
%.o : %.c
gcc -c -o [email protected] $< -MD -MF [email protected]
clean:
rm *.o test
distclean:
$(dep_files)
.PHONY:
clean
4. Extended description
Makefile Many automatic variables are used in the file :
- [email protected] : Represents the target in a rule . When there are multiple targets in a rule ,[email protected] It refers to the target of any command that causes the rule to run
- $^ : Represents all dependencies in the rule
- $< : Represents the first dependency in the rule
for example Makefile The contents of the document are as follows :
target1 target2:dep1 dep2 dep3
@echo "Tar:[email protected], First Dep:$<, All Dep:$^"
dep1 dep2 dep3:
# notes : Do not write the target rule of this line , perform make Will report a mistake , because makefile Not only is there no dep1 dep2 dep3 file ,
#makefile There are no rules in the file that target these dependent files .
function make:
1. make target1 perhaps make ( Take the first goal in the document as the primary goal )
The output of the terminal is as follows :
Tar:target1, First Dep:dep1, All Dep:dep1 dep2 dep3
2. make target2
The output of the terminal is as follows :
Tar:target2, First Dep:dep1, All Dep:dep1 dep2 dep3
3. make target1 target2
The output of the terminal is as follows :
Tar:target2, First Dep:dep1, All Dep:dep1 dep2 dep3
Tar:target2, First Dep:dep1, All Dep:dep1 dep2 dep3
边栏推荐
猜你喜欢

Summary of common constraints in MySQL foundation part I

Pyspark case series 4-dataframe output to a single folder solution

Pyramidtnt: TNT with characteristic pyramid structure

班组级安全培训,新员工入职培训教育课件,全内容PPT套用

基于位置服务(LBS)的SSM的框架实现的兴趣社交软件平台设计与实现

Wechat cloud development al short video one click face changing applet source code

使用 Ribbon 实现客户端负载均衡

详述用网络分析仪测量DC-DC和PDN

【机器学习理论】True Positive, True Negative, False Positive, False Negative概念

TikTok在英国遭遇文化冲突,短期内众多员工离职
随机推荐
MySQL comparison
云开发mbti人格类型测试助手微信小程序源码
Fix the problem that uicollectionview does not reach the bottom security zone
Gamefi: everything you need to know about the "play and earn" game economy
C#入门系列(十一) -- 多维数组
Leetcode 1952. 三除数
Correct opening method of RPC | understand go native net/rpc package
Unity字体间距
Cadence OrCAD capture design method to avoid misoperation graphic tutorial
Common techniques for handling dates
[audio and video] Introduction to SEI
6.如何自动生成头文件依赖 -M
云画质助手iApp源码
Wechat cloud development al short video one click face changing applet source code
修复UICollectionView 没有到达底部安全区的问题
C+ daily exercises (15)
C语言课程设计题目
金仓数据库KingbaseES中的PL/SQL 编译检查
Safety related website recommendations
C # introductory series (11) -- multidimensional array