当前位置:网站首页>Makefile foundation, common functions and general makefile
Makefile foundation, common functions and general makefile
2022-04-23 06:46:00 【tilblackout】
1. Basics
The process of compiling a program
- Preprocessing :① Insert the included header file into the source file ② Expand macro definition ③ Select the code to use according to conditional compilation ④ Finally, output the code to a
.i
File format - compile : hold C/C++ Code (
.i
file ) Translate into.s
Assembly code - assembly : hold
.s
The document is translated into.o
Machine code in format - link : hold
.o
file 、 Library files, etc , Generate executable files .
The rules :
The goal is : rely on 1 rely on 2 ...
<TAB> command
- Conditions for command execution : The dependent file is newer than the target file or No target file
Static mode :
<targets ...>:<target-pattern>:<prereq-patterns...>
<commands>
targets
: Define a series of object files , Wildcards are allowedtarget-parrtern
:targets
The pattern of , Target set modeprereq-parrterns
: Target dependent patterns , It's righttarget-parrtern
The formed pattern defines the dependency target again
example :
objects = a.o b.o c.S
$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
because target-parrtern
by %.o, So take objects In variables a.o
and b.o
, They depend on a.c
and b.c
, above Makefile Equivalent to
a.o:a.c
$(CC) -c $(CFLAGS) $< -o $@
b.o:b.c
$(CC) -c $(CFLAGS) $< -o $@
Of course, it can also be omitted targets
, direct writing <target-pattern>:<prereq-patterns...>
, So all the satisfaction <target-pattern>
All files will be matched , Not in targets
Find satisfaction in <target-pattern>
The file of .
Implicit rules
Common usage :
foo:foo.o bar.o
gcc -o foo foo.o bar.o
above Makefile It is not written in the document foo.o
as well as bar.o
File generation rules , But according to the implicit rules ,make
The command will automatically find foo.c
as well as bar.c
And call cc
The command source file will be generated foo.o
and bar.o
.
Assignment method
=
: The most basic assignment?=
: If it has not been assigned, give the value after the equal sign:=
: Overwrite previous values+=
: Add the value after the equal sign
=
and ?=
The delay variable is defined , That is, the value of this variable is determined when it is actually used .:=
Is an immediate variable , When defined, its value is determined .+=
The previous variables determine what variables .
$@
: Refers to the target file list under the current rule
$<
: Refers to the first dependent file in the dependent file list
$^
: Refers to all dependent files in the dependent file list
$?
: Refers to the new file list corresponding to the target file in the dependent file list
Conceptual differentiation
(1)%
and *
The difference between : Both are wildcards .*
in the light of Linux System ;%
Aiming at the present Makefile The content of the document , As the goal 、 Dependency .
(2)$()
and ${}
: stay shell in $()
Followed by an instruction ,${}
Followed by a variable ; stay Makefile in $()
and ${}
Equivalent when followed by variables , If you want to call the instruction, you need to add “shell”:$(shell Instructions )
Other
(1) Find... According to the cross compiler libgcc
The path of the library
arm-linux-gcc -print-libgcc-file-name
(2)export Variable
The variable and its value will be added to the current working environment variable , In the future make This variable can be used for all regular commands executed , Usually used to give children Makefile use .
(3)VPATH
make
Can identify Makefile The name defined in is VPATH
The variable of , It defines the search directory for dependent files
(4).PHONY Fake target
Common functions
Here are just a few commonly used , The function call format is :
$(function arguments)
1.patsubst
: seek text
In accordance with the format pattern
The content of , use replacement
Replace them .pattern
and replacement
You can use wildcards in %
$(patsubst pattern,replacement,text)
$(patsubst %.c,%.o,x.c.c bar.c)// The result is x.c.o bar.o
2.filter
: Take out text
In accordance with the format pattern...
The content of
$(filter pattern...,text)
$(filter %.c %.s,foo.c bar.c baz.s ugh.h)// The result is foo.c bar.c baz.s
filter-out
Is to remove the matching formatpattern...
The content of
3.wildcard
: Get files in directory
$(wildcard pattern)
There are files in the current directory 1.c、2.c、1.h、2.h, be :
c_src := $(wildcard *.c)// The result is 1.c 2.c
4.foreach
: Cyclic operation
The cycle will list
Take out and assign to var
, And then execute text
The instructions in ( Instructions generally contain var
)
$(foreach var,list,text)
objs := a b c d
dep_files := $(foreach f,$(objs),.$(f).d)// The result is a.d b.d c.d d.d
5. Replace text in variable ( Take the replacement suffix as an example )
var := a.c b.c
$(var:%.c=%.o) or ${var:.c=.o} # The result is a.o b.o
2. Write general Makefile
Let's have a look at Makefile
test:a.o b.o
gcc -o test a.o b.o
%.o:%.c
gcc -c -o $@ $<
If a.c
There is a header file a.h
, The user only modified a.h
, And because a.h
Not in dependence , be gcc
Will not be executed . And if each .c
The header of the file is written to Makefile in , Such as a.o:a.c a.h
, It's too much trouble .
solve : adopt GCC Compilation options -Wp,-MD
Generate .c
Files dependent on files .
Such as a.c File execution gcc -Wp,-MD,.a.o.d -c -o a.o a.c
, It will generate a a.o.d
, The contents are as follows
a.o:a.c xx.h yy.h # hypothesis a.c Contains header files xx.h and yy.h
Take the following engineering structures as an example , Modelled on the Linux The kernel writes a general Makefile
The build process :
- hold display In the catalog test The directory test.c Translate it into
test.o
, And will all .o The files are packed intobuilt-in.o
- Then go back to the previous level display Catalog , hold
disp_manager.c
andfb.c
Translate it into .o file - hold
disp_manager.o
、fb.o
and test In the catalogbuilt-in.o
Pack it up display In the catalogbuilt-in.o
- After several directories .c The file is compiled and packaged into
built-in.o
after ,main.c
It's also compiled intomain.o
, And then putmain.o
Of the subdirectory corresponding to its directorybuilt-in.o
Package into the top-level Directorybuilt-in.o
- Finally, link to the target file
(1) top floor Makefile
CROSS_COMPILE = arm-linux-
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
# Export variables to Makefile.build use
export AS LD CC CPP AR NM
export STRIP OBJCOPY OBJDUMP
# Specify compilation parameters : -Wall: Turn on all warnings ; -O2: Optimization options ; -g: Add debugging information
CFLAGS := -Wall -O2 -g
# Specify the directory of the compilation header file // If no header file directory is specified , Default to /usr/include look for
CFLAGS += -I $(shell pwd)/include
# Specify connection parameters : -lm: Represent math library ; -lfreetype: Express freetype library
LDFALGS := -lm -lfreetype
# export CFLAGS LDFALGS
export CFLAGS LDFALGS
TOPDIR := $(shell pwd)
export TOPDIR
# The final compiled object file show_file
TARGET := show_file
#obj-y Assign a value to the top layer of main.o And all directories
obj-y += main.o
obj-y += display/
obj-y += draw/
obj-y += encoding/
obj-y += fonts/
# The first rule
all :
#-C Followed by a directory , That is, enter the top-level directory to execute make,-f Followed by a file , The box Makefile.build Recursively compile each directory
make -C ./ -f $(TOPDIR)/Makefile.build
# stay Makefile.build Recursion finally generates the top-level built-in.o, Link it to generate the final file
$(CC) $(LDFALGS) -o $(TARGET) built-in.o
# eliminate
clean:
rm -rf $(shell find -name "*.o")
rm -rf $(TARGET)
distclean:
rm -rf $(shell find -name "*.o")
rm -rf $(shell find -name "*.d")
rm -rf $(TARGET)
From the above target all
The following instructions show , All directories are through Makefile.build
Compile according to the rules in this file ,Makefile.build
Each directory will be recursive in , Finally, the top-level Directory build-in.o
Generate executable files $(TARGET)
, namely showfile
.
(2)Makefile.build
# Fake target , That is the objective of this document
PHONY := __build
__build: # similar C Function declaration , Specific dependencies are defined later , The purpose is to declare as the first goal
# Initialize all variables that will be used : Make sure the type is correct 、 Does not inherit values from environment variables
obj-y :=
subdir-y :=
# Contains the current directory Makefile, It's going to be right. obj-y assignment
include Makefile
# Take out obj-y Defined subdirectories , And put "/" Get rid of ( It is stipulated that the catalogue should be followed by /)
__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))
subdir-y += $(__subdir-y)
# Of all subdirectories built-in.o, namely subdir_objs = dir1/built-in.o dir2/built-in.o
subdir_objs := $(foreach f,$(subdir-y),$(f)/built-in.o)
# Take out obj-y Defined xxx.o
cur_objs := $(filter-out %/, $(obj-y))
# Dependency file
dep_files := $(foreach f,$(cur_objs),.$(f).d) # Under the table of contents xxx.o The dependent file corresponding to the file is .xxx.d
dep_files := $(wildcard $(dep_files)) # if .xxx.d non-existent , Remove... From the variable
ifneq ($(dep_files),) # If it is not empty, it contains dependent files
include $(dep_files)
endif
PHONY += $(subdir-y) # Each directory name of a subdirectory is defined as a pseudo target
#__build It's a fake target , It is also the first stated goal , The pseudo target depends on the corresponding command 100% Will be performed
__build:$(subdir-y) built-in.o # Depends on the subdirectory and the of the directory built-in.o
# Enter the subdirectory to compile ( The top-level directory and each subdirectory are recursively stored in the top-level Makefile.build To compile the )
$(subdir-y):
make -C $@ -f $(TOPDIR)/Makefile.build #-C To enter that directory ,-f Use the top-level directory Makefile.build To compile the
# All of the current directory xxx.o Packaged with subdirectories built-in.o Generate the of the current directory built-in.o
built-in.o: $(cur_objs) $(subdir_objs)
$(LD) -r -o $@ $^ #-r: See explanation below
# Generate dependent files in the current directory , Such as xx.c The file corresponds to the generated file .xx.d Dependency file , This variable is used below
dep_file = .$@.d # The previous statement is dep_files
%.o : %.c # all .o File generation rules , Generate dependencies at the same time
$(CC) $(CFLAGS) -Wp,-MD, $(dep_file) -c -o $@ $<
.PHONY : $(PHONY) # Such as PHONY In variables subdir-y, The above... Will be executed unconditionally $(subdir-y): Of make command
among ld -r
Of -r
by relocateable, That is, a relocatable output . An output file is generated , It can be used again as ’ld
' The input of , This is often called " Part of the connection ".
(3) Under each directory Makefile
from Makefile.build
It can be seen from the documents , It declares a variable obj-y
, And then include
Under each directory Makefile
, So... Under each directory Makefile Just add the files and directories in this directory to the variable obj-y
in , At the end of the directory, add a /
, With display In the catalog Makefile For example :
obj-y += disp_manager.o
obj-y += fb.o
obj-y += test/ #test Is a subdirectory under the subdirectory , There's one in there, too Makefile
Finally, execute... In the top-level directory make
Command to generate the final executable .
版权声明
本文为[tilblackout]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204230549283041.html
边栏推荐
猜你喜欢
[UDS unified diagnosis service] IV. typical diagnosis service (1) - diagnosis and communication management function unit
JS中 t, _ => 的解析
File viewing commands and user management commands
OpenCV使用 GenericIndex 进行 KNN 搜索
VHDL finite state machine (FSM) code example
基于VGG卷积神经网络的图像识别代码实现
PN结、二极管原理详解与应用
深蓝学院激光slam 理论与实践 第三章激光雷达去畸变 作业习题
For() loop parameter call order
Collection of practical tips for C language (continuously updated)
随机推荐
HDU-Tunnel Warfare
客户端软件增量更新
[UDS unified diagnostic service] II. Network layer protocol (1) - overview and functions of network layer
日志写法(带时间)
ES6
【UDS统一诊断服务】一、诊断概述(1)— 诊断概述
产生随机数
浮点数双精度,单精度以及半精度知识总结
欢迎使用Markdown编辑器
cv_bridge 与opencv 版本不匹配的解决
Installation of GCC, G + +, GDB
微信小程序之 js 时间戳/1000 转换 秒,六个小时后,一天后,本周五 选项计算时间
C语言实现memcpy、memset、strcpy、strncpy、strcmp、strncmp、strlen
ARM常用汇编指令
Shell脚本 单引号、双引号和反引号的区别
POJ-The Unique MST
QT icon application
Palindromic Primes
修改注册表的值
往String原型上封装一个时间戳转日期的方法