Makefile之条件部分

本文详细解释了Makefile中的条件指令,如ifeq、ifdef、ifndef等,以及如何根据变量值动态调整编译选项。还介绍了如何利用MAKEFLAGS和findstring函数检测命令标志,以实现灵活的构建流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Makefile之条件部分


下一篇:练习8 Makefile之使用函数,上一篇:练习6 Makefile之使用变量目录首页

温故知新

条件指令在Makefile中根据变量的值决定是否执行或忽略部分内容。条件可以比较一个变量的值与另一个变量的值,或将一个变量的值与一个常量字符串进行比较。条件指令控制make实际上在Makefile中看到的内容,因此不能用于控制执行时的操作步骤。

以下是一个简单的Makefile示例,演示了如何使用条件指令:

# 定义变量
DEBUG = yes

# 使用条件指令
ifeq ($(DEBUG),yes)
    CFLAGS = -g
else
    CFLAGS = -O2
endif

# 默认目标
all: program

# 编译程序
program: main.c
    gcc $(CFLAGS) -o program main.c

# 清理生成的文件
clean:
    rm -f program

在上面的例子中,根据变量DEBUG的值,选择不同的编译选项CFLAGS。如果DEBUG的值是"yes",则设置CFLAGS为"-g",否则设置为"-O2"。这种条件判断发生在makefile 解析时,而不是在实际执行编译步骤时。

在命令行中执行make命令时,make会根据条件选择适当的编译选项来构建程序。


下一篇:练习8 Makefile之使用函数,上一篇:练习6 Makefile之使用变量目录首页

条件示例

这个条件示例告诉make在CC变量为’gcc’时使用一组库,否则使用另一组库。它通过控制规则中将使用哪一行配方来实现。结果是,将’CC=gcc’作为make的参数传递不仅会改变使用的编译器,还会改变链接的库。

libs_for_gcc = -lgnu
normal_libs =

foo: $(objects)
ifeq ($(CC),gcc)
    $(CC) -o foo $(objects) $(libs_for_gcc)
else
    $(CC) -o foo $(objects) $(normal_libs)
endif

这个条件使用了三个指令:一个ifeq,一个else和一个endif。

ifeq指令开始条件,并指定条件。它包含两个由逗号分隔并用括号括起的参数。对两个参数执行变量替换,然后它们进行比较。ifeq之后的Makefile行将在两个参数匹配时执行,否则将被忽略。

else指令导致以下行在前面的条件失败时执行。在上面的例子中,这意味着只有在第一个备用链接命令不被使用时才会使用第二个备用链接命令。在条件中有else是可选的。

endif指令结束条件。每个条件必须以endif结束。无条件的Makefile文本随后出现。

正如这个例子所示,条件在文本级别起作用:条件的行被视为Makefile的一部分,或者根据条件被忽略。这就是为什么Makefile的更大的语法单元,比如规则,可能跨越条件的开始或结束的原因。

当变量CC的值为’gcc’时,上述示例的效果如下:

foo: $(objects)
    $(CC) -o foo $(objects) $(libs_for_gcc)

当变量CC具有任何其他值时,效果如下:

foo: $(objects)
    $(CC) -o foo $(objects) $(normal_libs)

也可以通过对变量赋值进行条件化,然后无条件地使用变量来获得等效的结果:

libs_for_gcc = -lgnu
normal_libs =

ifeq ($(CC),gcc)
    libs=$(libs_for_gcc)
else
    libs=$(normal_libs)
endif

foo: $(objects)
    $(CC) -o foo $(objects) $(libs)

下一篇:练习8 Makefile之使用函数,上一篇:练习6 Makefile之使用变量目录首页

条件句的语法

这段文本描述了Makefile中条件指令的语法和用法。以下是对其中涉及的重要概念的简要总结:

  1. 简单条件语法:

    conditional-directive
    text-if-true
    endif
    

    如果条件为真,则执行 text-if-true 部分;否则,忽略该部分。

  2. 复杂条件语法:

    conditional-directive
    text-if-true
    else
    text-if-false
    endif
    

    或者多个 else 子句:

    conditional-directive-one
    text-if-one-is-true
    else conditional-directive-two
    text-if-two-is-true
    else
    text-if-one-and-two-are-false
    endif
    

    当条件为真时执行 text-if-true,否则执行 text-if-false,或者执行其他 else 子句中的内容。

  3. 条件指令的种类:

    • ifeq (arg1, arg2)
    • ifneq (arg1, arg2)
    • ifdef variable-name
    • ifndef variable-name

    这些指令测试不同的条件。条件可以包含变量引用,会在比较前被展开。

  4. 条件变量的测试:

    • ifeqifneq 用于比较两个参数是否相等或不相等。
    • ifdef 测试一个变量是否已定义且非空。
    • ifndef 测试一个变量是否未定义或为空。
  5. 条件中的变量展开:

    • 变量引用在条件中会被展开。例如:$(strip $(foo)) 用于测试变量 foo 是否为空。
  6. 条件的影响:

    • 条件影响make使用Makefile中的哪些行。如果条件为真,make读取 text-if-true 部分;如果条件为假,则完全忽略这些行。
  7. 条件的评估时机:

    • 条件在读取Makefile时被评估,因此不能在条件测试中使用自动变量,因为它们在执行规则时才被定义。
  8. 条件的嵌套和include:

    • 条件可以嵌套。include 可以在条件中使用,但是不允许在一个Makefile中开始条件然后在另一个Makefile中结束条件。

以上总结希望能帮助理解Makefile中条件指令的基本用法和语法。


下一篇:练习8 Makefile之使用函数,上一篇:练习6 Makefile之使用变量目录首页

测试标志的条件

这段文本介绍了如何使用条件指令以及MAKEFLAGS 变量和 findstring 函数来测试 make 命令标志,例如 -t 标志。这在 touch 不足以使文件看起来是最新的情况下非常有用。

MAKEFLAGS 将所有单字母选项(例如 -t)放入第一个单词,如果没有提供单字母选项,那么该单词将为空。为了更方便地处理这个情况,在开头添加一个值,以确保有一个单词,例如 ‘-$(MAKEFLAGS)’。

findstring 函数用于确定一个字符串是否出现在另一个字符串中。如果要测试 -t 标志,可以将 ‘t’ 作为第一个字符串,将 MAKEFLAGS 的第一个单词作为另一个字符串。

例如,下面的示例展示了如何设置使用 ‘ranlib -t’ 来完成标记存档文件为最新的过程:

archive.a: ...
ifneq (,$(findstring t,$(firstword -$(MAKEFLAGS))))
    +touch archive.a
    +ranlib -t archive.a
else
    ranlib archive.a
endif

在这个例子中,如果 -t 标志在 MAKEFLAGS 中,则执行 touch archive.aranlib -t archive.a,否则执行 ranlib archive.a+ 前缀标记这些配方行为“递归”,以便它们将被执行,即使使用了 -t 标志。


下一篇:练习8 Makefile之使用函数,上一篇:练习6 Makefile之使用变量目录首页

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值