曲径通幽论坛

标题: ifdef, ifndef, ifeq, endif, ifneq [打印本页]

作者: beyes    时间: 2010-12-7 19:17
标题: ifdef, ifndef, ifeq, endif, ifneq
用内核 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
像我们经常编译驱动模块时会使用下面的命令:
make -C /lib/modules/`uname -r`/build M=`pwd` modules
上面,使用 pwd 命令给出了要编译的模块所在的路径。


像 ifeq 和 ifneq 的第一个参数也可以不止一个变量,当有多个变量时,可能需要考虑每个变量的条件是否都满足判断条件,直到所有的变量都不满足时,才认为整个表达式是不满足的。示例代码如下:
hostprogs-y := 1
hostprogs-m :=

ifneq ($(hostprogs-y)$(hostprogs-m),)
    testvar := "defined"
endif

all:
    @echo "$(testvar)"
运行输出:
$ make
defined
如果将上面代码中对 hostprogs-y 的定义设为空,那么输出将为空;而 hostprogs-y 和 hostprogs-m 这两个变量只要有一个味真,那么就认为整个 ifneq 判断成立。




欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) Powered by Discuz! X3.2