|
用内核 Makefile 中的一段代码说明:
# To put more focus on warnings, be less verbose as default
# Use 'make V=1' to see the full commands
ifdef V
ifeq ("$(origin V)", "command line")
KBUILD_VERBOSE = $(V)
endif
endif
ifndef KBUILD_VERBOSE
KBUILD_VERBOSE =0
endif
代码中注释的意思是,为了能将精力集中在警告信息上面,默认上不输出详细而显得冗余的编译信息,如果想看到完整的命令执行情况,可以在 make 时使用参数 V=1 。
下面根据代码分析这 4 个符号的作用,实际上它们和 C 语言中的意思是一样的。
ifdef V 表示如果 V 变量被定义过,那么会执行下面的 ifeq 语句。V 变量的定义来源可以有不同,如在文件中定义,在命令行中定义,在环境变量中定义等。
ifeq ("$(origin V)", "command line") 表示若 V 是在命令行里已被定义,那么执行下面的 KBUILD_VERBOSE = $(V) 语句。也就是说,ifeq 用以判断后面括号里的两个值是否相等,如果相等则执行下面的语句。如果不相等,则不执行。关于 origin 函数的用法见:http://www.groad.net/bbs/read.php?tid-2941.html
ifndef 表示如果后面的变量没有被定义过,则执行其下面的语句。
上面,每个 ifdef , ifeq 和 ifndef 都要和一个 endif 匹配以构成一个完整的判断式。
另外,在内核 Makefile 中还有如对 (C) 以及 (M) 等选项同样分析。
(C) 选项有是关于代码检查的选择:
# Call a source code checker (by default, "sparse") as part of the
# C compilation.
#
# Use 'make C=1' to enable checking of only re-compiled files.
# Use 'make C=2' to enable checking of *all* source files, regardless
# of whether they are re-compiled or not.
#
# See the file "Documentation/sparse.txt" for more details, including
# where to get the "sparse" utility.
ifdef C
ifeq ("$(origin C)", "command line")
KBUILD_CHECKSRC = $(C)
endif
endif
ifndef KBUILD_CHECKSRC
KBUILD_CHECKSRC =0
endif
(M) 选项关于模块的编译:
# Use make M=dir to specify directory of external module to build
# Old syntax make ... SUBDIRS=$PWD is still supported
# Setting the environment variable KBUILD_EXTMOD take precedence
ifdef SUBDIRS
KBUILD_EXTMOD ?= $(SUBDIRS)
endif
ifdef M
ifeq ("$(origin M)", "command line")
KBUILD_EXTMOD := $(M)
endif
endif 像我们经常编译驱动模块时会使用下面的命令:上面,使用 pwd 命令给出了要编译的模块所在的路径。
像 ifeq 和 ifneq 的第一个参数也可以不止一个变量,当有多个变量时,可能需要考虑每个变量的条件是否都满足判断条件,直到所有的变量都不满足时,才认为整个表达式是不满足的。示例代码如下:hostprogs-y := 1
hostprogs-m :=
ifneq ($(hostprogs-y)$(hostprogs-m),)
testvar := "defined"
endif
all:
@echo "$(testvar)" 运行输出:如果将上面代码中对 hostprogs-y 的定义设为空,那么输出将为空;而 hostprogs-y 和 hostprogs-m 这两个变量只要有一个味真,那么就认为整个 ifneq 判断成立。 |
|