Makefile学习2

文章目录

  • Makefile学习2
    • Makefile条件判断
      • ifeq 关键字
      • ifneq 关键字
      • ifdef 关键字
      • ifndef 关键字
    • Makefile函数
      • 用户自定义函数
      • 文本处理函数
    • Makefile 通配符

Makefile学习2

Makefile条件判断

使用条件判断,可以让make在编译程序时,根据不同的情况,执行不同的分支:可以执行不同的命令,使用不同的编译参数,生成不同的目标。

ifeq 关键字

ifeq关键字用来判断两个参数是够相等,相等时条件成立为true,不相等为false。

条件判断语句由三个关键字组成:ifeq、else、endif。

ifeq后面的比较语句使用小括号抱起来,ifeq和小括号之间要用空格隔开,小括号里的两个参数用逗号隔开。当小括号里的条件满足时,make就会执行这个分支的命令,否则执行else部分。endif表示一个条件语句的结束。

ifeq一般和变量结合使用:

mode = debug
hello: hello.c
ifeq ($(mode),debug)@echo "debug mode" gcc -g -o hello hello.c
else@echo "release mode"gcc -o hello hello.c
endif

ifneq 关键字

ifneq 关键字和ifeq关键字恰恰相反,用来判断参数是否不相等。当比较的参数不相等时,条件语句才成立,值为true,否则为false。

mode = debug
hello: hello.c
ifneq ($(mode),)@echo "debug mode" gcc -g -o hello hello.c
else@echo "release mode"gcc -o hello hello.c
endif

在上面的语句中,我们让mode变量和一个空字符串比较,不相等,条件语句成立。

ifdef 关键字

ifdef 关键字用来判断一个变量是否已经定义。如果变量的值非空(在Makefile中,没有定义的变量的值为空),表达式为真。

mode = 
hello: hello.c
ifdef mode@echo "debug mode" gcc -g -o hello hello.c
else@echo "release mode"gcc -o hello hello.c
endif

如果在Makefile定义一个变量没有赋值,或者没有定义变量,那么这个变量的值都为空。

ifndef 关键字

ifndef关键字和ifdef相反,如果一个变量没有定义,表达式为真。

Makefile函数

GNU make 提供了大量的函数用来处理文件名、变量、文本和命令。通过这些函数,用户可以节省很多精力,编写出更加灵活和健壮的Makefile。

函数的使用和变量引用的展开方式相同:

$(function arguments)
${function arguments}

注意:

  • 函数主要分为两类:make内嵌函数和用户自定义函数。对于 GNU make内嵌的函数,直接引用就可以了;对于用户自定义的函数,要通过make的call函数来间接调用。
  • 函数和参数列表之间要用空格隔开,多个参数之间使用逗号隔开。
  • 如果在参数中引用了变量,变量的引用建议和函数引用使用统一格式:要么是一对小括号,要么是一对大括号。

wildcard函数:如果我们想要获取某个目录下所有的C文件列表,可以使用扩展通配符函数

SRC  = $(wildcard *.c)
HEAD = $(wildcard *.h)
all:@echo "SRC = $(SRC)"@echo "HEAD = $(HEAD)"

用户自定义函数

用户自定义函以define开头,endef结束。

给函数传递的参数在函数中使用 ( 0 ) 、 (0)、 (0)(1)引用。

用户自定义函数使用call函数间接调用,各个参数之间使用空格隔开。

PHONY: all
define func@echo "pram1 = $(0)"@echo "pram2 = $(1)"
endef
all:$(call func, hello zz.cc)

文本处理函数

GNU make提供了一系列文本处理函数:subst、patsubst、strip、findstring、filter、filer-out、sort、word、wordlist、words、fistword。

subst函数:用来实现字符串的替换,将字符串text中的old替换为new

$(subst old,new,text)
.PHONY: all
SRC  = $(wildcard *.c)
OBJ  = $(subst .c,.o,$(SRC))
all:@echo "OBJ = $(OBJ)"@echo $(subst banana, apple, "banana is good, I like banana")
# ls
add.c  add.h  hello.c  main.c  makefile  sub.c  sub.h
# make
OBJ = hello.o main.o add.o sub.oapple is good, I like  apple

