scripts/Makefile.host 分析【fixdep、conf】

文章目录

  • [1. 目标 (obj)/fixdep](#1. 目标 (obj)/fixdep)
    • [1.1 cmd_host-csingle函数分析:](#1.1 cmd_host-csingle函数分析:)
  • [2. 目标 (obj)/conf](#2. 目标 (obj)/conf)
bash 复制代码
1  	# SPDX-License-Identifier: GPL-2.0
2  	# ==========================================================================
3  	# Building binaries on the host system
4  	# Binaries are used during the compilation of the kernel, for example
5  	# to preprocess a data file.
6  	#
7  	# Both C and C++ are supported, but preferred language is C for such utilities.
8  	#
9  	# Sample syntax (see Documentation/kbuild/makefiles.txt for reference)
10 	# hostprogs-y := bin2hex
11 	# Will compile bin2hex.c and create an executable named bin2hex
12 	#
13 	# hostprogs-y    := lxdialog
14 	# lxdialog-objs := checklist.o lxdialog.o
15 	# Will compile lxdialog.c and checklist.c, and then link the executable
16 	# lxdialog, based on checklist.o and lxdialog.o
17 	#
18 	# hostprogs-y      := qconf
19 	# qconf-cxxobjs   := qconf.o
20 	# qconf-objs      := menu.o
21 	# Will compile qconf as a C++ program, and menu as a C program.
22 	# They are linked as C++ code to the executable qconf
23 
24 	__hostprogs := $(sort $(hostprogs-y) $(hostprogs-m))
25 	host-cshlib := $(sort $(hostlibs-y) $(hostlibs-m))
26 	host-cxxshlib := $(sort $(hostcxxlibs-y) $(hostcxxlibs-m))
27 
28 	# C code
29 	# Executables compiled from a single .c file
30 	host-csingle	:= $(foreach m,$(__hostprogs), \
31 				$(if $($(m)-objs)$($(m)-cxxobjs)$($(m)-sharedobjs),,$(m)))
32 
33 	# C executables linked based on several .o files
34 	host-cmulti	:= $(foreach m,$(__hostprogs),\
35 			   $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m))))
36 
37 	# Shared object libraries
38 	host-shared	:= $(foreach m,$(__hostprogs),\
39 			   $(if $($(m)-sharedobjs),$(m))))
40 
41 	# Object (.o) files compiled from .c files
42 	host-cobjs	:= $(sort $(foreach m,$(__hostprogs),$($(m)-objs)))
43 
44 	# C++ code
45 	# C++ executables compiled from at least one .cc file
46 	# and zero or more .c files
47 	host-cxxmulti	:= $(foreach m,$(__hostprogs),$(if $($(m)-cxxobjs),$(m)))
48 
49 	# C++ Object (.o) files compiled from .cc files
50 	host-cxxobjs	:= $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs)))
51 
52 	# Object (.o) files used by the shared libaries
53 	host-cshobjs	:= $(sort $(foreach m,$(host-cshlib),$($(m:.so=-objs))))
54 	host-cxxshobjs	:= $(sort $(foreach m,$(host-cxxshlib),$($(m:.so=-objs))))
55 
56 	host-csingle	:= $(addprefix $(obj)/,$(host-csingle))
57 	host-cmulti	:= $(addprefix $(obj)/,$(host-cmulti))
58 	host-cobjs	:= $(addprefix $(obj)/,$(host-cobjs))
59 	host-cxxmulti	:= $(addprefix $(obj)/,$(host-cxxmulti))
60 	host-cxxobjs	:= $(addprefix $(obj)/,$(host-cxxobjs))
61 	host-cshlib	:= $(addprefix $(obj)/,$(host-cshlib))
62 	host-cxxshlib	:= $(addprefix $(obj)/,$(host-cxxshlib))
63 	host-cshobjs	:= $(addprefix $(obj)/,$(host-cshobjs))
64 	host-cxxshobjs	:= $(addprefix $(obj)/,$(host-cxxshobjs))
65 	host-shared	:= $(addprefix $(obj)/,$(host-shared))
66 
67 	#####
68 	# Handle options to gcc. Support building with separate output directory
69 
70 	_hostc_flags   = $(KBUILD_HOSTCFLAGS)   $(HOST_EXTRACFLAGS)   \
71 					 $(HOSTCFLAGS_$(basetarget).o)
72 	_hostcxx_flags = $(KBUILD_HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \
73 					 $(HOSTCXXFLAGS_$(basetarget).o)
74 
75 	ifeq ($(KBUILD_SRC),)
76 	__hostc_flags	= $(_hostc_flags)
77 	__hostcxx_flags	= $(_hostcxx_flags)
78 	else
79 	__hostc_flags	= -I$(obj) $(call flags,_hostc_flags)
80 	__hostcxx_flags	= -I$(obj) $(call flags,_hostcxx_flags)
81 	endif
82 
83 	hostc_flags    = -Wp,-MD,$(depfile) $(__hostc_flags)
84 	hostcxx_flags  = -Wp,-MD,$(depfile) $(__hostcxx_flags)
85 
86 	#####
87 	# Compile programs on the host
88 
89 	# Create executable from a single .c file
90 	# host-csingle -> Executable
91 	quiet_cmd_host-csingle 	= HOSTCC  $@
92 		  cmd_host-csingle	= $(HOSTCC) $(hostc_flags) -o $@ $< \
93 			$(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(@F))
94 	$(host-csingle): $(obj)/%: $(src)/%.c FORCE
95 		$(call if_changed_dep,host-csingle)
96 
97 	# Link an executable based on list of .o files, all plain c
98 	# host-cmulti -> executable
99 	quiet_cmd_host-cmulti	= HOSTLD  $@
100		  cmd_host-cmulti	= $(HOSTCC) $(KBUILD_HOSTLDFLAGS) -o $@ \
101				  $(addprefix $(obj)/,$($(@F)-objs)) \
102				  $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(@F))
103	$(host-cmulti): FORCE
104		$(call if_changed,host-cmulti)
105	$(call multi_depend, $(host-cmulti), , -objs)
106
107	# Create .o file from a single .c file
108	# host-cobjs -> .o
109	quiet_cmd_host-cobjs	= HOSTCC  $@
110		  cmd_host-cobjs	= $(HOSTCC) $(hostc_flags) -c -o $@ $<
111	$(host-cobjs): $(obj)/%.o: $(src)/%.c FORCE
112		$(call if_changed_dep,host-cobjs)
113
114	# Link an executable based on list of .o files, a mixture of .c and .cc
115	# host-cxxmulti -> executable
116	quiet_cmd_host-cxxmulti	= HOSTLD  $@
117		  cmd_host-cxxmulti	= $(HOSTCXX) $(KBUILD_HOSTLDFLAGS) -o $@ \
118				  $(foreach o,objs cxxobjs,\
119				  $(addprefix $(obj)/,$($(@F)-$(o)))) \
120				  $(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(@F))
121	$(host-cxxmulti): FORCE
122		$(call if_changed,host-cxxmulti)
123	$(call multi_depend, $(host-cxxmulti), , -objs -cxxobjs)
124
125	# Create .o file from a single .cc (C++) file
126	quiet_cmd_host-cxxobjs	= HOSTCXX $@
127		  cmd_host-cxxobjs	= $(HOSTCXX) $(hostcxx_flags) -c -o $@ $<
128	$(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE
129		$(call if_changed_dep,host-cxxobjs)
130
131	# Compile .c file, create position independent .o file
132	# host-cshobjs -> .o
133	quiet_cmd_host-cshobjs	= HOSTCC  -fPIC $@
134		  cmd_host-cshobjs	= $(HOSTCC) $(hostc_flags) -fPIC -c -o $@ $<
135	$(host-cshobjs): $(obj)/%.o: $(src)/%.c FORCE
136		$(call if_changed_dep,host-cshobjs)
137
138	# Compile .c file, create position independent .o file
139	# Note that plugin capable gcc versions can be either C or C++ based
140	# therefore plugin source files have to be compilable in both C and C++ mode.
141	# This is why a C++ compiler is invoked on a .c file.
142	# host-cxxshobjs -> .o
143	quiet_cmd_host-cxxshobjs	= HOSTCXX -fPIC $@
144		  cmd_host-cxxshobjs	= $(HOSTCXX) $(hostcxx_flags) -fPIC -c -o $@ $<
145	$(host-cxxshobjs): $(obj)/%.o: $(src)/%.c FORCE
146		$(call if_changed_dep,host-cxxshobjs)
147
148	# Link a shared library, based on position independent .o files
149	# *.o -> .so shared library (host-cshlib)
150	quiet_cmd_host-cshlib	= HOSTLLD -shared $@
151		  cmd_host-cshlib	= $(HOSTCC) $(HOSTLDFLAGS) -shared -o $@ \
152				  $(addprefix $(obj)/,$($(@F:.so=-objs))) \
153				  $(HOST_LOADLIBES) $(HOSTLDLIBS_$(@F))
154	$(host-cshlib): FORCE
155		$(call if_changed,host-cshlib)
156	$(call multi_depend, $(host-cshlib), .so, -objs)
157
158	# Link a shared library, based on position independent .o files
159	# *.o -> .so shared library (host-cxxshlib)
160	quiet_cmd_host-cxxshlib	= HOSTLLD -shared $@
161		  cmd_host-cxxshlib	= $(HOSTCXX) $(HOSTLDFLAGS) -shared -o $@ \
162				  $(addprefix $(obj)/,$($(@F:.so=-objs))) \
163				  $(HOST_LOADLIBES) $(HOSTLDLIBS_$(@F))
164	$(host-cxxshlib): FORCE
165		$(call if_changed,host-cxxshlib)
166	$(call multi_depend, $(host-cxxshlib), .so, -objs)
167
168	targets += $(host-csingle)  $(host-cmulti) $(host-cobjs)\
169		   $(host-cxxmulti) $(host-cxxobjs) $(host-shared) \
170		   $(host-cshlib) $(host-cshobjs) $(host-cxxshlib) $(host-cxxshobjs)
171

1. 目标 $(obj)/fixdep

由于目标是 $(obj)/fixdep,所以自动匹配第94-95行:

bash 复制代码
94 $(host-csingle): $(obj)/%: $(src)/%.c FORCE
95 	  $(call if_changed_dep,host-csingle)

1.第94行中的 $(host-csingle) 在第24-56行中定义:

bash 复制代码
24 __hostprogs  := $(sort $(hostprogs-y) $(hostprogs-m))
30 host-csingle	:= $(foreach m,$(__hostprogs), \
31                $(if $($(m)-objs)$($(m)-cxxobjs)$($(m)-sharedobjs),,$(m)))
56 host-csingle	:= $(addprefix $(obj)/,$(host-csingle))

addprefix函数、sort函数、foreach函数

第24行:由于顶层 Makefile 的482行执行make -f ./scripts/Makefile.build obj=scripts/basic<见执行依赖scripts_basic>,又在 Makefile.build 中第57行引用scripts/basic/Makefile<见1.1>,在 scripts/basic/Makefile 中定义hostprogs-y := fixdep,hostprogs-m 未定义,所以最终: __hostprogs = fixdep

第30行:由于第24行的变量定义,所以最终: host-csingle = fixdep

第56行:由第30行定义,所以最终: host-csingle = $(obj)/fixdep

2.第94行中的 (obj) 和 (src) 在 scripts/Makefile.build 的第7-15行中定义,所以最终: (obj) = (src)

bash 复制代码
7  prefix := tpl
8  src := $(patsubst $(prefix)/%,%,$(obj))
9  ifeq ($(obj),$(src))
10 prefix := spl
11 src := $(patsubst $(prefix)/%,%,$(obj))
12 ifeq ($(obj),$(src))
13 prefix := .
14 endif
15 endif

第94-95行最终展开为:

bash 复制代码
94 $(obj)/fixdep: $(obj)/%: $(obj)/%.c FORCE
95 	  $(call if_changed_dep,host-csingle)

这里目标$(obj)/fixdep的生成,依赖$(src)/%.c,其目录下存在此类文件【fixdep.c】,经过 if_changed_dep函数 分析可知,打印和执行 cmd_host-csingle 函数,在执行的时候目标 (obj)/fixdep 就已经生成完成, 并通过 (obj)/fixdep 工具将实现目标 (obj)/fixdep 所用的命令、源码、头文件等信息全部写入到 `(obj)/.fixdep.cmd`文件中。

**最终:**打印和执行 cmd_host-csingle 函数【即生成 scripts/basic/fixdep 工具】,将实现目标 $(obj)/fixdep 所用的命令、源码、头文件等信息全部写入到 scripts/basic/.fixdep.cmd文件中。

bash 复制代码
92 cmd_host-csingle = cc -Wp,-MD,scripts/basic/.fixdep.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer   -std=gnu11     -o scripts/basic/fixdep scripts/basic/fixdep.c   
94 scripts/basic/fixdep: scripts/basic/fixdep: scripts/basic/fixdep.c FORCE
95 	  $(cmd_host-csingle)

1.1 cmd_host-csingle函数分析:

bash 复制代码
91 quiet_cmd_host-csingle 	= HOSTCC  $@
92       cmd_host-csingle	= $(HOSTCC) $(hostc_flags) -o $@ $< \
93 	  	$(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(@F))

第92行:$(HOSTCC) 在顶层 Makefile 的282行定义 HOSTCC = cc

第92行:$(hostc_flags) 在83行定义:

bash 复制代码
70 _hostc_flags   = $(KBUILD_HOSTCFLAGS)   $(HOST_EXTRACFLAGS)   \
71                 $(HOSTCFLAGS_$(basetarget).o)
72 _hostcxx_flags = $(KBUILD_HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \
73                 $(HOSTCXXFLAGS_$(basetarget).o)
74
75 ifeq ($(KBUILD_SRC),)
76 __hostc_flags	= $(_hostc_flags)
77 __hostcxx_flags	= $(_hostcxx_flags)
78 else
79 __hostc_flags	= -I$(obj) $(call flags,_hostc_flags)
80 __hostcxx_flags	= -I$(obj) $(call flags,_hostcxx_flags)
81 endif
82
83 hostc_flags    = -Wp,-MD,$(depfile) $(__hostc_flags)
84 hostcxx_flags  = -Wp,-MD,$(depfile) $(__hostcxx_flags)
......
83 hostc_flags    = -Wp,-MD,$(depfile) $(__hostc_flags)

第83行:$(depfile) 在scripts/Kbuild.include 【在顶层Makefile的396行引用】的20行定义:

最终: depfile = (obj)/.(notdir $@).cmd
dir函数、notdir 函数、subst 函数

bash 复制代码
5  comma   := ,
15 dot-target = $(dir $@).$(notdir $@)
20 depfile = $(subst $(comma),_,$(dot-target).d)

第83行:(__hostc_flags),当输入`make O=dir`时,`KBUILD_SRC=dir`,由于这里没有`O=`,所以第75行条件成立,执行第76行,第76行中的 (_hostc_flags) 在第70行中定义,其中的 $(HOST_EXTRACFLAGS) $(HOSTCFLAGS_$(basetarget).o) 未定义为空,$(KBUILD_HOSTCFLAGS)在顶层 Makefile 中定义为:-Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu11

最终: hostc_flags = -Wp,-MD,scripts/basic/.fixdep.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu11

第93行:@F介绍$(KBUILD_HOSTLDLIBS) $(HOSTLDLIBS_$(@F) 未定义为空

最终:

bash 复制代码
cmd_host-csingle = cc -Wp,-MD,$(obj).$(notdir $@).cmd -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer   -std=gnu11     -o $@ $<

2. 目标 $(obj)/conf

由于目标是 $(obj)/conf,所以自动匹配第94-95行:

bash 复制代码
94 $(host-csingle): $(obj)/%: $(src)/%.c FORCE
95 	  $(call if_changed_dep,host-csingle)

1.第94行中的 $(host-csingle) 在第24-56行中定义:

bash 复制代码
24 __hostprogs  := $(sort $(hostprogs-y) $(hostprogs-m))
30 host-csingle	:= $(foreach m,$(__hostprogs), \
31                $(if $($(m)-objs)$($(m)-cxxobjs)$($(m)-sharedobjs),,$(m)))
56 host-csingle	:= $(addprefix $(obj)/,$(host-csingle))

addprefix函数、sort函数、foreach函数

第24行:由于顶层 Makefile 的564行执行make -f ./scripts/Makefile.build obj=scripts/kconfig rpi_3_32b_defconfig<见实现%config>,又在 Makefile.build 的57行引用scripts/kconfig/Makefile<见2.1>,在 scripts/basic/Makefile 中定义hostprogs-y := fixdep,hostprogs-m 未定义,所以最终: __hostprogs = fixdep

第30行:由于第24行的变量定义,所以最终: host-csingle = fixdep

第56行:由第30行定义,所以最终: host-csingle = $(obj)/fixdep

2.第94行中的 (obj) 和 (src) 在 scripts/Makefile.build 的第7-15行中定义,所以最终: (obj) = (src)

bash 复制代码
7  prefix := tpl
8  src := $(patsubst $(prefix)/%,%,$(obj))
9  ifeq ($(obj),$(src))
10 prefix := spl
11 src := $(patsubst $(prefix)/%,%,$(obj))
12 ifeq ($(obj),$(src))
13 prefix := .
14 endif
15 endif

第94-95行最终展开为:

bash 复制代码
94 $(obj)/fixdep: $(obj)/%: $(obj)/%.c FORCE
95 	  $(call if_changed_dep,host-csingle)
相关推荐
懒羊羊大王呀4 分钟前
Ubuntu20.04中MySQL的安装和配置
linux·mysql·ubuntu
浅安的邂逅10 分钟前
Ubuntu apt-get安装-报错:尝试“apt --fix-broken install”有未能满足的依赖关系,几种解决办法
linux·ubuntu·apt install
爱瑞瑞1 小时前
🐧深入浅出的认识 Linux 指令
linux·shell
ajassi20002 小时前
开源 java android app 开发(十一)调试、发布
android·java·linux·开源
小李飞刀李寻欢2 小时前
使用kubeadm部署Kubernetes(k8s)集群的步骤
linux·服务器·ubuntu·kubernetes·k8s
运维成长记2 小时前
阿里云实践创建实例步骤
linux·运维·服务器·阿里云·云计算
THe CHallEnge of THe BrAve2 小时前
Linux检验库是否安装成功
linux·运维·服务器
算家计算3 小时前
告别复杂文档解析噩梦!MonkeyOCR 本地部署教程:支持公式/表格多元素结构化
linux·人工智能·开源
曹勖之4 小时前
ROS2 工作空间中, CMakeLists.txt, setup.py和 package.xml的作用分别是?
xml·linux·服务器·ros2
企鹅侠客4 小时前
ttyd:安全地通过网络共享您的 Linux 终端
linux·运维·ttyd