Makefile【04】 您所在的位置:网站首页 mk的标志是什么 Makefile【04】

Makefile【04】

2024-06-17 11:07| 来源: 网络整理| 查看: 265

1. Makefile 条件判断作用

条件语句可以根据一个变量的值来控制 make 执行或者时忽略 Makefile 的特定部分,条件语句可以是两个不同的变量或者是常量和变量之间的比较。

下面是条件判断中使用到的一些关键字:

关键字功能ifeq判断参数是否不相等,相等为 true,不相等为 falseifneq判断参数是否不相等,不相等为 true,相等为 falseifdef判断是否有值,有值为 true,没有值为 falseifndef判断是否有值,没有值为 true,有值为 false 2. ifeq 和 ifneq

条件判断的使用方式如下:

ifeq (first, second) ifeq 'first' 'second' ifeq `first` `second` ifeq `first` 'second' ifeq 'first' `second`

示例:

first = $(CXX) second = g++ all: ifeq ($(first), $(second)) echo `first == second` else echo `first != second` endif

执行 make 之后的输出

wohu@ubuntu:~/cpp/ifeq$ make echo `first == second` first == second wohu@ubuntu:~/cpp/ifeq$

条件语句中使用到三个关键字 ifeq、else、endif。其中:

ifeq 表示条件语句的开始,并指定一个比较条件(相等)。括号和关键字之间要使用空格分隔,两个参数之间要使用逗号分隔。参数中的变量引用在进行变量值比较的时候被展开。ifeq后面的是条件满足的时候执行的,条件不满足忽略;else 表示当条件不满足的时候执行的部分,不是所有的条件语句都要执行此部分;endif是判断语句结束标志,Makefile 中条件判断的结束都要有; 其实 ifneq 和 ifeq 的使用方法是完全相同的,只不过是满足条件后执行的语句正好相反。

3. ifdef 和 ifndef

使用方式如下:

ifdef VARIABLE_NAME

它的主要功能是判断变量的值是不是为空,示例 1

a = b = $(a) all: ifdef b echo yes else echo no endif

执行 make 之后的输出

wohu@ubuntu:~/cpp/ifeq$ make echo yes yes wohu@ubuntu:~/cpp/ifeq$

示例 2

a = all: ifdef a echo yes else echo no endif

执行 make 之后的输出

wohu@ubuntu:~/cpp/ifeq$ make echo no no wohu@ubuntu:~/cpp/ifeq$

通过两个实例对比说明:我们执行 make 可以看到示例 1 打印的结果是 yes ,实例 2 打印的结果是 no 。

其原因就是在实例 1 中,变量 b 的定义是 b = $(a)。虽然变量 a 的值为空,但是 ifdef 的判断结果为真,这种方式判断显然是有不行的,因此当我们需要判断一个变量的值是否为空的时候需要使用ifeq 而不是 ifdef。

注意:在条件表达式中不能使用自动化变量,自动化变量在规则命令执行时才有效,更不能将一个完整的条件判断语句分卸在两个不同的 Makefile 的文件中。

在一个 Makefile 中使用指示符 include 包含另一个 Makefile 文件。

4. 定义命令包

命令包有点像是个函数, 将连续的相同的命令合成一条, 减少 Makefile 中的代码量, 便于以后维护。

语法:

define command ... endef

示例:

# Makefile 内容 define run_demo_makefile @echo -n "Hello" @echo " Makefile!" @echo "这里可以执行多条 Shell 命令!" endef all: $(run_demo_makefile)

执行 make

wohu@ubuntu:~/cpp/func$ make Hello Makefile! 这里可以执行多条 Shell 命令! wohu@ubuntu:~/cpp/func$ 5. Makefile 伪目标

所谓的伪目标可以这样来理解,它并不会创建目标文件,只是想去执行这个目标下面的命令。伪目标的存在可以帮助我们找到命令并执行。

如果需要书写这样一个规则,规则所定义的命令不是去创建文件,而是通过 make 命令明确指定它来执行一些特定的命令。实例:

clean: rm -rf *.o test

规则中 rm 命令不是创建文件 clean 的命令,而是执行删除任务,删除当前目录下的所有的 .o 结尾和文件名为 test 的文件。

当工作目录下不存在以 clean 命令的文件时,在 shell 中输入 make clean 命令,命令 rm -rf *.o test 总会被执行 ,这也是我们期望的结果。

如果当前目录下存在文件名为 clean 的文件时情况就会不一样了,当我们在 shell 中执行命令 make clean,由于这个规则没有依赖文件,所以目标被认为是最新的而不去执行规则所定义的命令。因此命令 rm 将不会被执行。

为了解决这个问题,删除 clean 文件或者是在 Makefile 中将目标 clean 声明为伪目标。

将一个目标声明称伪目标的方法是将它作为特殊的目标 .PHONY 的依赖,如下:

.PHONY:clean

这样 clean 就被声明成一个伪目标,无论当前目录下是否存在 clean 这个文件,当我们执行 make clean 后 rm 都会被执行。

而且当一个目标被声明为伪目标之后,make 在执行此规则时不会去试图去查找隐含的关系去创建它。这样同样提高了 make 的执行效率,同时也不用担心目标和文件名重名而使我们的编译失败。

在书写伪目标的时候,需要声明目标是一个伪目标,之后才是伪目标的规则定义。目标 clean 的完整书写格式如下:

.PHONY:clean clean: rm -rf *.o test

示例: 目录结构

wohu@ubuntu:~/cpp/ifeq$ tree . └── Makefile 0 directories, 1 file wohu@ubuntu:~/cpp/ifeq$

只有一个 Makefile 文件,内容如下:

a = 123 bbb: echo "a is $(a)"

执行 make 输出结果如下:

wohu@ubuntu:~/cpp/ifeq$ make echo "a is 123" a is 123 wohu@ubuntu:~/cpp/ifeq$ make bbb echo "a is 123" a is 123 wohu@ubuntu:~/cpp/ifeq$

手工创建文件 bbb 之后再执行 make,echo 语句就不会执行

wohu@ubuntu:~/cpp/ifeq$ ls Makefile wohu@ubuntu:~/cpp/ifeq$ touch bbb wohu@ubuntu:~/cpp/ifeq$ make make: 'bbb' is up to date. wohu@ubuntu:~/cpp/ifeq$

添加伪目标后

a = 123 .PHONY: bbb bbb: echo "a is $(a)"

执行 make 输出结果如下,即无论当前目录下是否存在 bbb 这个文件,当我们执行 make bbb 后 echo 都会被执行。

wohu@ubuntu:~/cpp/ifeq$ ls bbb Makefile wohu@ubuntu:~/cpp/ifeq$ make bbb echo "a is 123" a is 123 wohu@ubuntu:~/cpp/ifeq$



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有