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)
相关推荐
keep__go1 小时前
Linux 批量配置互信
linux·运维·服务器·数据库·shell
矛取矛求1 小时前
Linux中给普通账户一次性提权
linux·运维·服务器
Fanstay9851 小时前
在Linux中使用Nginx和Docker进行项目部署
linux·nginx·docker
大熊程序猿1 小时前
ubuntu 安装kafka-eagle
linux·ubuntu·kafka
daizikui3 小时前
Linux文件目录命令
linux·运维·服务器
NikitaC3 小时前
ldconfig 和 LD_LIBRARY_PATH 区别
linux·c++
清源妙木真菌3 小时前
Linux:进程概念
linux
许嵩664 小时前
IC 脚本之VIM 记录
linux·编辑器·vim
花生的酱5 小时前
Shell编程之正则表达式与文本处理器
linux·运维·正则表达式