Makefile第八课:Makefile常用函数

Makefile常用函数

前言

学习杜老师推荐的Makefile教程视频,链接。记录下个人学习笔记,仅供自己参考。

之前有转载过杜老师的从零Makefile落地算法大项目文章,感兴趣的可以看看。

本课程主要讲解Makefile中的常见函数。

0.导言

Makefile函数调用,很像变量的调用,也是以 $ 来标识的,其语法如下:

$(fn, arguments) or ${fn, arguments}
  • fn:函数名
  • arguments:函数参数,参数间以逗号 , 分隔,而函数名和参数之间以 空格 分隔

1.shell

$(shell <command> <arguments>)
  • 名称:shell命令函数 —— shell
  • 功能:调用 shell 命令 command
  • 返回:函数返回 shell 命令 command 的执行结果

示例如下:

# shell 指令,src 文件夹下找到 .cpp 文件
cpp_srcs := $(shell find src -name "*.cpp") 
# shell 指令, 获取计算机架构
HOST_ARCH := $(shell uname -m)

debug :
	@echo $(cpp_srcs)
	@echo $(HOST_ARCH)

.PHONY : debug

输出如下:

src/main.cpp
aarch64

2.subset

$(subst <from>,<to>,<text>)
  • 名称:字符串替换函数 —— subst
  • 功能:把字串 <text> 中的 <form> 字符串替换成 <to>
  • 返回:函数返回被替换过后的字符串

示例如下:

# shell 指令,src 文件夹下找到 .cpp 文件
cpp_srcs := $(shell find src -name "*.cpp") 

# subst 将src/替换为objs/
cpp_objs := $(subst src/,objs/,$(cpp_srcs))
# subst 将.cpp替换为.o
cpp_objs := $(subst .cpp,.o,$(cpp_objs))

debug :
	@echo $(cpp_srcs)
	@echo $(cpp_objs)

.PHONY : debug

输出如下:

src/main.cpp
objs/main.o

3.patsubst

$(patsubst <pattern>,<replacement>,<text>)
  • 名称:模式字符串替换函数 —— patsubst
  • 功能:通配符 %,表示任意长度的字符,从 text 中取出 pattern, 替换成 replacement
  • 返回:函数返回被替换过后的字符串
  • 区别:subst函数只能进行简单的字符串替换,而patsubst函数则可以根据通配符进行更加灵活的字符串替换

示例如下:

# shell 指令,src 文件夹下找到 .cpp 文件
cpp_srcs := $(shell find src -name "*.cpp") 

# patsubst 将src/*.cpp替换为objs/*.o
cpp_objs := $(patsubst src/%.cpp,objs/%.o,$(cpp_srcs))

debug :
	@echo $(cpp_srcs)
	@echo $(cpp_objs)

.PHONY : debug

输出如下:

src/main.cpp
objs/main.o

4.foreach

$(foreach <var>,<list>,<text>)
  • 名称:循环函数 —— foreach
  • 功能:把字符串<list>中的元素逐一取出来,执行<text>包含的表达式
  • 返回:<text>所返回的每个字符串所组成的整个字符串 (以空格分隔)

示例如下:


include_paths := src  \
				 /usr/include/opencv4

library_paths := /usr/lib/aarch64-linux-gnu \
				 /usr/local/cuda-10.2/lib64

include_paths := $(foreach item,$(include_paths),-I$(item))

library_paths := $(library_paths:%=-L%)

debug :
	@echo $(include_paths)
	@echo $(library_paths)

.PHONY : debug

输出如下:

-Isrc -I/usr/include/opencv4
-L/usr/lib/aarch64-linux-gnu -L/usr/local/cuda-10.2/lib64

foreach类似于python的for ... in,伪代码如下:

for item in include_paths:
    item = f"-I{item}"

5.dir

$(dir <names...>)
  • 名称:取目录函数 —— dir

  • 功能:从文件名序列<names>中取出目录部分。目录部分是指最后一个反斜杠(\)之前的部分。如果没有反斜杠,那么返回.\

  • 返回:返回文件名序<names>的目录部分

示例如下:

cpp_srcs := $(shell find src -name *.cpp)

cpp_objs := $(patsubst src/%.cpp,objs/%.o,$(cpp_srcs))

objs/%.o : src/%.cpp
	@mkdir -p $(dir $@)
	@g++ -c $^ -o $@

compile : $(cpp_objs)

debug :
	@echo $(cpp_srcs)
	@echo $(cpp_objs)

.PHONY : debug compile

6.notdir

$(notdir <names...>)
  • 名称:去目录函数 —— notdir
  • 功能:从文件名序列<name>取出非目录部分。非目录部分是指最后一个反斜杠(\)之后
  • 返回:返回文件名序列<name>的非目录部分。

示例如下:

libs := $(notdir $(shell find /usr/lib -name lib*))

debug :
	@echo $(libs)

.PHONY : debug

Tips链接静态库只需要使用-l-L参数即可(-l参数可具体指定需要链接的库,-L参数可以指定需要链接的库文件路径),而动态库除了使用-l-L参数外,还需要使用-rpath-Wl参数,其中,-rpath参数指定了运行时搜索动态库的路径,-Wl参数则将后续的选项传递给链接器ld。具体来说,-Wl,-rpath参数可以设置动态库搜索路径。(from ChatGPT)

7.filter

$(filter <names...>)
  • 名称:过滤函数 —— filter
  • 功能:过滤出符合条件的字符串
  • 返回:返回符合条件的字符串列表

示例如下:

libs := $(notdir $(shell find /usr/lib -name lib*))

a_libs  := $(filter %.a,$(libs))
so_libs := $(filter %.so,$(libs))

debug :
	@echo $(a_libs)

.PHONY : debug

8.basename

$(basename <names...>)
  • 名称:去目录和后缀函数 —— basename
  • 功能:从文件名序列<names>中取出非目录部分和后缀部分。非目录部分是指最后一个反斜杠(\)之后的部分,后缀部分是指最后一个点(.)之后的部分
  • 返回:返回文件名序列<name>的非目录部分和后缀部分
libs := $(notdir $(shell find /usr/lib -name lib*))

a_libs  := $(subst lib,,$(basename $(filter %.a,$(libs))))
so_libs := $(subst lib,,$(basename $(filter %.so,$(libs))))

debug :
	@echo $(so_libs)

.PHONY : debug

总结

本次课程主要学习了Makefile中的常见函数以及它们对应的用法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱听歌的周童鞋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值