[关闭]
@cyysu 2017-10-16T08:27:21.000000Z 字数 6705 阅读 1580

Makefile-项目篇(三)

  • 时间:2017年10月16日
  • 作者:Kali
  • 邮箱:cyysu.github.io@gmail.com
  • 版本:3.0
  • 描述:Makefile-项目三,Linux 4.4 Makefile讲解,同时还可以了解Linux的编译过程

Makefile系列教程


项目实战

  1. # 在本此项目中先给出前250行内容,我们慢慢分析这个顶层Makefile
  2. VERSION = 4
  3. PATCHLEVEL = 4
  4. SUBLEVEL = 92
  5. EXTRAVERSION =
  6. NAME = Blurry Fish Butt
  7. # *DOCUMENTATION*
  8. # To see a list of typical targets execute "make help"
  9. # More info can be located in ./README
  10. # Comments in this file are targeted only to the developer, do not
  11. # expect to learn how to build the kernel reading this file.
  12. # o Do not use make's built-in rules and variables
  13. # (this increases performance and avoids hard-to-debug behaviour);
  14. # o Look for make include files relative to root of kernel src
  15. # 这里-r表示禁止使用隐含规则 -R禁止使用任何作用于变量上的隐含规则
  16. MAKEFLAGS += -rR --include-dir=$(CURDIR)
  17. # Avoid funny character set dependencies
  18. # Makefile中的变量设置,如果不想传递变量到下一级的Makefile就可以采用unexport
  19. # 如果想传递所有的变量,直接写export
  20. # 但是Makefile中SHELL变量和MAKEFLAGS变量总是会传递到下一级Makefile
  21. unexport LC_ALL
  22. LC_COLLATE=C
  23. LC_NUMERIC=C
  24. export LC_COLLATE LC_NUMERIC
  25. # Avoid interference with shell env settings
  26. unexport GREP_OPTIONS
  27. # We are using a recursive build, so we need to do a little thinking
  28. # to get the ordering right.
  29. #
  30. # Most importantly: sub-Makefiles should only ever modify files in
  31. # their own directory. If in some directory we have a dependency on
  32. # a file in another dir (which doesn't happen often, but it's often
  33. # unavoidable when linking the built-in.o targets which finally
  34. # turn into vmlinux), we will call a sub make in that other dir, and
  35. # after that we are sure that everything which is in that other dir
  36. # is now up to date.
  37. #
  38. # The only cases where we need to modify files which have global
  39. # effects are thus separated out and done before the recursive
  40. # descending is started. They are now explicitly listed as the
  41. # prepare rule.
  42. # Beautify output
  43. # ---------------------------------------------------------------------------
  44. #
  45. # Normally, we echo the whole command before executing it. By making
  46. # that echo $($(quiet)$(cmd)), we now have the possibility to set
  47. # $(quiet) to choose other forms of output instead, e.g.
  48. #
  49. # quiet_cmd_cc_o_c = Compiling $(RELDIR)/$@
  50. # cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
  51. #
  52. # If $(quiet) is empty, the whole command will be printed.
  53. # If it is set to "quiet_", only the short version will be printed.
  54. # If it is set to "silent_", nothing will be printed at all, since
  55. # the variable $(silent_cmd_cc_o_c) doesn't exist.
  56. #
  57. # A simple variant is to prefix commands with $(Q) - that's useful
  58. # for commands that shall be hidden in non-verbose mode.
  59. #
  60. # $(Q)ln $@ :<
  61. #
  62. # If KBUILD_VERBOSE equals 0 then the above command will be hidden.
  63. # If KBUILD_VERBOSE equals 1 then the above command is displayed.
  64. #
  65. # To put more focus on warnings, be less verbose as default
  66. # Use 'make V=1' to see the full commands
  67. # 这里时为了控制是否打印信息,我们这个makefile 1000多行,如果那个过程出现了错误肯定需要调试的
  68. # origin函数表示判断这个变量的来源
  69. ifeq ("$(origin V)", "command line")
  70. KBUILD_VERBOSE = $(V)
  71. endif
  72. ifndef KBUILD_VERBOSE
  73. KBUILD_VERBOSE = 0
  74. endif
  75. # 这里的Q就表示不回显命令,只会显示结果
  76. ifeq ($(KBUILD_VERBOSE),1)
  77. quiet =
  78. Q =
  79. else
  80. quiet=quiet_
  81. Q = @
  82. endif
  83. # If the user is running make -s (silent mode), suppress echoing of
  84. # commands
  85. # 这个filter函数我们前面就知道了,
  86. ifneq ($(filter 4.%,$(MAKE_VERSION)),) # make-4
  87. # firstword为取首单词函数
  88. ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),)
  89. quiet=silent_
  90. endif
  91. else # make-3.8x
  92. ifneq ($(filter s% -s%,$(MAKEFLAGS)),)
  93. quiet=silent_
  94. endif
  95. endif
  96. export quiet Q KBUILD_VERBOSE
  97. # kbuild supports saving output files in a separate directory.
  98. # To locate output files in a separate directory two syntaxes are supported.
  99. # In both cases the working directory must be the root of the kernel src.
  100. # 1) O=
  101. # Use "make O=dir/to/store/output/files/"
  102. #
  103. # 2) Set KBUILD_OUTPUT
  104. # Set the environment variable KBUILD_OUTPUT to point to the directory
  105. # where the output files shall be placed.
  106. # export KBUILD_OUTPUT=dir/to/store/output/files/
  107. # make
  108. #
  109. # The O= assignment takes precedence over the KBUILD_OUTPUT environment
  110. # variable.
  111. # KBUILD_SRC is set on invocation of make in OBJ directory
  112. # KBUILD_SRC is not intended to be used by the regular user (for now)
  113. ifeq ($(KBUILD_SRC),)
  114. # OK, Make called in directory where kernel src resides
  115. # Do we want to locate output files in a separate directory?
  116. # 这里的参数使用方法可以参考上面的注释信息
  117. ifeq ("$(origin O)", "command line")
  118. KBUILD_OUTPUT := $(O)
  119. endif
  120. # That's our default target when none is given on the command line
  121. PHONY := _all
  122. _all:
  123. # Cancel implicit rules on top Makefile
  124. # 取消隐式推倒规则
  125. $(CURDIR)/Makefile Makefile: ;
  126. # 将$(CURDIR)中的:变成空格,然后查看里面的参数个数
  127. ifneq ($(words $(subst :, ,$(CURDIR))), 1)
  128. $(error main directory cannot contain spaces nor colons)
  129. endif
  130. ifneq ($(KBUILD_OUTPUT),)
  131. # Invoke a second make in the output directory, passing relevant variables
  132. # check that the output directory actually exists
  133. saved-output := $(KBUILD_OUTPUT)
  134. KBUILD_OUTPUT := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) \
  135. && /bin/pwd)
  136. $(if $(KBUILD_OUTPUT),, \
  137. $(error failed to create output directory "$(saved-output)"))
  138. # make的环境变量叫MAKECMDGOALS,这个变量会存放你所指定的终极目标的列表。如果在命令行中没有指定目标,那么这个变量是空值
  139. PHONY += $(MAKECMDGOALS) sub-make
  140. # filter-out为Makefile反过滤函数
  141. $(filter-out _all sub-make $(CURDIR)/Makefile, $(MAKECMDGOALS)) _all: sub-make
  142. @:
  143. # 这个就是进入子目录进行编译了 $(filter-out _all sub-make,$(MAKECMDGOALS) 这个就是向make传递的参数了
  144. sub-make: FORCE
  145. $(Q)$(MAKE) -C $(KBUILD_OUTPUT) KBUILD_SRC=$(CURDIR) \
  146. -f $(CURDIR)/Makefile $(filter-out _all sub-make,$(MAKECMDGOALS))
  147. # Leave processing to above invocation of make
  148. skip-makefile := 1
  149. endif # ifneq ($(KBUILD_OUTPUT),)
  150. endif # ifeq ($(KBUILD_SRC),)
  151. # We process the rest of the Makefile if this is the final invocation of make
  152. ifeq ($(skip-makefile),)
  153. # Do not print "Entering directory ...",
  154. # but we want to display it when entering to the output directory
  155. # so that IDEs/editors are able to understand relative filenames.
  156. # 设置不打印进入目录和离开目录信息
  157. MAKEFLAGS += --no-print-directory
  158. # Call a source code checker (by default, "sparse") as part of the
  159. # C compilation.
  160. #
  161. # Use 'make C=1' to enable checking of only re-compiled files.
  162. # Use 'make C=2' to enable checking of *all* source files, regardless
  163. # of whether they are re-compiled or not.
  164. #
  165. # See the file "Documentation/sparse.txt" for more details, including
  166. # where to get the "sparse" utility.
  167. ifeq ("$(origin C)", "command line")
  168. KBUILD_CHECKSRC = $(C)
  169. endif
  170. ifndef KBUILD_CHECKSRC
  171. KBUILD_CHECKSRC = 0
  172. endif
  173. # Use make M=dir to specify directory of external module to build
  174. # Old syntax make ... SUBDIRS=$PWD is still supported
  175. # Setting the environment variable KBUILD_EXTMOD take precedence
  176. ifdef SUBDIRS
  177. KBUILD_EXTMOD ?= $(SUBDIRS)
  178. endif
  179. ifeq ("$(origin M)", "command line")
  180. KBUILD_EXTMOD := $(M)
  181. endif
  182. # If building an external module we do not care about the all: rule
  183. # but instead _all depend on modules
  184. PHONY += all
  185. ifeq ($(KBUILD_EXTMOD),)
  186. _all: all
  187. else
  188. _all: modules
  189. endif
  190. ifeq ($(KBUILD_SRC),)
  191. # building in the source tree
  192. srctree := .
  193. else
  194. ifeq ($(KBUILD_SRC)/,$(dir $(CURDIR)))
  195. # building in a subdirectory of the source tree
  196. srctree := ..
  197. else
  198. srctree := $(KBUILD_SRC)
  199. endif
  200. endif
  201. objtree := .
  202. src := $(srctree)
  203. obj := $(objtree)
  204. # 设置依赖查找路径
  205. VPATH := $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD))
  206. export srctree objtree VPATH
  207. # SUBARCH tells the usermode build what the underlying arch is. That is set
  208. # first, and if a usermode build is happening, the "ARCH=um" on the command
  209. # line overrides the setting of ARCH below. If a native build is happening,
  210. # then ARCH is assigned, getting whatever value it gets normally, and
  211. # SUBARCH is subsequently ignored.
  212. # uname -m 查看系统的架构,这个函数的作用时如果在编译Linux内核时不指定架构那么顶层Makefile就会自动获取
  213. SUBARCH := $(shell uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
  214. -e s/sun4u/sparc64/ \
  215. -e s/arm.*/arm/ -e s/sa110/arm/ \
  216. -e s/s390x/s390/ -e s/parisc64/parisc/ \
  217. -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
  218. -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ )

打赏

                    支付宝                                                         微信

微信与支付宝支付

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注