patsubst函数:主要用来模式替换,使用通配符 % 代表一个单词中的若干字符,在PATTERN和REPLACEMENT如果都包含这个通配符,表示两者表示的是相同的若干个字符,并执行替换操作。

.PHONY: all
SRC  = $(wildcard *.c)
OBJ  = $(patsubst %.c, %.o, $(SRC))
all:@echo "OBJ = $(OBJ)"

strip函数:去空格函数,一个字符串通常有多个单词,单词之间使用一个或多个空格进行分割,strip函数用来将多个连续的空字符合并成一个,并去掉字符串开头、末尾的空字符。空字符包括:空格、多个空格、tab等不可显示的字符。

.PHONY: all
STR =     hello a    b   c   
STRIP_STR = $(strip $(STR))
all:@echo "STR = $(STR)"@echo "STRIP_STR = $(STRIP_STR)"
# make
STR = hello a    b   c   
STRIP_STR = hello a b c

strip函数经常用在条件判断语句的表达式中,去掉多余的空格等因素,确保表达式比较的可靠和健壮。

ifeq ($(strip $(foo)),)echo "foo is empty"
endif

findstring函数:用来查找一个字符串,在字符串IN中查找“FIND”字符串,如果找到,则返回字符串FIND,否则,返回空。

$(findstring FIND, IN)
.PHONY: all
STR =     hello a    b   c   
FIND = $(findstring hello, $(STR))
all:@echo "STR = $(STR)"@echo "FIND = $(FIND)"

filter函数:用来过滤掉一个指定的字符串,用来过滤掉字符串TEXT中所有不符合PATTERN模式的单词,只留下符合PATTERN格式的单词。

$(filter PATTERN…,TEXT)
.PHONY: all
FILE = a.c b.h c.s d.cpp   
SRC = $(filter %.c, $(FILE))
all:@echo "FILE = $(FILE)"@echo "SRC = $(SRC)"

filer-out函数:是一个反过滤函数,功能和filter函数恰恰相反:该函数会过滤掉所有符合PATTERN模式的单词,保留所有不符合此模式的单词。

.PHONY: all
FILE = a.c b.h c.s d.cpp   
SRC = $(filter-out %.c, $(FILE))
all:@echo "FILE = $(FILE)"@echo "SRC = $(SRC)"

sort函数:对字符串LIST中的单词以首字母为准进行排序,并删除重复的单词。

.PHONY: all
FILE = e.c a.c b.h c.s d.cpp   
all:@echo "FILE = $(FILE)"@echo $(sort $(FILE))

word函数:从一个字符串TEXT中,按照指定的数目N取单词

 $(word N,TEXT)

wordlist函数:用来从一个字符串TEXT中取出从N到M之间的一个单词串

$(wordlist N, M, TEXT)

words函数:用来统计一个字符串TEXT中单词的个数

$(words TEXT)

foreach函数:做一些循环或遍历操作

$(foreach VAR,LIST,TEXT)

把LIST中使用空格分割的单词依次取出并赋值给变量VAR,然后执行TEXT表达式。重复这个过程,直到遍历完LIST中的最后一个单词。函数的返回值是TEXT多次计算的结果。

自动搜索各个目录下的C源文件:

