一些Makefile的函数

6 篇文章 0 订阅
1 篇文章 0 订阅

origin

查询参数VARNAME的出处。VARNAME为变量名,所以一般不通过$进行引用

$(origin VARNAME)
  1. 若从未定义过该变量,origin返回undefined

    all:
    	@echo $(origin V)
    

    make时输出:undefined

  2. 若该变量为环境变量,则返回enviroment

    all:
    	@echo $(origin USER)
    # 或者
    # VAR = USER
    # all:
    # @echo $(origin $(VAR))
    

    make时输出:enviroment

  3. 若该变量是个默认定义,则返回default

    all:
    	@echo $(origin CC)
    

    make时输出:default

  4. 如果该变量被定义在Makefile文件中,则返回file

    VAR := 1
    all:
    	@echo $(origin VAR)
    

    make时输出:file

  5. 如果变量来自命令行,则返回command line

    all:
    	@echo $(origin COMMANDVAR)
    

    make COMMANDVAR="hello"时输出:command line

  6. 如果变量被override重新定义过,则返回override

    override SHELL=/bin/sh
    all:
    	@echo $(origin SHELL)
    

    make时输出:override

  7. 如果变量是自动化变量(如$@$<),则返回automatic

    all:
    	@echo $(origin $@)
    

    make时输出:automatic

strip

去掉字符串str开头和结尾的空字符。若字符串中间有连续的空字符,将其合并为一个。返回去掉空字符后的字符串

str :=      abc
$(strip $(str))

shell

在Makefile里可以调用shell脚本,但调用存在 一些语法规则

  1. 在Makefile中只能在target中调用shell脚本

    VAR = hello
    all:
    	@echo ${VAR}
    

    在echo命令前加@表示不回显echo命令本身

    make输出结果:hello

  2. 若想在makefile里执行shell命令,必须使用如下形式:

    $(shell <command>)
    

    例如:

    x = $(shell echo "hello")
    y = $(shell pwd)
    
    all:
            @echo $x;\
            echo $y
    

    make执行后输出结果为

    hello
    /home/qxy/Desktop/test
    
  3. target里执行shell命令,一行创建一个进程执行,可以在行末加;\保证代码是一行而不是多行,使它们在同一个进程中执行,例如

    all:
    	@pwd
    	@cd ..
    	@pwd
    

    make执行后输出为

    /home/qxy/Desktop/test
    /home/qxy/Desktop/test
    

    而如果想要cd对后续的命令切实的起到更换目录的作用,需要用以下写法:

    all:
    	@pwd;\
    	cd ..;\
    	pwd
    

    make执行后输出为

    /home/qxy/Desktop/test
    /home/qxy/Desktop
    

    可以发现后者的cd命令确实的起了作用。因为前者的cd与它后面的pwd不属于同一个进程,它们都继承了该makefile执行时的环境变量,cd无法影响与他不属于同一个进程的命令的环境变量

  4. 在Makefile中所有$打头的单词都会被解释成makefile的变量,如果需要使用shell的变量,要加两个$$

    VAR = 1
    all:
    	@VAR=2;\
    	echo $(VAR);\
    	echo $$VAR
    

    make执行后输出为

    1
    2
    

    这里有两个注意点:一是在makefile语法中赋值的等号两边可以有空格,但在shell语法中不可以有空格;二是在target中调用shell命令一行为一个进程,前文也有提到,因此想让echo $$VAR访问到刚刚定义的VAR=2就必须在结尾书写;\,使他们在同一个进程执行

wildcard

搜索指定目录下所有指定结尾的文件,生成一个以空格间隔的文件名列表并返回。当前目录文件只有文件名,子目录下的文件名包含路径信息,比如./foo/3.c

src = $(wildcard arg1, arg2, ...)
# example:
# 假设当前目录下有 1.c 和 2.c 两个文件和 foo/ 一个文件夹
# foo/ 文件夹中有 3.c, 4.c 两个文件
src = $(wildcard *.c ./foo/*.c)
all:
	@echo $(src)

make执行后输出为:1.c 2.c ./foo/3.o ./foo/4.o

notdir

去除所有的目录信息,返回文件名列表

src = $(wildcard *.c ./foo/*.c)
file = $(notdir $(src))
all:
	@echo $(file)

make执行后输出为:1.c 2.c 3.c 4.c

patsubst

src中所有后缀为.c的文件后缀替换为.o

obj = $(patsubst %.c %.o $(src)) 
all:
	@echo $(obj)

make执行后输出为:1.o 2.o 3.o 4.o

foreach

用于循环

$(foreach <var>, <list>, <text>)

这个函数把<list>中的单词逐一取出放到<var>指定的变量中,然后执行<text>的表达式。每次<text>返回一个字符串,foreach结束后<text>返回的所有字符串组成的整个字符串(以空格分隔)作为foreach表达式的返回值

例如:

names := a b c d
files := $(foreach n, $(names), $(n).o)
all:
	@echo $(files)

make执行后输出为:a.o b.o c.o d.o

call

$(call <expression>,<parm1>,<parm2>,<parm3>...)

call被执行时,<expression>参数中的变量如$(1), $(2), $(3)...会被按编号顺序替换成<parm1>, <parm2>, <parm3>...<expression>的返回值即为call函数的返回值。例如;

reverse = $(1) $(2)
foo = $(call reverse, a, b)

此时foo的值为a b

若写成

reverse = $(2) $(1)
foo = $(call reverse, a, b)

变量按顺序替换后$(2)被替换成b$(1)被替换成a,因此此时foo的值为b a

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值