.PHONY: all
dirs = lcd usb media keyboard
srcs = $(foreach dir, $(dirs), $(wildcard $(dir)/*))
all:@echo "srcs = $(srcs)"

Makefile 通配符

在Makefile中表示一个文件名时,可以使用通配符。

在Makefile中可以使用的通配符有:* 、? 、 […]。通配符的使用方法和含义和在shell中一样。

通配符使用说明
*匹配0个或者是任意个字符
匹配任意一个字符
[]我们可以指定匹配的字符放在 “[]” 中

除此之外,Makefile还有经常使用的几个自动变量也可以看做特殊通配符:

  • $@:所有目标文件
  • $^:目标依赖的所有文件
  • $<:第一个依赖文件
  • $?:所有更新过的依赖文件

在Makefile中,通配符主要用在两个场合:

用在规则的目标和依赖中:make在读取Makefile时会自动对其进行匹配处理

test: *.ogcc -o $@ $^
*.o: *.cgcc -c $^

用在规则的命令中:通配符的通配处理在shell执行命令时完成

clean:rm -f *.o

除了以上两种情况,在其他地方都不能直接使用通配符。需要一些函数(如wildcard)来实现。如果想列举当前目录下的所有C文件,可以直接使用wildcard函数:

$(wildcard *.c)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/19418.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IO进程线程day5(2023.8.2)

一、Xmind整理&#xff1a; 父进程会拷贝文件描述符表给子进程&#xff1a; 二、课上练习&#xff1a; 练习1&#xff1a;①从终端获取一个文件的路径以及名字。②若该文件是目录文件&#xff0c;则将该文件下的所有文件的属性显示到终端&#xff0c;类似ls -l该文件夹③若该文…

【Linux命令200例】touch用来创建新的文件或者修改已有文件

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;本文已收录于专栏&#xff1a;Linux命令大全。 &#x1f3c6;本专栏我们会通过具体的系统的命令讲解加上鲜…

代码随想录算法训练营day52

文章目录 Day52 最长递增子序列题目思路代码 最长连续递增序列题目思路代码 最长重复子数组题目思路代码 Day52 最长递增子序列 300. 最长递增子序列 - 力扣&#xff08;LeetCode&#xff09; 题目 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 …

前端视频播放技术概览

转眼间&#xff0c;2023 年已进入下半场&#xff0c;在这样一个时间节点下&#xff0c;长视频平台如爱奇艺、优酷、腾讯视频等&#xff0c;以及短视频平台如抖音、快手等&#xff0c;对大家来说早已是司空见惯的事物。然而&#xff0c;在我们追剧、刷弹幕的时候&#xff0c;很少…

阿里云国际版在使用过程中应该注意什么呢?

为确保系统稳定性&#xff0c;用户不得进行以下操作。否则&#xff0c;阿里云可能无法解决由以下违规操作引起的问题&#xff1a; 1) Windows系统中的PV Drivers 程序不可删除 PV Drivers程序为服务器虚拟化驱动程序&#xff0c;请不要针对该程序进行任何操作&#xff0c;如果删…

电压放大器工作在什么状态

电压放大器是一种广泛应用于电子电路中的基本电路元件&#xff0c;其主要功能是将输入信号的电压放大到所需的输出电压幅值&#xff0c;并且保持信号的形状不变。在实际电路设计中&#xff0c;电压放大器的工作状态会受到多种因素的影响&#xff0c;比如输入信号的频率、放大倍…

iOS--runtime

什么是Runtime runtime是由C和C、汇编实现的一套API&#xff0c;为OC语言加入了面向对象、运行时的功能运行时&#xff08;runtime&#xff09;将数据类型的确定由编译时推迟到了运行时平时编写的OC代码&#xff0c;在程序运行过程中&#xff0c;最终会转换成runtime的C语言代…

爱尔眼科四川省区“同心博爱 光明工程”“西部健康公益行”炉霍站启动

8月1日&#xff0c;“同心博爱 光明工程”“西部健康公益行”炉霍站出征仪式在四川爱尔眼科医院隆重举行。 此次公益活动由民革成都市委会、中共锦江区委统战部指导&#xff0c;如意树爱心促进会主办&#xff0c;民革锦江区总支部、爱尔眼科四川省区支持&#xff0c;四川爱尔眼…

手把手教你从零开始搭建个人博客

随着技术的进步和用户需求的变化&#xff0c;个人博客的形式和内容一直在不停地演变。为了给读者提供更丰富、有趣的阅读体验&#xff0c;搭建个人博客的网站一直在寻找更好的优化方法。所以现在出现了一批功能更完善的个人博客搭建软件&#xff0c;今天looklook就以HelpLook为…

C++设计模式之适配器设计模式

文章目录 C适配器设计模式什么是适配器设计模式该模式有什么优缺点优点缺点 如何使用 C适配器设计模式 什么是适配器设计模式 适配器设计模式是一种行为型设计模式&#xff0c;它允许你将两个不兼容的接口组合在一起&#xff0c;使它们能够协同工作。 该模式有什么优缺点 优…

Boost开发指南-3.10singleton_pool

singleton_pool singleton_pool与 pool的接口完全一致&#xff0c;可以分配简单数据类型&#xff08;POD&#xff09;的内存指针&#xff0c;但它是一个单件。 singleton_pool位于名字空间boost&#xff0c;为了使用singleton_pool组件&#xff0c;需要包含头文件<boost/p…

Activiity跳转startActivity源码分析Activity启动流程(下)

调用ActivityThread子类ClientTranslationHandler的scheduleTranslation 注意上图有个sendMessage的 接着会执行translacationExecutor的execute方法。 都会走cycleToPath方法 cycleToPath方法对应的performLifecycleSequence 调用Actvitiy各个生命周期。 然后是第二种情况&am…

设计模式行为型——命令模式

目录 什么是命令模式 命令模式的实现 命令模式角色 命令模式类图 命令模式举例 命令模式代码实现 命令模式的特点 优点 缺点 使用场景 注意事项 什么是命令模式 命令模式&#xff08;Command Pattern&#xff09;是一种数据驱动的设计模式&#xff0c;它属…

【C#学习笔记】值类型(1)

虽然拥有编程基础的人可以很快地上手C#&#xff0c;但是依然需要学习C#的特性和基础。本系列是本人学习C#的笔记&#xff0c;完全按照微软官方文档编写&#xff0c;但是不适合没有编程基础的人。 文章目录 .NET 体系结构Hello&#xff0c;World类型和变量&#xff08;重要&…

Hive的堵塞问题和表锁问题原因查找

Hive的堵塞问题可能是由多种原因引起的。下面是一些可能的原因和解决方法&#xff1a; 数据倾斜&#xff1a;如果某个字段的值分布不均匀&#xff0c;可能会导致某些任务处理的数据量过大&#xff0c;从而造成堵塞。可以通过使用分桶或者使用JOIN操作时进行数据倾斜处理来解决这…

docker容器创建私有仓库(第三篇)

目录 六、创建私有仓库 七、Docker资源限制 7.1、CPU使用率 7.2、CPU共享比例 7.3、CPU周期限制 7.4、CPU核心限制 7.5、CPU 配额控制参数的混合案例 7.6、内存限制 7.7、Block IO 的限制 7.8、限制bps 和iops 8、Docker数据持久化 8.1、数据持久化介绍 8.2、Volum…

操作系统的运行机制、中断和异常、系统调用

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; c语言 数据结构 javaweb 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 操作系统 一、操作系统的运行机制1.1内核程序1.2应用程序1…

maven如何打包你会吗?

1.新建一个maven项目&#xff0c;在main/java中建立Main类 public class Main {public static void main(String[] args) {System.out.println("hello java ...");} } 2.添加依赖&#xff0c;使其成为可执行包 <build><plugins><!--打包成为可执行包-…

UncaughtExceptionHandler初探(1)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、UncaughtExceptionHandler 是什么&#xff1f;二、使用步骤1.通过try-catch捕捉子线程的问题2.非线程池设置3.线程池的情况下设置UncaughtExceptionHandler…

ESP32cam系列教程003:ESP32cam实现远程 HTTP_OTA 自动升级

文章目录 1.什么是 OTA2. ESP32cam HTTP_OTA 本地准备2.1 HTTP OTA 升级原理2.2 开发板本地基准程序&#xff08;程序版本&#xff1a;1_0_0&#xff09;2.3 开发板升级程序&#xff08;程序版本&#xff1a;1_0_1&#xff09;2.4 本地 HTTP_OTA 升级测试2.4.1 本地运行一个 HT…